X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=gzip.c;h=3d2aeafecc9674e9a76371198941846425545356;hb=83223a0c7bbc239a4320f02fe0c9cc1006d97ec4;hp=0fca5a3b129851e7077ae05457e42e8ebc85fcc6;hpb=51dee92f25d476f28bf126159ee428c7b916008c;p=debian%2Fgzip diff --git a/gzip.c b/gzip.c index 0fca5a3..3d2aeaf 100644 --- a/gzip.c +++ b/gzip.c @@ -1,6 +1,6 @@ /* gzip (GNU zip) -- compress files with zip algorithm and 'compress' interface - Copyright (C) 1999, 2001-2002, 2006-2007, 2009-2016 Free Software + Copyright (C) 1999, 2001-2002, 2006-2007, 2009-2017 Free Software Foundation, Inc. Copyright (C) 1992-1993 Jean-loup Gailly @@ -189,12 +189,17 @@ static int foreground = 0; /* set if program run in foreground */ int save_orig_name; /* set if original name must be saved */ static int last_member; /* set for .zip and .Z files */ static int part_nb; /* number of parts in .gz file */ - struct timespec time_stamp; /* original time stamp (modification time) */ off_t ifile_size; /* input file size, -1 for devices (debug only) */ static char *env; /* contents of GZIP env variable */ static char const *z_suffix; /* default suffix (can be set with --suffix) */ static size_t z_len; /* strlen(z_suffix) */ +/* The original timestamp (modification time). Its tv_nsec component + is negative if the original time is unknown or is out of time_t + range; the latter can happen on hosts with 32-bit signed time_t + because the gzip format's MTIME is 32-bit unsigned. */ +struct timespec time_stamp; + /* The set of signals that are caught. */ static sigset_t caught_signals; @@ -285,7 +290,6 @@ static const struct option longopts[] = {"recursive", 0, 0, 'r'}, /* recurse through directories */ {"suffix", 1, 0, 'S'}, /* use given suffix instead of .gz */ {"test", 0, 0, 't'}, /* test compressed file integrity */ - {"no-time", 0, 0, 'T'}, /* don't save or restore the time stamp */ {"verbose", 0, 0, 'v'}, /* verbose mode */ {"version", 0, 0, 'V'}, /* display version number */ {"fast", 0, 0, '1'}, /* compress faster */ @@ -358,11 +362,11 @@ local void help() " -l, --list list compressed file contents", " -L, --license display software license", #ifdef UNDOCUMENTED - " -m, --no-time do not save or restore the original modification time", + " -m do not save or restore the original modification time", " -M, --time save or restore the original modification time", #endif - " -n, --no-name do not save or restore the original name and time stamp", - " -N, --name save or restore the original name and time stamp", + " -n, --no-name do not save or restore the original name and timestamp", + " -N, --name save or restore the original name and timestamp", " -q, --quiet suppress all warnings", #if ! NO_DIR " -r, --recursive operate recursively on directories", @@ -748,7 +752,7 @@ local void treat_stdin() strcpy(ifname, "stdin"); strcpy(ofname, "stdout"); - /* Get the file's time stamp and size. */ + /* Get the file's timestamp and size. */ if (fstat (STDIN_FILENO, &istat) != 0) { progerror ("standard input"); @@ -1462,7 +1466,7 @@ discard_input_bytes (nbytes, flags) * original name was given and to_stdout is not set. * Return the compression method, -1 for error, -2 for warning. * Set inptr to the offset of the next byte to be processed. - * Updates time_stamp if there is one and --no-time is not used. + * Updates time_stamp if there is one and neither -m nor -n is used. * This function may be called repeatedly for an input file consisting * of several contiguous gzip'ed members. * IN assertions: there is at least one remaining compressed member. @@ -1475,7 +1479,7 @@ local int get_method(in) uch magic[10]; /* magic header */ int imagic0; /* first magic byte or EOF */ int imagic1; /* like magic[1], but can represent EOF */ - ulg stamp; /* time stamp */ + ulg stamp; /* timestamp */ /* If --force and --stdout, zcat == cat, so do not complain about * premature end of file: use try_byte instead of get_byte. @@ -1535,17 +1539,10 @@ local int get_method(in) stamp |= ((ulg)get_byte()) << 8; stamp |= ((ulg)get_byte()) << 16; stamp |= ((ulg)get_byte()) << 24; - if (stamp != 0 && !no_time) + if (!no_time && 0 < stamp && stamp <= TYPE_MAXIMUM (time_t)) { - if (stamp <= TYPE_MAXIMUM (time_t)) - { - time_stamp.tv_sec = stamp; - time_stamp.tv_nsec = 0; - } - else - WARN ((stderr, - "%s: %s: MTIME %lu out of range for this platform\n", - program_name, ifname, stamp)); + time_stamp.tv_sec = stamp; + time_stamp.tv_nsec = 0; } magic[8] = get_byte (); /* Ignore extra flags. */ @@ -1774,7 +1771,9 @@ local void do_list(ifd, method) static char const month_abbr[][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; - struct tm *tm = localtime (&time_stamp.tv_sec); + struct tm *tm = (time_stamp.tv_nsec < 0 + ? NULL + : localtime (&time_stamp.tv_sec)); printf ("%5s %08lx ", methods[method], crc); if (tm) printf ("%s%3d %02d:%02d ", month_abbr[tm->tm_mon], @@ -1920,21 +1919,23 @@ local void copy_stat(ifstat) int r; #ifndef NO_UTIME + bool restoring; struct timespec timespec[2]; timespec[0] = get_stat_atime (ifstat); timespec[1] = get_stat_mtime (ifstat); + restoring = (decompress && 0 <= time_stamp.tv_nsec + && ! (timespec[1].tv_sec == time_stamp.tv_sec + && timespec[1].tv_nsec == time_stamp.tv_nsec)); + if (restoring) + timespec[1] = time_stamp; - if (decompress && 0 <= time_stamp.tv_nsec - && ! (timespec[1].tv_sec == time_stamp.tv_sec - && timespec[1].tv_nsec == time_stamp.tv_nsec)) + if (fdutimens (ofd, ofname, timespec) == 0) { - timespec[1] = time_stamp; - if (verbose > 1) { - fprintf(stderr, "%s: time stamp restored\n", ofname); + if (restoring && 1 < verbose) { + fprintf(stderr, "%s: timestamp restored\n", ofname); } } - - if (fdutimens (ofd, ofname, timespec) != 0) + else { int e = errno; WARN ((stderr, "%s: ", program_name));