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