From 88514167fd6e746fb46c7475739be2223186c9ba Mon Sep 17 00:00:00 2001 From: kientzle Date: Fri, 5 Sep 2008 05:55:49 +0000 Subject: MfP4: Use the set/unset tracking to determine when mtime or atime is unavailable. Use start_time as a substitute when one is missing; if both are missing, skip the call to {f,l,}utime{s,}() entirely. --- lib/libarchive/archive_write_disk.c | 65 +++++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 14 deletions(-) (limited to 'lib') diff --git a/lib/libarchive/archive_write_disk.c b/lib/libarchive/archive_write_disk.c index 521c162..14a0529 100644 --- a/lib/libarchive/archive_write_disk.c +++ b/lib/libarchive/archive_write_disk.c @@ -439,15 +439,25 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry) fe->mode = a->mode; } - if (a->deferred & TODO_TIMES) { + if ((a->deferred & TODO_TIMES) + && (archive_entry_mtime_is_set(entry) + || archive_entry_atime_is_set(entry))) { fe = current_fixup(a, archive_entry_pathname(entry)); fe->fixup |= TODO_TIMES; - fe->mtime = archive_entry_mtime(entry); - fe->mtime_nanos = archive_entry_mtime_nsec(entry); - fe->atime = archive_entry_atime(entry); - fe->atime_nanos = archive_entry_atime_nsec(entry); - if (fe->atime == 0 && fe->atime_nanos == 0) + if (archive_entry_mtime_is_set(entry)) { + fe->mtime = archive_entry_mtime(entry); + fe->mtime_nanos = archive_entry_mtime_nsec(entry); + } else { + fe->mtime = a->start_time; + fe->mtime_nanos = 0; + } + if (archive_entry_atime_is_set(entry)) { + fe->atime = archive_entry_atime(entry); + fe->atime_nanos = archive_entry_atime_nsec(entry); + } else { fe->atime = a->start_time; + fe->atime_nanos = 0; + } } if (a->deferred & TODO_FFLAGS) { @@ -1623,18 +1633,31 @@ set_time(struct archive_write_disk *a) { struct timeval times[2]; - times[1].tv_sec = archive_entry_mtime(a->entry); - times[1].tv_usec = archive_entry_mtime_nsec(a->entry) / 1000; + /* If no time was provided, we're done. */ + if (!archive_entry_atime_is_set(a->entry) + && !archive_entry_mtime_is_set(a->entry)) + return (ARCHIVE_OK); - times[0].tv_sec = archive_entry_atime(a->entry); - times[0].tv_usec = archive_entry_atime_nsec(a->entry) / 1000; + /* We know at least one is set, so... */ + if (archive_entry_mtime_is_set(a->entry)) { + times[1].tv_sec = archive_entry_mtime(a->entry); + times[1].tv_usec = archive_entry_mtime_nsec(a->entry) / 1000; + } else { + times[1].tv_sec = a->start_time; + times[1].tv_usec = 0; + } /* If no atime was specified, use start time instead. */ /* In theory, it would be marginally more correct to use * time(NULL) here, but that would cost us an extra syscall * for little gain. */ - if (times[0].tv_sec == 0 && times[0].tv_usec == 0) + if (archive_entry_atime_is_set(a->entry)) { + times[0].tv_sec = archive_entry_atime(a->entry); + times[0].tv_usec = archive_entry_atime_nsec(a->entry) / 1000; + } else { times[0].tv_sec = a->start_time; + times[0].tv_usec = 0; + } #ifdef HAVE_FUTIMES if (a->fd >= 0 && futimes(a->fd, times) == 0) { @@ -1672,10 +1695,24 @@ set_time(struct archive_write_disk *a) { struct utimbuf times; - times.modtime = archive_entry_mtime(a->entry); - times.actime = archive_entry_atime(a->entry); - if (times.actime == 0) + /* If no time was provided, we're done. */ + if (!archive_entry_atime_is_set(a->entry) + && !archive_entry_mtime_is_set(a->entry)) + return (ARCHIVE_OK); + + /* We know at least one is set, so... */ + /* Set mtime from mtime if set, else start time. */ + if (archive_entry_mtime_is_set(a->entry)) + times.modtime = archive_entry_mtime(a->entry); + else + times.modtime = a->start_time; + + /* Set atime from provided atime, else mtime. */ + if (archive_entry_atime_is_set(a->entry)) + times.actime = archive_entry_atime(a->entry); + else times.actime = a->start_time; + if (!S_ISLNK(a->mode) && utime(a->name, ×) != 0) { archive_set_error(&a->archive, errno, "Can't update time for %s", a->name); -- cgit v1.1