summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorkientzle <kientzle@FreeBSD.org>2008-09-05 05:55:49 +0000
committerkientzle <kientzle@FreeBSD.org>2008-09-05 05:55:49 +0000
commit88514167fd6e746fb46c7475739be2223186c9ba (patch)
tree9e371550600999ca9cf3468af433bdc43b859e22 /lib
parent6beefd0e3976cc801a87f0ae67aa91e22f1eb692 (diff)
downloadFreeBSD-src-88514167fd6e746fb46c7475739be2223186c9ba.zip
FreeBSD-src-88514167fd6e746fb46c7475739be2223186c9ba.tar.gz
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.
Diffstat (limited to 'lib')
-rw-r--r--lib/libarchive/archive_write_disk.c65
1 files changed, 51 insertions, 14 deletions
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, &times) != 0) {
archive_set_error(&a->archive, errno,
"Can't update time for %s", a->name);
OpenPOWER on IntegriCloud