X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fextract.c;h=9be0a8b1392b95ae200192bdb131c86f0963f532;hb=d659cbaccdc1f3279c49107cf15f15a639738529;hp=0e758a2c2456c4b50d526e67f017cfda850dd5ea;hpb=f6445e4ed68362950e8c83b60eed09871982fbe1;p=chaz%2Ftar diff --git a/src/extract.c b/src/extract.c index 0e758a2..9be0a8b 100644 --- a/src/extract.c +++ b/src/extract.c @@ -1,7 +1,7 @@ /* Extract files from a tar archive. Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000, - 2001, 2003, 2004 Free Software Foundation, Inc. + 2001, 2003, 2004, 2005 Free Software Foundation, Inc. Written by John Gilmore, on 1985-11-19. @@ -21,19 +21,10 @@ #include #include +#include #include #include -#if HAVE_UTIME_H -# include -#else -struct utimbuf - { - long actime; - long modtime; - }; -#endif - #include "common.h" static bool we_are_root; /* true if our effective uid == 0 */ @@ -201,15 +192,30 @@ set_mode (char const *file_name, /* Check time after successfully setting FILE_NAME's time stamp to T. */ static void -check_time (char const *file_name, time_t t) +check_time (char const *file_name, struct timespec t) { - time_t now; - if (t <= 0) + if (t.tv_sec <= 0) WARN ((0, 0, _("%s: implausibly old time stamp %s"), - file_name, tartime (t))); - else if (start_time < t && (now = time (0)) < t) - WARN ((0, 0, _("%s: time stamp %s is %lu s in the future"), - file_name, tartime (t), (unsigned long) (t - now))); + file_name, tartime (t, true))); + else if (timespec_lt (start_time, t)) + { + struct timespec now; + gettime (&now); + if (timespec_lt (now, t)) + { + unsigned long int ds = t.tv_sec - now.tv_sec; + int dns = t.tv_nsec - now.tv_nsec; + char dnsbuf[sizeof ".FFFFFFFFF"]; + if (dns < 0) + { + dns += 1000000000; + ds--; + } + code_ns_fraction (dns, dnsbuf); + WARN ((0, 0, _("%s: time stamp %s is %lu%s s in the future"), + file_name, tartime (t, true), ds, dnsbuf)); + } + } } /* Restore stat attributes (owner, group, mode and times) for @@ -233,8 +239,6 @@ set_stat (char const *file_name, mode_t invert_permissions, enum permstatus permstatus, char typeflag) { - struct utimbuf utimbuf; - if (typeflag != SYMTYPE) { /* We do the utime before the chmod because some versions of utime are @@ -248,19 +252,16 @@ set_stat (char const *file_name, /* FIXME: incremental_option should set ctime too, but how? */ - if (incremental_option) - utimbuf.actime = stat_info->st_atime; - else - utimbuf.actime = start_time; - - utimbuf.modtime = stat_info->st_mtime; + struct timespec ts[2]; + ts[0] = incremental_option ? get_stat_atime (stat_info) : start_time; + ts[1] = get_stat_mtime (stat_info); - if (utime (file_name, &utimbuf) < 0) + if (utimens (file_name, ts) != 0) utime_error (file_name); else { - check_time (file_name, utimbuf.actime); - check_time (file_name, utimbuf.modtime); + check_time (file_name, ts[0]); + check_time (file_name, ts[1]); } } @@ -778,7 +779,7 @@ extract_file (char *file_name, int typeflag) static int extract_link (char *file_name, int typeflag) { - char const *link_name = safer_name_suffix (current_stat_info.link_name, + char const *link_name = safer_name_suffix (current_stat_info.link_name, true, absolute_names_option); int interdir_made = 0; @@ -1134,7 +1135,7 @@ extract_archive (void) if (verbose_option) print_header (¤t_stat_info, -1); - file_name = safer_name_suffix (current_stat_info.file_name, + file_name = safer_name_suffix (current_stat_info.file_name, false, absolute_names_option); if (strip_name_components) {