#include <errno.h>
#include <dirent.h>
#include <sys/stat.h>
+#include <time.h>
+#include <utime.h>
#include "ar.h"
extern char *basename(const char *);
memcpy(buf, p, size);
}
+time_t
+ftime_to_time_t(uint32_t ftime)
+{
+ struct tm tm;
+ /* ftime is time structure on MS-DOS
+
+ 32 24 16 8
+ 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
+ |-------------|-------|---------|---------|-----------|---------|
+ year(-1980) month day hour minute second/2
+ (1-127) (1-12) (1-31) (0-23) (0-59) (0-29)
+ */
+
+ memset(&tm, 0, sizeof(tm));
+ tm.tm_year = (ftime >> 25) + 1980 - 1900;
+ tm.tm_mon = ((ftime >> 21) & 0x0f) - 1;
+ tm.tm_mday = (ftime >> 16) & 0x1f;
+ tm.tm_hour = (ftime >> 11) & 0x1f;
+ tm.tm_min = (ftime >> 5) & 0x3f;
+ tm.tm_sec = (ftime & 0x1f) * 2;
+
+ return mktime(&tm);
+}
+
+uint32_t
+time_t_to_ftime(time_t t)
+{
+ struct tm tm;
+ uint32_t ftime;
+ /* ftime is time structure on MS-DOS
+
+ 32 24 16 8
+ 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
+ |-------------|-------|---------|---------|-----------|---------|
+ year(-1980) month day hour minute second/2
+ (1-127) (1-12) (1-31) (0-23) (0-59) (0-29)
+ */
+
+#if HAVE_LOCALTIME_R
+ localtime(&t, &tm);
+#else
+ tm = *localtime(&t);
+#endif
+
+ return (uint32_t)(tm.tm_year + 1900 - 1980) << 25
+ | (uint32_t)(tm.tm_mon + 1) << 21
+ | (uint32_t)(tm.tm_mday) << 16
+ | (uint32_t)(tm.tm_hour) << 11
+ | (uint32_t)(tm.tm_min) << 5
+ | (uint32_t)(tm.tm_sec / 2);
+}
+
static int
read_header_lv0(FILE *fp, char *buf, struct lzh_header *h)
{
get_char(&buf[0], h->method, 5);
h->compsize = get_dword(&buf[5]);
h->origsize = get_dword(&buf[9]);
- h->ftime = get_dword(&buf[13]);
+ h->mtime = ftime_to_time_t(get_dword(&buf[13]));
/* attrib = get_byte(&buf[17]); */
h->level = get_byte(&buf[18]); /* header level */
h->namelen = get_byte(&buf[19]);
get_char(&buf[0], h->method, 5);
h->compsize = get_dword(&buf[5]);
h->origsize = get_dword(&buf[9]);
- h->ftime = get_dword(&buf[13]);
+ h->mtime = ftime_to_time_t(get_dword(&buf[13]));
/* attrib = get_byte(&buf[17]); */
h->level = get_byte(&buf[18]); /* header level */
h->namelen = get_byte(&buf[19]);
get_char(&buf[2], h->method, 5);
h->compsize = get_dword(&buf[7]);
h->origsize = get_dword(&buf[11]);
- h->ftime = get_dword(&buf[15]);
+ h->mtime = get_dword(&buf[15]);
/* attrib = get_byte(&buf[19]); */
h->level = get_byte(&buf[20]); /* header level */
h->file_crc = get_word(&buf[21]);
put_char(&buf[2], h->method, 5);
put_dword(&buf[7], h->compsize); /* packed size */
put_dword(&buf[11], h->origsize); /* original size */
- put_dword(&buf[15], h->ftime); /* ftime */
+ put_dword(&buf[15], time_t_to_ftime(h->mtime)); /* ftime */
put_byte(&buf[19], 0x20); /* attribute */
put_byte(&buf[20], 0); /* level */
put_byte(&buf[21], h->namelen); /* length of pathname */
put_char(&buf[2], h->method, 5);
put_dword(&buf[7], h->compsize); /* packed size */
put_dword(&buf[11], h->origsize); /* original size */
- put_dword(&buf[15], h->ftime); /* ftime */
+ put_dword(&buf[15], time_t_to_ftime(h->mtime)); /* ftime */
put_byte(&buf[19], 0x20); /* attribute */
put_byte(&buf[20], 1); /* level */
put_byte(&buf[21], h->namelen); /* length of pathname */
put_char(&buf[2], h->method, 5);
put_dword(&buf[7], h->compsize); /* packed size */
put_dword(&buf[11], h->origsize); /* original size */
- put_dword(&buf[15], h->ftime); /* time_t */
+ put_dword(&buf[15], h->mtime); /* time_t */
put_byte(&buf[19], 0x20); /* DOS attribute (0x20 fixed) */
put_byte(&buf[20], 2); /* level */
put_word(&buf[21], h->file_crc);
stat(h.filename, &st);
+ h.mtime = st.st_mtime;
if (S_ISDIR(st.st_mode)) {
DIR *dir;
struct dirent *ent;
if (to_file) {
fprintf(stdout, "\n");
- if (outfile)
+ if (outfile) {
+ struct utimbuf ut;
+
fclose(outfile);
+
+ ut.actime = ut.modtime = h->mtime;
+ utime(h->filename, &ut);
+ }
}
outfile = NULL;
}
/* change directory to extract dir */
if (cmd == 'x') {
- struct stat *stbuf;
-
if (opts.outdir) {
if (mkdir(opts.outdir, 0777) == -1) {
if (errno != EEXIST)