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.
This commit is contained in:
Tim Kientzle 2008-09-05 05:55:49 +00:00
parent 9128ec21f3
commit e20d272f0a

View File

@ -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, &times) != 0) {
archive_set_error(&a->archive, errno,
"Can't update time for %s", a->name);