mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-30 16:28:30 +00:00
Improve zipos path handling (#579)
This change adds opendir, readdir, and stat support for the /zip/ root, as well as directories not explicitly encoded in the zip file.
This commit is contained in:
parent
494d74271b
commit
1ef955c33b
5 changed files with 73 additions and 10 deletions
|
@ -28,6 +28,9 @@
|
|||
ssize_t __zipos_find(struct Zipos *zipos, const struct ZiposUri *name) {
|
||||
const char *zname;
|
||||
size_t i, n, c, znamesize;
|
||||
if (!name->len) {
|
||||
return 0;
|
||||
}
|
||||
c = GetZipCdirOffset(zipos->cdir);
|
||||
n = GetZipCdirRecords(zipos->cdir);
|
||||
for (i = 0; i < n; ++i, c += ZIP_CFILE_HDRSIZE(zipos->map + c)) {
|
||||
|
@ -38,6 +41,13 @@ ssize_t __zipos_find(struct Zipos *zipos, const struct ZiposUri *name) {
|
|||
(name->len + 1 == znamesize && !memcmp(name->path, zname, name->len) &&
|
||||
zname[name->len] == '/')) {
|
||||
return c;
|
||||
} else if ((name->len < znamesize &&
|
||||
!memcmp(name->path, zname, name->len) &&
|
||||
zname[name->len - 1] == '/') ||
|
||||
(name->len + 1 < znamesize &&
|
||||
!memcmp(name->path, zname, name->len) &&
|
||||
zname[name->len] == '/')) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
|
|
|
@ -16,9 +16,10 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/safemacros.internal.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/intrin/safemacros.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/s.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/zip.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
@ -27,14 +28,18 @@ int __zipos_stat_impl(struct Zipos *zipos, size_t cf, struct stat *st) {
|
|||
size_t lf;
|
||||
if (zipos && st) {
|
||||
bzero(st, sizeof(*st));
|
||||
lf = GetZipCfileOffset(zipos->map + cf);
|
||||
st->st_mode = GetZipCfileMode(zipos->map + cf);
|
||||
st->st_size = GetZipLfileUncompressedSize(zipos->map + lf);
|
||||
st->st_blocks =
|
||||
roundup(GetZipLfileCompressedSize(zipos->map + lf), 512) / 512;
|
||||
GetZipCfileTimestamps(zipos->map + cf, &st->st_mtim, &st->st_atim,
|
||||
&st->st_ctim, 0);
|
||||
st->st_birthtim = st->st_ctim;
|
||||
if (cf) {
|
||||
lf = GetZipCfileOffset(zipos->map + cf);
|
||||
st->st_mode = GetZipCfileMode(zipos->map + cf);
|
||||
st->st_size = GetZipLfileUncompressedSize(zipos->map + lf);
|
||||
st->st_blocks =
|
||||
roundup(GetZipLfileCompressedSize(zipos->map + lf), 512) / 512;
|
||||
GetZipCfileTimestamps(zipos->map + cf, &st->st_mtim, &st->st_atim,
|
||||
&st->st_ctim, 0);
|
||||
st->st_birthtim = st->st_ctim;
|
||||
} else {
|
||||
st->st_mode = 0444 | S_IFDIR | 0111;
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
return einval();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue