/* 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-2018 Free Software
Foundation, Inc.
Copyright (C) 1992-1993 Jean-loup Gailly
*/
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 <http://www.gnu.org/licenses/gpl.html>.",
+"the GNU General Public License <https://www.gnu.org/licenses/gpl.html>.",
"There is NO WARRANTY, to the extent permitted by law.",
0};
#include "ignore-value.h"
#include "stat-time.h"
#include "version.h"
+#include "xalloc.h"
#include "yesno.h"
/* configuration */
static char const *z_suffix; /* default suffix (can be set with --suffix) */
static size_t z_len; /* strlen(z_suffix) */
-/* The original time stamp (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. */
/* 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);
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 */
" -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",
case '4' + ENV_OPTION: case '5' + ENV_OPTION: case '6' + ENV_OPTION:
case '7' + ENV_OPTION: case '8' + ENV_OPTION: case '9' + ENV_OPTION:
optc -= ENV_OPTION;
- /* Fall through. */
+ FALLTHROUGH;
case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
level = optc - '0';
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");
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);
}
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;
}
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.
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. */
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],
if (fdutimens (ofd, ofname, timespec) == 0)
{
if (restoring && 1 < verbose) {
- fprintf(stderr, "%s: time stamp restored\n", ofname);
+ fprintf(stderr, "%s: timestamp restored\n", ofname);
}
}
else