]> granicus.if.org Git - zziplib/commitdiff
unzip lookalike - part
authorGuido Draheim <guidod@gmx.de>
Tue, 17 May 2005 00:21:16 +0000 (00:21 +0000)
committerGuido Draheim <guidod@gmx.de>
Tue, 17 May 2005 00:21:16 +0000 (00:21 +0000)
 (.)

bins/Makefile.am
bins/Makefile.in
bins/unzip-mem.c [new file with mode: 0644]
zzip/memdisk.c
zzip/memdisk.h

index 957ac8490f532abbafa186c2cdfb33106a1426ab..ed9429d35df478ed1132b4e696ec622322ec5c42 100644 (file)
@@ -5,7 +5,7 @@ DEFS = @DEFS@ -I$(top_builddir) -I$(top_srcdir) # also for automake 1.4
 
 bin_PROGRAMS = zzcat zzdir zzxorcat zzxordir zzxorcopy \
                unzzip unzzipdir unzzipcat unzzipcat-seeko \
-               unzzipdir-mem unzzipcat-mem 
+               unzzipdir-mem unzzipcat-mem unzip-mem
 noinst_PROGRAMS = zziptest zzobfuscated zzip
 aclocaldir = $(datadir)/aclocal
 aclocal_DATA = zziplib.m4
@@ -46,6 +46,8 @@ unzzipdir_mem_LDFLAGS = @ZZIPLIB_LDFLAGS@
 unzzipdir_mem_LDADD = ../zzip/libzzipmmapped.la @RESOLVES@ -lz
 unzzipcat_mem_LDFLAGS = @ZZIPLIB_LDFLAGS@
 unzzipcat_mem_LDADD = ../zzip/libzzipmmapped.la @RESOLVES@ -lz
+unzip_mem_LDFLAGS = @ZZIPLIB_LDFLAGS@
+unzip_mem_LDADD = ../zzip/libzzipmmapped.la @RESOLVES@ -lz
 # and this uses the simplified fseeko stdio version
 unzzipcat_seeko_LDFLAGS = @ZZIPLIB_LDFLAGS@
 unzzipcat_seeko_LDADD = ../zzip/libzzipfseeko.la @RESOLVES@ -lz
index 9bfd1386da3a064aef7dd6f839ccda884577d4f7..db5937c3f37812bfb6d72918650e837608a32ae6 100644 (file)
@@ -15,7 +15,7 @@
 @SET_MAKE@
 
 
-SOURCES = unzzip.c unzzipcat.c unzzipcat-mem.c unzzipcat-seeko.c unzzipdir.c unzzipdir-mem.c zzcat.c zzdir.c zzip.c zziptest.c zzobfuscated.c zzxorcat.c zzxorcopy.c zzxordir.c
+SOURCES = unzip-mem.c unzzip.c unzzipcat.c unzzipcat-mem.c unzzipcat-seeko.c unzzipdir.c unzzipdir-mem.c zzcat.c zzdir.c zzip.c zziptest.c zzobfuscated.c zzxorcat.c zzxorcopy.c zzxordir.c
 
 srcdir = @srcdir@
 top_srcdir = @top_srcdir@
@@ -43,7 +43,8 @@ target_triplet = @target@
 bin_PROGRAMS = zzcat$(EXEEXT) zzdir$(EXEEXT) zzxorcat$(EXEEXT) \
        zzxordir$(EXEEXT) zzxorcopy$(EXEEXT) unzzip$(EXEEXT) \
        unzzipdir$(EXEEXT) unzzipcat$(EXEEXT) unzzipcat-seeko$(EXEEXT) \
-       unzzipdir-mem$(EXEEXT) unzzipcat-mem$(EXEEXT)
+       unzzipdir-mem$(EXEEXT) unzzipcat-mem$(EXEEXT) \
+       unzip-mem$(EXEEXT)
 noinst_PROGRAMS = zziptest$(EXEEXT) zzobfuscated$(EXEEXT) \
        zzip$(EXEEXT)
 subdir = bins
@@ -59,6 +60,9 @@ CONFIG_CLEAN_FILES =
 am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(aclocaldir)"
 binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
 PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
+unzip_mem_SOURCES = unzip-mem.c
+unzip_mem_OBJECTS = unzip-mem.$(OBJEXT)
+unzip_mem_DEPENDENCIES = ../zzip/libzzipmmapped.la
 unzzip_SOURCES = unzzip.c
 unzzip_OBJECTS = unzzip.$(OBJEXT)
 unzzip_DEPENDENCIES = ../zzip/libzzip.la
@@ -111,12 +115,14 @@ LTCOMPILE = $(LIBTOOL) --mode=compile --tag=CC $(CC) $(DEFS) \
 CCLD = $(CC)
 LINK = $(LIBTOOL) --mode=link --tag=CC $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
        $(AM_LDFLAGS) $(LDFLAGS) -o $@
-SOURCES = unzzip.c unzzipcat.c unzzipcat-mem.c unzzipcat-seeko.c \
-       unzzipdir.c unzzipdir-mem.c zzcat.c zzdir.c zzip.c zziptest.c \
-       zzobfuscated.c zzxorcat.c zzxorcopy.c zzxordir.c
-DIST_SOURCES = unzzip.c unzzipcat.c unzzipcat-mem.c unzzipcat-seeko.c \
-       unzzipdir.c unzzipdir-mem.c zzcat.c zzdir.c zzip.c zziptest.c \
-       zzobfuscated.c zzxorcat.c zzxorcopy.c zzxordir.c
+SOURCES = unzip-mem.c unzzip.c unzzipcat.c unzzipcat-mem.c \
+       unzzipcat-seeko.c unzzipdir.c unzzipdir-mem.c zzcat.c zzdir.c \
+       zzip.c zziptest.c zzobfuscated.c zzxorcat.c zzxorcopy.c \
+       zzxordir.c
+DIST_SOURCES = unzip-mem.c unzzip.c unzzipcat.c unzzipcat-mem.c \
+       unzzipcat-seeko.c unzzipdir.c unzzipdir-mem.c zzcat.c zzdir.c \
+       zzip.c zziptest.c zzobfuscated.c zzxorcat.c zzxorcopy.c \
+       zzxordir.c
 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
 am__vpath_adj = case $$p in \
     $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
@@ -295,6 +301,8 @@ unzzipdir_mem_LDFLAGS = @ZZIPLIB_LDFLAGS@
 unzzipdir_mem_LDADD = ../zzip/libzzipmmapped.la @RESOLVES@ -lz
 unzzipcat_mem_LDFLAGS = @ZZIPLIB_LDFLAGS@
 unzzipcat_mem_LDADD = ../zzip/libzzipmmapped.la @RESOLVES@ -lz
+unzip_mem_LDFLAGS = @ZZIPLIB_LDFLAGS@
+unzip_mem_LDADD = ../zzip/libzzipmmapped.la @RESOLVES@ -lz
 # and this uses the simplified fseeko stdio version
 unzzipcat_seeko_LDFLAGS = @ZZIPLIB_LDFLAGS@
 unzzipcat_seeko_LDADD = ../zzip/libzzipfseeko.la @RESOLVES@ -lz
@@ -366,6 +374,9 @@ clean-noinstPROGRAMS:
          echo " rm -f $$p $$f"; \
          rm -f $$p $$f ; \
        done
+unzip-mem$(EXEEXT): $(unzip_mem_OBJECTS) $(unzip_mem_DEPENDENCIES) 
+       @rm -f unzip-mem$(EXEEXT)
+       $(LINK) $(unzip_mem_LDFLAGS) $(unzip_mem_OBJECTS) $(unzip_mem_LDADD) $(LIBS)
 unzzip$(EXEEXT): $(unzzip_OBJECTS) $(unzzip_DEPENDENCIES) 
        @rm -f unzzip$(EXEEXT)
        $(LINK) $(unzzip_LDFLAGS) $(unzzip_OBJECTS) $(unzzip_LDADD) $(LIBS)
@@ -415,6 +426,7 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unzip-mem.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unzzip.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unzzipcat-mem.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unzzipcat-seeko.Po@am__quote@
diff --git a/bins/unzip-mem.c b/bins/unzip-mem.c
new file mode 100644 (file)
index 0000000..f4ce5e9
--- /dev/null
@@ -0,0 +1,420 @@
+/*
+ *     Copyright (c) 2003 Guido Draheim <guidod@gmx.de>
+ *      Use freely under the restrictions of the ZLIB license.
+ *
+ *      This file is used as an example to clarify zzipmmap api usage.
+ */
+
+#include <zlib.h> /* crc32 */
+
+#include <zzip/memdisk.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef ZZIP_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef ZZIP_HAVE_IO_H
+#include <io.h>
+#endif
+
+#include <time.h>
+
+#ifdef ZZIP_HAVE_FNMATCH_H
+#include <fnmatch.h>
+#else
+#define fnmatch(x,y,z) strcmp(x,y)
+#endif
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+#define ___ {
+#define ____ }
+
+#define EXIT_SUCCESS 0
+#define EXIT_WARNINGS 1
+#define EXIT_ERRORS 2
+#define EXIT_EFORMAT 3
+#define EXIT_ENOMEM 4
+#define EXIT_ENOTTY 5
+#define EXIT_EINFLATE 6
+#define EXIT_ENOARCH 9
+#define EXIT_EOPTION 10
+#define EXIT_ENOFILE 11
+#define EXIT_EDISKFULL 50
+#define EXIT_EPREMATURE 51
+#define EXIT_USERABORT 80
+#define EXIT_BADCOMPRESSION 81
+#define EXIT_BADPASSWORD 82
+
+static int status = EXIT_SUCCESS;
+static int option_list = 0;        /* "-l" */
+static int option_pipe = 0;        /* "-p" */
+static int option_verbose = 0;     /* "-v" */
+static int option_testcrc = 0;     /* "-t" */
+static int option_binary = 0;      /* "-b" */
+static int option_nocase = 0;      /* "-C" */
+static int option_junkpaths = 0;   /* "-j" */
+static int option_dosfiles = 0;    /* "-L" */
+static int option_keepold = 0;     /* "-n" */
+static int option_overwrite = 0;   /* "-o" */
+static int option_quiet = 0;       /* "-q" */
+static int option_permbits = 0;    /* "-X" */
+
+static const char usage[] = 
+{
+    "unzzip-mem <zip> [names].. \n"
+    "  - unzzip a zip archive.\n"
+    "options:\n"
+    "  -l list archive files (name, usize, mtime, comments)\n" /* +totals */
+    "  -p extract archive files to pipe, i.e. stdout (binary mode)\n"
+    "  -t test archive files (check the crc values)\n"
+    "  -v verbose list of archive files\n"
+    "  -b accept and ignore (force binary extract)\n"
+    "  -C match filenames case-insensitively\n"
+    "  -j junk paths (do not recreate directory structure)\n"
+    "  -L convert dos filenames to lowercase upon extract\n"
+    "  -n never overwrite existing files\n"
+    "  -o always overwrite existing files\n"
+    "  -q quite operation\n"
+    "  -X restore user/owner attributes of files\n"
+};
+
+static void zzip_mem_entry_pipe(ZZIP_MEM_DISK* disk, 
+                               ZZIP_MEM_ENTRY* entry, FILE* out)
+{
+    ZZIP_DISK_FILE* file = zzip_mem_entry_fopen (disk, entry);
+    if (file) 
+    {
+       char buffer[1024]; int len;
+       while ((len = zzip_mem_disk_fread (buffer, 1024, 1, file)))
+           fwrite (buffer, len, 1, out);
+       
+       zzip_mem_disk_fclose (file);
+    }
+}
+
+static void zzip_mem_entry_make(ZZIP_MEM_DISK* disk, 
+                               ZZIP_MEM_ENTRY* entry)
+{
+    FILE* file = fopen (entry->zz_name, "w");
+    if (file) { zzip_mem_entry_pipe (disk, entry, file); fclose (file); }
+    perror (entry->zz_name);
+    if (status < EXIT_WARNINGS) status = EXIT_WARNINGS;
+}
+
+/* ------------------------- test ------------------------------------ */
+
+static char* archive = 0;
+static int test_errors = 0;
+
+static void zzip_mem_entry_test(ZZIP_MEM_DISK* disk, 
+                               ZZIP_MEM_ENTRY* entry)
+{
+    ZZIP_DISK_FILE* file = zzip_mem_entry_fopen (disk, entry);
+    printf ("    testing: %s ", entry->zz_name);
+    if (strlen (entry->zz_name) < 24) {
+       printf ("%.*s", 24 - strlen (entry->zz_name),
+               "                        ");
+    }
+    if (file) 
+    {
+       unsigned long crc = crc32 (0L, NULL, 0);
+       char buffer[1024]; int len; 
+       while ((len = zzip_mem_disk_fread (buffer, 1024, 1, file))) {
+           crc = crc32 (crc, buffer, len);
+       }
+       
+       zzip_mem_disk_fclose (file);
+       if (crc == (unsigned long) entry->zz_crc32) {
+           printf ("OK\n");
+       } else {
+           printf ("BAD %lx (should be %lx)\n", crc, entry->zz_crc32);
+           test_errors ++;
+       } 
+    } else {
+       printf ("ERROR (no such file)\n");
+       test_errors ++;
+    }
+}
+
+static void zzip_mem_entry_test_start(void)
+{
+    test_errors = 0;
+    printf ("Archive: %s\n", archive);
+}
+
+static void zzip_mem_entry_test_done(void)
+{
+    if (test_errors == 0) {
+       printf ("No errors detected in compressed data of %s\n", archive);
+    } else {
+       printf ("%i errors detected in compressed data of %s\n", 
+               test_errors, archive);
+    }
+}
+
+/* ------------------------- list ------------------------------------ */
+
+static char _zzip_time_[30];
+static char* _zzip_ctime (long* timeval) 
+{
+    struct tm* date = localtime (timeval);
+    sprintf (_zzip_time_, "%02i-%02i-%02i %02i:%02i",
+            date->tm_mon, date->tm_mday, date->tm_year%100,
+            date->tm_hour, date->tm_min);
+    return _zzip_time_;
+}
+
+static const char* comprlevel[] = {
+    "stored",   "shrunk",   "redu:1",   "redu:2",   "redu:3",   "redu:4",
+    "impl:N",   "toknze",   "defl:N",   "defl:B",   "impl:B" };
+
+zzip_off_t sum_usize = 0;
+zzip_off_t sum_csize = 0;
+zzip_off_t sum_files = 0;
+#define L (long)
+
+static void zzip_mem_entry_direntry_start (void)
+{
+    sum_usize = 0;
+    sum_csize = 0;
+    sum_files = 0;
+    if (option_verbose) goto verbose;
+    printf("  Length    Date & Time     Name\n");
+    printf(" --------    ----   ----    ----\n");
+    return;
+ verbose:
+    printf(" Length   Method    Size  Ratio   Date   Time   CRC-32    Name\n");
+    printf("--------  ------  ------- -----   ----   ----   ------    ----\n");
+}
+
+static void zzip_mem_entry_direntry_done (void)
+{
+    char exp = ' ';
+    if (sum_usize / 1024 > 1024*1024*1024) { exp = 'G';
+       sum_usize /= 1024*1024*1024; sum_usize /= 1024*1024*1024; }
+    if (sum_usize > 1024*1024*1024) { exp = 'M';
+       sum_usize /= 1024*1024; sum_csize /= 1024*1024; }
+    if (sum_usize > 1024*1024) { exp = 'K';
+       sum_usize /= 1024; sum_csize /= 1024; }
+    if (option_verbose) goto verbose;
+    printf(" --------                   ----\n");
+    printf(" %8li%c           %8li %s\n", sum_usize, exp, sum_files,
+          sum_files == 1 ? "file" : "files");
+    return;
+ verbose:
+    printf("--------  ------  ------- -----                           ----\n");
+    printf("%8li%c       %8li%c %3li%%                     %8li %s\n",
+          L sum_usize, exp, L sum_csize, exp, 
+          L (100 - (sum_csize*100/sum_usize)), sum_files, 
+          sum_files == 1 ? "file" : "files");
+}
+
+static void zzip_mem_entry_direntry(ZZIP_MEM_ENTRY* entry)
+{
+    char* name = zzip_mem_entry_to_name (entry);
+    zzip_off_t usize = zzip_mem_entry_usize (entry);
+    zzip_off_t csize = zzip_mem_entry_csize (entry);
+    int compr = zzip_mem_entry_data_comprlevel (entry);
+    long mtime = entry->zz_mktime;
+    long crc32 = entry->zz_crc32;
+    char* comment = zzip_mem_entry_to_comment (entry);
+    char exp = ' ';
+
+    sum_usize += usize;
+    sum_csize += csize;
+    sum_files += 1;
+
+    if (usize / 1024 > 1024*1024*1024) { exp = 'G';
+       usize /= 1024*1024*1024; usize /= 1024*1024*1024; }
+    if (usize > 1024*1024*1024) { exp = 'M';
+       usize /= 1024*1024; csize /= 1024*1024; }
+    if (usize > 1024*1024) { exp = 'K';
+       usize /= 1024; csize /= 1024; }
+   
+    if (! comment) comment = "";
+    if (*name == '\n') name++;
+
+    if (option_verbose) {
+       printf("%8li%c %s %8li%c%3li%%  %s  %8lx  %s %s\n", 
+              L usize, exp, comprlevel[compr], L csize, exp, 
+              L (100 - (csize*100/usize)),
+              _zzip_ctime(&mtime), crc32, name, comment);
+    } else {
+       printf(" %8li%c %s   %s %s\n", 
+              L usize, exp, _zzip_ctime(&mtime), name, comment);
+    }    
+}
+
+static void zzip_mem_entry_listfiles(ZZIP_MEM_DISK* disk, char* filespec)
+{
+    zzip_mem_entry_direntry_start ();
+    ___ ZZIP_MEM_ENTRY* entry = 0;
+    while ((entry = zzip_mem_disk_findmatch(disk, filespec, entry, 0, 0)))
+       zzip_mem_entry_direntry (entry); ____;
+    zzip_mem_entry_direntry_done ();
+}
+
+static void zzip_mem_entry_listall(ZZIP_MEM_DISK* disk)
+{
+    zzip_mem_entry_direntry_start ();
+    ___ ZZIP_MEM_ENTRY* entry = zzip_mem_disk_findfirst(disk);
+    for (; entry ; entry = zzip_mem_disk_findnext(disk, entry))
+       zzip_mem_entry_direntry (entry); ____;
+    zzip_mem_entry_direntry_done ();
+}
+
+static void zzip_mem_entry_testfiles(ZZIP_MEM_DISK* disk, char* filespec)
+{
+    zzip_mem_entry_test_start ();
+    ___ ZZIP_MEM_ENTRY* entry = 0;
+    while ((entry = zzip_mem_disk_findmatch(disk, filespec, entry, 0, 0)))
+       zzip_mem_entry_test (disk, entry); ____;
+    zzip_mem_entry_test_done ();
+}
+
+static void zzip_mem_entry_testall(ZZIP_MEM_DISK* disk)
+{
+    zzip_mem_entry_test_start ();
+    ___ ZZIP_MEM_ENTRY* entry = zzip_mem_disk_findfirst(disk);
+    for (; entry ; entry = zzip_mem_disk_findnext(disk, entry))
+       zzip_mem_entry_test (disk, entry); ____;
+    zzip_mem_entry_test_done ();
+}
+
+static void zzip_mem_entry_pipefiles(ZZIP_MEM_DISK* disk, char* filespec)
+{
+    ZZIP_MEM_ENTRY* entry = 0;
+    while ((entry = zzip_mem_disk_findmatch(disk, filespec, entry, 0, 0)))
+       zzip_mem_entry_pipe (disk, entry, stdout);
+}
+
+static void zzip_mem_entry_pipeall(ZZIP_MEM_DISK* disk)
+{
+    ZZIP_MEM_ENTRY* entry = zzip_mem_disk_findfirst(disk);
+    for (; entry ; entry = zzip_mem_disk_findnext(disk, entry))
+       zzip_mem_entry_pipe (disk, entry, stdout);
+}
+
+static void zzip_mem_entry_makefiles(ZZIP_MEM_DISK* disk, char* filespec)
+{
+    ZZIP_MEM_ENTRY* entry = 0;
+    while ((entry = zzip_mem_disk_findmatch(disk, filespec, entry, 0, 0)))
+       zzip_mem_entry_make (disk, entry);
+}
+
+static void zzip_mem_entry_makeall(ZZIP_MEM_DISK* disk)
+{
+    ZZIP_MEM_ENTRY* entry = zzip_mem_disk_findfirst(disk);
+    for (; entry ; entry = zzip_mem_disk_findnext(disk, entry))
+       zzip_mem_entry_make (disk, entry);
+}
+
+int 
+main (int argc, char ** argv)
+{
+    int argn; int archname = 0; int filespec = 0;
+    ZZIP_MEM_DISK* disk;
+    if (argc <= 1 || ! strcmp (argv[1], "--help"))
+    {
+       printf (usage);
+       return 0;
+    }
+    if (! strcmp (argv[1], "--version"))
+    {
+       printf (__FILE__" version "ZZIP_PACKAGE" "ZZIP_VERSION"\n");
+       return 0;
+    }
+
+    for (argn=1; argn < argc; argn++) {
+       if ((argv[argn])[0] == '-') {
+           int x = 1;
+           while ((argv[argn])[x]) {
+               switch (argv[argn][x]) {
+               case 'l': option_list++; break;
+               case 'p': option_pipe++; break;
+               case 't': option_testcrc++; break;
+               case 'v': option_verbose++; break;
+               case 'b': option_binary++; break;
+               case 'C': option_nocase++; break;
+               case 'j': option_junkpaths++; break;
+               case 'L': option_dosfiles++; break;
+               case 'n': option_keepold++; break;
+               case 'o': option_overwrite++; break;
+               case 'q': option_quiet++; break;
+               case 'X': option_permbits++; break;
+               }
+               x++;
+           }
+           (argv[argn])[0] = 0;
+       } else {
+           if (! archname) { archname = argn; continue; }
+           if (! filespec) { filespec = argn; continue; }
+       }
+    }
+
+    if (! archname) {
+       printf (usage);
+       return 0;
+    } else archive = argv[archname];
+
+    disk = zzip_mem_disk_open (argv[archname]);
+    if (! disk) {
+       perror(argv[archname]);
+       return -1;
+    }
+
+    if (option_list || option_verbose) {
+       if (! filespec) {
+           zzip_mem_entry_listall (disk);
+       } else {
+           for (argn=filespec; argn < argc; argn++) {
+               if (argv[argn][0]) {
+                   zzip_mem_entry_listfiles (disk, argv[argn]);
+               }
+           }
+       }
+    } else if (option_pipe) {
+       if (! filespec) {
+           zzip_mem_entry_pipeall (disk);
+       } else {
+           for (argn=filespec; argn < argc; argn++) {
+               if (argv[argn][0]) {
+                   zzip_mem_entry_pipefiles (disk, argv[argn]);
+               }
+           }
+       }
+    } else if (option_testcrc) {
+       if (! filespec) {
+           zzip_mem_entry_testall (disk);
+       } else {
+           for (argn=filespec; argn < argc; argn++) {
+               if (argv[argn][0]) {
+                   zzip_mem_entry_testfiles (disk, argv[argn]);
+               }
+           }
+       }
+    } else {
+       if (! filespec) {
+           zzip_mem_entry_makeall (disk);
+       } else {
+           for (argn=filespec; argn < argc; argn++) {
+               if (argv[argn][0]) {
+                   zzip_mem_entry_makefiles (disk, argv[argn]);
+               }
+           }
+       }
+    }
+
+    return status;
+} 
+
+/* 
+ * Local variables:
+ * c-file-style: "stroustrup"
+ * End:
+ */
index 1abd04303e9afc55d042397ffd9ea7ef115355bf..0f4714a3ad9d3c9a1f2b6d2a1c25d81c78efa0ed 100644 (file)
@@ -26,6 +26,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <time.h>
 
 #include <zlib.h>
 #include <zzip/format.h>
@@ -58,6 +59,9 @@ typedef struct _zzip_extra_zip64 { /* ZIP64 extended information extra field */
     char z_diskstart[4]; /* Number of the disk for file start*/
 } zzip_extra_zip64;
 
+/*forward*/
+
+
 static ZZIP_MEM_ENTRY* _zzip_new
 zzip_mem_entry_new(ZZIP_DISK* disk, ZZIP_DISK_ENTRY* entry);
 static void
@@ -142,6 +146,7 @@ zzip_mem_entry_new(ZZIP_DISK* disk, ZZIP_DISK_ENTRY* entry)
     item->zz_data =      zzip_file_header_to_data(header);
     item->zz_flags =     zzip_disk_entry_get_flags(entry);
     item->zz_compr =     zzip_disk_entry_get_compr(entry);
+    item->zz_mktime =    zzip_disk_entry_get_mktime(entry);
     item->zz_crc32 =     zzip_disk_entry_get_crc32(entry);
     item->zz_csize =     zzip_disk_entry_get_csize(entry);
     item->zz_usize =     zzip_disk_entry_get_usize(entry);
@@ -196,7 +201,7 @@ zzip_mem_entry_extra_block (ZZIP_MEM_ENTRY* entry, short datatype)
     while (1) {
        ZZIP_EXTRA_BLOCK* ext = entry->zz_ext[i];
        if (ext) {
-           while (ext->z_datatype) {
+           while (*(short*)(ext->z_datatype)) {
                if (datatype == zzip_extra_block_get_datatype (ext)) {
                    return ext;
                }
@@ -371,3 +376,18 @@ zzip_mem_disk_feof (ZZIP_MEM_DISK_FILE* file)
 {
     return zzip_disk_feof (file);
 }
+
+/* convert dostime of entry to unix time_t */
+long zzip_disk_entry_get_mktime(ZZIP_DISK_ENTRY* entry) 
+{
+    uint16_t dostime = ZZIP_GET16 (entry->z_dostime.time);
+    uint16_t dosdate = ZZIP_GET16 (entry->z_dostime.date);
+    struct tm date;
+    date.tm_sec =  (dostime) & 0x1F;       /* bits 0..4 */
+    date.tm_min =  (dostime >> 5) & 0x3F;  /* bits 5..10 */
+    date.tm_hour = (dostime >> 11);       /* bits 11..15 */
+    date.tm_mday = (dosdate) & 0x1F;      /* bits 16..20 */
+    date.tm_mon =  (dosdate >> 5) & 0xF;  /* bits 21..24 */
+    date.tm_year = (dosdate >> 9) + 80;   /* bits 25..31 */
+    return mktime (&date); /* well, unix has that function... */
+}
index 292226716ff3a94262e310bf453b5a5e3e779b96..b20fc0546c67f6560d6f089765ae58f9d62a964b 100644 (file)
@@ -49,6 +49,7 @@ struct _zzip_mem_entry {
     char*            zz_data;      /* compressed content start (mmap addr) */
     int              zz_flags;     /* (from "z_flags") */
     int              zz_compr;     /* (from "z_compr") */
+    long             zz_mktime;    /* (from "z_dostime") */
     long             zz_crc32;     /* (from "z_crc32") */
     zzip_off_t       zz_csize;     /* (from "z_csize")  overridden by zip64 */
     zzip_off_t       zz_usize;     /* (from "z_usize")  overridden by zip64 */
@@ -60,7 +61,7 @@ struct _zzip_mem_entry {
 };                                 /* the extra blocks are NOT converted */
      
 #define _zzip_mem_disk_findfirst(_d_) ((_d_)->list)
-#define _zzip_mem_disk_findnext(_d_,_e_) ((_e_)?(_d_)->list:(_e_)->zz_next)
+#define _zzip_mem_disk_findnext(_d_,_e_) (!(_e_)?(_d_)->list:(_e_)->zz_next)
 #define _zzip_mem_entry_findnext(_e_) ((_e_)->zz_next)
 
 #ifndef USE_INLINE
@@ -84,11 +85,13 @@ zzip_mem_entry_findnext(ZZIP_MEM_ENTRY* entry) {
 #endif
 
 #define _zzip_mem_entry_to_name(_e_) ((_e_)->zz_name)
+#define _zzip_mem_entry_to_comment(_e_) ((_e_)->zz_comment)
 #define _zzip_mem_entry_strdup_name(_e_) (strdup((_e_)->zz_name))
 #define _zzip_mem_entry_to_data(_e_) ((_e_)->zz_data)
 
 #ifndef USE_INLINE
 #define zzip_mem_entry_to_name _zzip_mem_entry_to_name
+#define zzip_mem_entry_to_comment _zzip_mem_entry_to_comment
 #define zzip_mem_entry_strdup_name _zzip_mem_entry_strdup_name
 #define zzip_mem_entry_to_data _zzip_mem_entry_to_data
 #else
@@ -96,6 +99,10 @@ _zzip_inline char*
 zzip_mem_entry_to_name(ZZIP_MEM_ENTRY* entry) {
     if (! entry) return 0;
     return _zzip_mem_entry_to_name(entry); }
+_zzip_inline char*
+zzip_mem_entry_to_comment(ZZIP_MEM_ENTRY* entry) {
+    if (! entry) return 0;
+    return _zzip_mem_entry_to_comment(entry); }
 _zzip_inline char* _zzip_new
 zzip_mem_entry_strdup_name(ZZIP_MEM_ENTRY* entry) {
     if (! entry) return 0;
@@ -146,7 +153,7 @@ zzip_mem_disk_fclose (ZZIP_MEM_DISK_FILE* file);
 int
 zzip_mem_disk_feof (ZZIP_MEM_DISK_FILE* file);
 
-
-
+/* convert dostime of entry to unix time_t */
+long zzip_disk_entry_get_mktime(ZZIP_DISK_ENTRY* entry);
 
 #endif