From: Tim Kientzle Date: Sat, 30 Aug 2008 22:43:15 +0000 (-0400) Subject: IFC: Resolve different handling of missing atime/mtime in SVN vs X-Git-Tag: v2.6.0~102 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8e71fa728044552aadc7bd8689743274e0df2e5a;p=thirdparty%2Flibarchive.git IFC: Resolve different handling of missing atime/mtime in SVN vs current P4 code (which relies on some facilities not yet in SVN). SVN-Revision: 190 --- diff --git a/libarchive/archive_write_disk.c b/libarchive/archive_write_disk.c index 3e1ab6b72..f0ce6249f 100644 --- a/libarchive/archive_write_disk.c +++ b/libarchive/archive_write_disk.c @@ -25,7 +25,7 @@ */ #include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_disk.c,v 1.31 2008/08/24 06:21:00 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_disk.c,v 1.32 2008/08/28 06:40:22 kientzle Exp $"); #ifdef HAVE_SYS_TYPES_H #include @@ -443,17 +443,24 @@ _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); + if (archive_entry_mtime_is_set(entry)) { + fe->mtime = archive_entry_mtime(entry); + fe->mtime_nanos = archive_entry_mtime_nsec(entry); + } else { + fe->mtime = archive_entry_atime(entry); + fe->mtime_nanos = archive_entry_atime_nsec(entry); + } 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; + fe->atime = archive_entry_mtime(entry); + fe->atime_nanos = archive_entry_mtime_nsec(entry); } } @@ -1664,15 +1671,26 @@ 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); + + /* 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 = archive_entry_atime(a->entry); + times[1].tv_usec = archive_entry_atime_nsec(a->entry) / 1000; + } 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; + times[0].tv_sec = archive_entry_mtime(a->entry); + times[0].tv_usec = archive_entry_mtime_nsec(a->entry) / 1000; } #ifdef HAVE_FUTIMES @@ -1711,11 +1729,24 @@ set_time(struct archive_write_disk *a) { struct utimbuf times; - times.modtime = archive_entry_mtime(a->entry); + /* 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 atime. */ + if (archive_entry_mtime_is_set(a->entry)) + times.modtime = archive_entry_mtime(a->entry); + else + times.modtime = archive_entry_atime(a->entry); + + /* 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; + times.actime = archive_entry_mtime(a->entry); + if (!S_ISLNK(a->mode) && utime(a->name, ×) != 0) { archive_set_error(&a->archive, errno, "Can't update time for %s", a->name); diff --git a/libarchive/test/test_write_disk.c b/libarchive/test/test_write_disk.c index eb137c3f8..00ee09268 100644 --- a/libarchive/test/test_write_disk.c +++ b/libarchive/test/test_write_disk.c @@ -23,7 +23,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "test.h" -__FBSDID("$FreeBSD: src/lib/libarchive/test/test_write_disk.c,v 1.9 2008/06/15 10:35:22 kientzle Exp $"); +__FBSDID("$FreeBSD: src/lib/libarchive/test/test_write_disk.c,v 1.11 2008/08/30 05:31:23 kientzle Exp $"); #define UMASK 022 @@ -61,7 +61,7 @@ static void create_reg_file(struct archive_entry *ae, const char *msg) /* Write the entry to disk. */ assert((ad = archive_write_disk_new()) != NULL); - archive_write_disk_set_options(ad, ARCHIVE_EXTRACT_TIME); + archive_write_disk_set_options(ad, ARCHIVE_EXTRACT_TIME); failure("%s", msg); /* * A touchy API design issue: archive_write_data() does (as of @@ -95,10 +95,10 @@ static void create_reg_file(struct archive_entry *ae, const char *msg) failure("st.st_mode=%o archive_entry_mode(ae)=%o", st.st_mode, archive_entry_mode(ae)); assertEqualInt(st.st_mode, (archive_entry_mode(ae) & ~UMASK)); - failure("Old bug: if no atime specified, atime got set to Jan 1, 1970"); - assert(st.st_atime != 0); assertEqualInt(st.st_size, sizeof(data)); - assertEqualInt(st.st_mtime, 123456789); + failure("No atime was specified, so atime should get set to mtime"); + assertEqualInt(st.st_atime, st.st_mtime); + assertEqualInt(st.st_mtime, 123456789); } static void create_reg_file2(struct archive_entry *ae, const char *msg)