X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=gzip.c;h=59ab553e448a157a267dcf2cd9eaf84d9f2ac903;hb=3bd3681e0fbddf82ca7fa12af67cf139fe1e6379;hp=32a229c4e044a28a1b36e6e61fea47521b6c59b9;hpb=6a692a8db14d2ce1f9ad166e6e426e723385b74d;p=debian%2Fgzip diff --git a/gzip.c b/gzip.c index 32a229c..59ab553 100644 --- a/gzip.c +++ b/gzip.c @@ -29,10 +29,10 @@ */ static char const *const license_msg[] = { -"Copyright (C) 2016 Free Software Foundation, Inc.", +"Copyright (C) 2017 Free Software Foundation, Inc.", "Copyright (C) 1993 Jean-loup Gailly.", "This is free software. You may redistribute copies of it under the terms of", -"the GNU General Public License .", +"the GNU General Public License .", "There is NO WARRANTY, to the extent permitted by law.", 0}; @@ -77,6 +77,7 @@ static char const *const license_msg[] = { #include "ignore-value.h" #include "stat-time.h" #include "version.h" +#include "xalloc.h" #include "yesno.h" /* configuration */ @@ -194,10 +195,12 @@ 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. */ +/* The original timestamp (modification time). If the original is + unknown, TIME_STAMP.tv_nsec is negative. If the original is + greater than struct timespec range, TIME_STAMP is the maximal + struct timespec value; this can happen on hosts with 32-bit signed + time_t because the gzip format's MTIME is 32-bit unsigned. + The original cannot be less than struct timespec range. */ struct timespec time_stamp; /* The set of signals that are caught. */ @@ -302,7 +305,7 @@ static const struct option longopts[] = /* local functions */ -local void try_help (void) ATTRIBUTE_NORETURN; +local noreturn void try_help (void); local void help (void); local void license (void); local void version (void); @@ -322,7 +325,7 @@ local void copy_stat (struct stat *ifstat); local void install_signal_handlers (void); local void remove_output_file (void); local RETSIGTYPE abort_gzip_signal (int); -local void do_exit (int exitcode) ATTRIBUTE_NORETURN; +local noreturn void do_exit (int exitcode); static void finish_out (void); int main (int argc, char **argv); static int (*work) (int infile, int outfile) = zip; /* function to call */ @@ -1180,9 +1183,12 @@ local char *get_suffix(name) break; } } + + char *z_lower = xstrdup(z_suffix); + strlwr(z_lower); known_suffixes[suffix_of_builtin ? sizeof known_suffixes / sizeof *known_suffixes - 2 - : 0] = z_suffix; + : 0] = z_lower; suf = known_suffixes + suffix_of_builtin; nlen = strlen(name); @@ -1193,15 +1199,18 @@ local char *get_suffix(name) } strlwr(suffix); slen = strlen(suffix); + char *match = NULL; do { int s = strlen(*suf); if (slen > s && ! ISSLASH (suffix[slen - s - 1]) && strequ(suffix + slen - s, *suf)) { - return name+nlen-s; + match = name+nlen-s; + break; } } while (*++suf != NULL); + free(z_lower); - return NULL; + return match; } @@ -1539,10 +1548,21 @@ local int get_method(in) stamp |= ((ulg)get_byte()) << 8; stamp |= ((ulg)get_byte()) << 16; stamp |= ((ulg)get_byte()) << 24; - if (!no_time && 0 < stamp && stamp <= TYPE_MAXIMUM (time_t)) + if (stamp != 0 && !no_time) { - time_stamp.tv_sec = stamp; - time_stamp.tv_nsec = 0; + 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 = TYPE_MAXIMUM (time_t); + time_stamp.tv_nsec = TIMESPEC_RESOLUTION - 1; + } } magic[8] = get_byte (); /* Ignore extra flags. */ @@ -1771,9 +1791,7 @@ 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 = (time_stamp.tv_nsec < 0 - ? NULL - : localtime (&time_stamp.tv_sec)); + struct tm *tm = localtime (&time_stamp.tv_sec); printf ("%5s %08lx ", methods[method], crc); if (tm) printf ("%s%3d %02d:%02d ", month_abbr[tm->tm_mon],