/* Crude programme to show detailed information about a zip file. */ #include "memento.h" #include "outf.h" #include #include #include #include #include static int s_native_little_endinesss(void) { static const char a[] = { 1, 2}; uint16_t b = *(uint16_t*) a; if (b == 1 + 2*256) { /* Native little-endiness. */ return 1; } else if (b == 2 + 1*256) { return 0; } abort(); } static int s_show(const char* filename) { outf("Looking at filename=%s", filename); assert(s_native_little_endinesss()); FILE* f = fopen(filename, "r"); assert(f); size_t datasize = 10*1000*1000; char* data = extract_malloc(datasize); assert(data); size_t n = fread(data, 1, datasize, f); assert(n < datasize); datasize = n; outf("datasize=%zi", datasize); fclose(f); /* look for End of central directory (EOCD) record. */ uint32_t magic = 0x06054b50; char* pos = data + datasize - 22; for(;;) { if (!memcmp(pos, &magic, sizeof(magic))) break; assert(pos > data); pos -= 1; } outf("found EOCD at offset=%li", pos-data); uint16_t disk_number = *(uint16_t*)(pos+4); uint16_t disk_cd = *(uint16_t*)(pos+6); uint16_t num_records_on_disk = *(uint16_t*)(pos+8); uint16_t num_records = *(uint16_t*)(pos+10); uint32_t size_cd = *(uint32_t*)(pos+12); uint32_t offset_cd = *(uint32_t*)(pos+16); uint16_t comment_length = *(uint16_t*)(pos+20); char* comment = extract_malloc(comment_length + 1); assert(comment); memcpy(comment, pos+22, comment_length); comment[comment_length] = 0; assert(strlen(comment) == comment_length); outf(" EOCD:"); outf(" disk_number=%i", disk_number); outf(" disk_cd=%i", disk_cd); outf(" num_records_on_disk=%i", num_records_on_disk); outf(" num_records=%i", num_records); outf(" size_cd=%i", size_cd); outf(" offset_cd=%i", offset_cd); outf(" comment_length=%i", comment_length); outf(" comment=%s", comment); if (pos != data + datasize - 22 - comment_length) { outf("file does not end with EOCD. datasize=%zi pos-data=%li datasize-22-comment_length=%zi", datasize, pos-data, datasize-22-comment_length ); /* I think this isn't actually an error according to the Zip standard, but zip files created by us should always pass this test. Note that Word doesn't like trailing data after the EOCD record, but will repair the file. */ assert(0); } pos = data + offset_cd; int i; for (i=0; i