Below is a small patch that implements file timestamps
when listing/extracting cab archives.  I found the lack
of this feature to be quite annoying, and after some
digging just went on and implemented it... ;)

The patch is against svn #2777.

Thanks.

/mjt

P.S. I'm not subscribed to the mailinglist.
Index: src/unshield.c
===================================================================
--- src/unshield.c      (revision 2777)
+++ src/unshield.c      (working copy)
@@ -11,6 +11,8 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <time.h>
+#include <utime.h>
 #include "../lib/libunshield.h"
 #ifdef HAVE_CONFIG_H
 #include "../lib/unshield_config.h"
@@ -261,6 +263,7 @@
   char filename[256];
   char* p;
   int directory = unshield_file_directory(unshield, index);
+  time_t ts;
 
   strcpy(dirname, output_directory);
   strcat(dirname, "/");
@@ -346,6 +349,10 @@
     unlink(filename);
     exit_status = 1;
   }
+  else if ((ts = unshield_file_timestamp(unshield, index)) != 0) {
+    struct utimbuf utb = { ts, ts };
+    utime(filename, &utb);
+  }
 
   return success;
 }
@@ -442,6 +449,8 @@
   for (i = first; i <= last; i++)
   {
     char dirname[256];
+    char tsbuf[sizeof("2000-12-31 23:59")];
+    time_t ts;
 
     if (unshield_file_is_valid(unshield, i))
     {
@@ -452,6 +461,16 @@
       else
         dirname[0] = '\0';
 
+      ts = unshield_file_timestamp(unshield, i);
+      if (ts) {
+        struct tm *tm = localtime(&ts);
+       sprintf(tsbuf, "%04d-%02d-%02d %02d:%02d",
+           tm->tm_year + 1900, tm->tm_mon, tm->tm_mday,
+          tm->tm_hour, tm->tm_min);
+      }
+      else
+        memset(tsbuf, ' ', sizeof(tsbuf)-1);
+
       strcat(dirname,
           unshield_directory_name(unshield, unshield_file_directory(unshield, 
i)));
 
@@ -464,7 +483,8 @@
       if (dirname[strlen(dirname)-1] != '/')
         strcat(dirname, "/");
 
-      printf(" %8" SIZE_FORMAT "  %s%s\n",
+      printf(" %s %8" SIZE_FORMAT "  %s%s\n",
+          tsbuf,
           unshield_file_size(unshield, i),
           dirname,
           unshield_file_name(unshield, i)); 
@@ -503,7 +523,7 @@
     }
   }
 
-  printf(" --------  -------\n          %i files\n", count);
+  printf(" ---------- ----- --------  -------\n          %i files\n", count);
 
   return true;
 }
Index: lib/libunshield.h
===================================================================
--- lib/libunshield.h   (revision 2777)
+++ lib/libunshield.h   (working copy)
@@ -4,6 +4,7 @@
 
 #include <stdbool.h>
 #include <stddef.h>
+#include <sys/types.h>
 
 #define UNSHIELD_LOG_LEVEL_LOWEST    0
 
@@ -82,6 +83,7 @@
 bool        unshield_file_save          (Unshield* unshield, int index, const 
char* filename);
 int         unshield_file_directory     (Unshield* unshield, int index);
 size_t      unshield_file_size          (Unshield* unshield, int index);
+time_t      unshield_file_timestamp    (Unshield* unshield, int index);
 
 /** For investigation of compressed data */
 bool unshield_file_save_raw(Unshield* unshield, int index, const char* 
filename);
Index: lib/file.c
===================================================================
--- lib/file.c  (revision 2777)
+++ lib/file.c  (working copy)
@@ -15,6 +15,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sys/param.h>    /* for MIN(a,b) */
+#include <time.h>
 #include <zlib.h>
 
 #define VERBOSE 3
@@ -22,6 +23,20 @@
 #define ror8(x,n)   (((x) >> ((int)(n))) | ((x) << (8 - (int)(n))))
 #define rol8(x,n)   (((x) << ((int)(n))) | ((x) >> (8 - (int)(n))))
 
+/* a-la win32 function */
+time_t DosDateTimeToTime(uint16_t dosDate, uint16_t dosTime) {
+  struct tm tm;
+  if (!dosDate || !dosTime)
+    return 0;
+  memset(&tm, 0, sizeof(tm));
+  tm.tm_sec = (dosTime & 31) * 2;
+  tm.tm_min = (dosTime >> 5) & 0x31;
+  tm.tm_hour = (dosTime >> 11) & 0x1f;
+  tm.tm_mday = dosDate & 0x1f;
+  tm.tm_mon = (dosDate >> 5) & 0x0f;
+  tm.tm_year = (1980 + ((dosDate >> 9) & 0x7f)) - 1900;
+  return mktime(&tm);
+}
 
 static FileDescriptor* unshield_read_file_descriptor(Unshield* unshield, int 
index)
 {
@@ -30,6 +45,7 @@
   uint8_t* p = NULL;
   uint8_t* saved_p = NULL;
   FileDescriptor* fd = NEW1(FileDescriptor);
+  uint16_t dostime, dosdate;
 
   switch (header->major_version)
   {
@@ -53,6 +69,9 @@
 
       fd->expanded_size     = READ_UINT32(p); p += 4;
       fd->compressed_size   = READ_UINT32(p); p += 4;
+      dosdate = READ_UINT16(p+4);
+      dostime = READ_UINT16(p+4+4);
+      fd->timestamp = DosDateTimeToTime(dosdate, dostime);
       p += 0x14;
       fd->data_offset       = READ_UINT32(p); p += 4;
       
@@ -99,7 +118,11 @@
       fd->directory_index   = READ_UINT16(p); p += 2;
 
       assert((p - saved_p) == 0x40);
-      
+
+      dosdate = READ_UINT16(p+4);
+      dostime = READ_UINT16(p+4+2);
+      fd->timestamp = DosDateTimeToTime(dosdate, dostime);
+ 
       p += 0xc;
       fd->link_previous     = READ_UINT32(p); p += 4;
       fd->link_next         = READ_UINT32(p); p += 4;
@@ -819,6 +842,17 @@
     return 0;
 }/*}}}*/
 
+time_t unshield_file_timestamp(Unshield* unshield, int index)/*{{{*/
+{
+  FileDescriptor* fd = unshield_get_file_descriptor(unshield, index);
+  if (fd)
+  {
+    return fd->timestamp;
+  }
+  else
+    return 0;
+}/*}}}*/
+
 bool unshield_file_save_raw(Unshield* unshield, int index, const char* 
filename)
 {
   /* XXX: Thou Shalt Not Cut & Paste... */
Index: lib/cabfile.h
===================================================================
--- lib/cabfile.h       (revision 2777)
+++ lib/cabfile.h       (working copy)
@@ -83,6 +83,7 @@
   uint32_t link_previous;
   uint32_t link_next;
   uint8_t link_flags;
+  time_t timestamp;
 } FileDescriptor;
 
 typedef struct
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
SynCE-Devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/synce-devel

Reply via email to