/* * print the table of contents from the "central directory structure" */ static int unztable(Biobuf *bin, char *file) { ZipHead zh; int entries; entries = findCDir(bin, file); if(entries < 0) return 0; if(verbose > 1) print("%d items in the archive\n", entries); while(entries-- > 0){ if(setjmp(zjmp)){ free(zh.file); return 0; } memset(&zh, 0, sizeof(zh)); if(!cheader(bin, &zh)) return 1; if(wantFile(zh.file)){ if(verbose) print("%-32s %10lu %s", zh.file, zh.uncsize, ctime(msdos2time(zh.modtime, zh.moddate))); else print("%s\n", zh.file); if(verbose > 1){ print("\tmade by os %d vers %d.%d\n", zh.madeos, zh.madevers/10, zh.madevers % 10); print("\textract by os %d vers %d.%d\n", zh.extos, zh.extvers/10, zh.extvers % 10); print("\tflags %x\n", zh.flags); print("\tmethod %d\n", zh.meth); print("\tmod time %d\n", zh.modtime); print("\tmod date %d\n", zh.moddate); print("\tcrc %lx\n", zh.crc); print("\tcompressed size %lu\n", zh.csize); print("\tuncompressed size %lu\n", zh.uncsize); print("\tinternal attributes %x\n", zh.iattr); print("\texternal attributes %lx\n", zh.eattr); print("\tstarts at %ld\n", zh.off); } } free(zh.file); zh.file = nil; } return 1; }
/* * extract files using the info in the central directory structure */ static int unzip(Biobuf *bin, char *file) { ZipHead zh; int64_t off; int ok, eok, entries; entries = findCDir(bin, file); if(entries < 0) return 0; ok = 1; while(entries-- > 0){ if(setjmp(zjmp)){ free(zh.file); return 0; } memset(&zh, 0, sizeof(zh)); if(!cheader(bin, &zh)) return ok; off = Boffset(bin); if(wantFile(zh.file)){ if(Bseek(bin, zh.off, 0) < 0){ fprint(2, "unzip: can't seek to start of %s, skipping\n", zh.file); ok = 0; }else{ eok = unzipEntry(bin, &zh); if(eok <= 0){ fprint(2, "unzip: skipping %s\n", zh.file); ok = 0; } } } free(zh.file); zh.file = nil; if(Bseek(bin, off, 0) < 0){ fprint(2, "unzip: can't seek to start of next entry, terminating extraction\n"); return 0; } } return ok; }
void populate(char *name) { char *p; Fileinf f; ZipHead zh; int ok, entries; crctab = mkcrctab(ZCrcPoly); ok = inflateinit(); if(ok != FlateOk) sysfatal("inflateinit failed: %s", flateerr(ok)); bin = Bopen(name, OREAD); if (bin == nil) error("Can't open argument file"); entries = findCDir(bin); if(entries < 0) sysfatal("empty file"); while(entries-- > 0){ memset(&zh, 0, sizeof(zh)); if(!cheader(bin, &zh)) break; f.addr = zh.off; if(zh.iattr & IS_TEXT) f.addr |= High64; f.mode = (zh.madevers == IS_MSDOS && zh.eattr & IS_RDONLY)? 0444: 0644; if (zh.meth == 0 && zh.uncsize == 0){ p = strchr(zh.file, '\0'); if(p > zh.file && p[-1] == '/') f.mode |= (DMDIR | 0111); } f.uid = 0; f.gid = 0; f.size = zh.uncsize; f.mdate = msdos2time(zh.modtime, zh.moddate); f.name = zh.file + ((zh.file[0] == '/')? 1: 0); poppath(f, 1); free(zh.file); } return ; }