OSDN Git Service

* src/header.c (wintime_to_unix_stamp): newly added for converting
authorarai <arai@6a8cc165-1e22-0410-a132-eb4e3f353aba>
Sun, 25 Aug 2002 19:58:07 +0000 (19:58 +0000)
committerarai <arai@6a8cc165-1e22-0410-a132-eb4e3f353aba>
Sun, 25 Aug 2002 19:58:07 +0000 (19:58 +0000)
from `FILETIME' to `time_t'.
(get_extended_header): use `wintime_to_unix_stamp()' to recognize
the Windows time stamp header (0x41).

* src/lha.h: define `uint64_t' unless system has it.

* configure.ac: check existence of the type `uint64_t'.

* config.h.in: ditto.

git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/lha/lha/trunk@527 6a8cc165-1e22-0410-a132-eb4e3f353aba

config.h.in
configure.ac
src/header.c
src/lha.h

index 6e63aee..4dff470 100644 (file)
@@ -61,6 +61,9 @@
 /* Define to 1 if you have the `link' function. */
 #undef HAVE_LINK
 
+/* Define to 1 if the system has the type `long long'. */
+#undef HAVE_LONG_LONG
+
 /* Define to 1 if you have the `memcpy' function. */
 #undef HAVE_MEMCPY
 
 /* Define to 1 if the system has the type `uid_t'. */
 #undef HAVE_UID_T
 
+/* Define to 1 if the system has the type `uint64_t'. */
+#undef HAVE_UINT64_T
+
 /* Define to 1 if you have the <unistd.h> header file. */
 #undef HAVE_UNISTD_H
 
 /* Define as the return type of signal handlers (`int' or `void'). */
 #undef RETSIGTYPE
 
+/* The size of a `long', as computed by sizeof. */
+#undef SIZEOF_LONG
+
 /* Define to 1 if you have the ANSI C header files. */
 #undef STDC_HEADERS
 
index 9a9453d..4ae8db9 100644 (file)
@@ -22,7 +22,7 @@ AC_SEARCH_LIBS(opendir, [mingwex])
 AC_HEADER_DIRENT
 AC_HEADER_STDC
 AC_CHECK_HEADERS(fcntl.h limits.h sys/file.h sys/param.h sys/time.h)
-AC_CHECK_HEADERS(pwd.h grp.h utime.h)
+AC_CHECK_HEADERS(pwd.h grp.h utime.h inttypes.h stdint.h)
 
 # Checks for typedefs, structures, and compiler characteristics.
 AC_C_CONST
@@ -30,7 +30,8 @@ AC_HEADER_TIME
 AC_STRUCT_TM
 AC_STRUCT_TIMEZONE
 
-AC_CHECK_TYPES([uid_t, gid_t])
+AC_CHECK_SIZEOF(long)
+AC_CHECK_TYPES([uid_t, gid_t, long long, uint64_t])
 AC_CHECK_MEMBERS([struct tm.tm_gmtoff, struct stat.st_ino],,,
 [
 #if HAVE_SYS_TYPES_H
index 625a1b7..355d8e5 100644 (file)
@@ -494,6 +494,44 @@ unix_to_generic_stamp(t)
                        (tm->tm_sec / 2)));
 }
 
+static unsigned long
+wintime_to_unix_stamp()
+{
+#if HAVE_UINT64_T
+    uint64_t t;
+    uint64_t epoch = 0x019db1ded53e8000; /* 1970-01-01 00:00:00 (UTC) */
+
+    t = get_longword();
+    t += (uint64_t)get_longword() << 32;
+    t = (t - epoch) / 10000000;
+    return t;
+#else
+    int i, borrow;
+    unsigned long t, q, x;
+    unsigned long wintime[8];
+    unsigned long epoch[8] = {0x01,0x9d,0xb1,0xde, 0xd5,0x3e,0x80,0x00};
+                                /* 1970-01-01 00:00:00 (UTC) */
+    /* wintime -= epoch */
+    borrow = 0;
+    for (i = 7; i >= 0; i--) {
+        wintime[i] = (unsigned)get_byte() - epoch[i] - borrow;
+        borrow = (wintime[i] > 0xff) ? 1 : 0;
+        wintime[i] &= 0xff;
+    }
+
+    /* q = wintime / 10000000 */
+    t = q = 0;
+    x = 10000000;               /* x: 24bit */
+    for (i = 0; i < 8; i++) {
+        t = (t << 8) + wintime[i]; /* 24bit + 8bit. t must be 32bit variable */
+        q <<= 8;                   /* q must be 32bit (time_t) */
+        q += t / x;
+        t %= x;     /* 16bit */
+    }
+    return q;
+#endif
+}
+
 /* ------------------------------------------------------------------------ */
 /* build header functions                                                                                                      */
 /* ------------------------------------------------------------------------ */
@@ -516,6 +554,7 @@ unix_to_generic_stamp(t)
  *  on level 3 header:
  *    size field is 4 bytes
  */
+
 static long
 get_extended_header(fp, hdr, header_size, hcrc)
     FILE *fp;
@@ -575,7 +614,18 @@ get_extended_header(fp, hdr, header_size, hcrc)
             break;
         case 0x41:
             /* Windows time stamp (FILETIME structure) */
-            skip_bytes(header_size - n); /* ignored */
+            /* it is time in 100 nano seconds since 1601-01-01 00:00:00 */
+
+            skip_bytes(8); /* create time is ignored */
+
+            /* set last modified time */
+            if (hdr->header_level >= 2)
+                skip_bytes(8);  /* time_t has been already set */
+            else
+                hdr->unix_last_modified_stamp = wintime_to_unix_stamp();
+
+            skip_bytes(8); /* last access time is ignored */
+
             break;
         case 0x50:
             /* UNIX permission */
index 6a53c5c..9232778 100644 (file)
--- a/src/lha.h
+++ b/src/lha.h
 #include <sys/stat.h>
 #include <signal.h>
 
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+#endif
+
 #if STDC_HEADERS
 # include <string.h>
 #else
@@ -81,6 +89,17 @@ typedef int uid_t;
 typedef int gid_t;
 #endif
 
+#if !HAVE_UINT64_T
+# define HAVE_UINT64_T 1
+# if SIZEOF_LONG == 8
+    typedef unsigned long uint64_t;
+# elif HAVE_LONG_LONG
+    typedef unsigned long long uint64_t;
+# else
+#  undef HAVE_UINT64_T
+# endif
+#endif
+
 #if TIME_WITH_SYS_TIME
 # include <sys/time.h>
 # include <time.h>