X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=gzip.c;h=9e2a890fc12040575a848a90f965ffe48d1ef1db;hb=3ac0fd944a5bcf7e4ed614be23435dd28002fbc5;hp=08b5c5fbd6c8fa80d2be549c9becf36973403422;hpb=e7921f54c622e3b32e525f345bc34308821e4ae0;p=debian%2Fgzip diff --git a/gzip.c b/gzip.c index 08b5c5f..9e2a890 100644 --- a/gzip.c +++ b/gzip.c @@ -1,11 +1,12 @@ /* gzip (GNU zip) -- compress files with zip algorithm and 'compress' interface - Copyright (C) 1999, 2001, 2002, 2006 Free Software Foundation, Inc. + Copyright (C) 1999, 2001-2002, 2006-2007, 2009-2010 Free Software + Foundation, Inc. Copyright (C) 1992-1993 Jean-loup Gailly This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) + the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -27,8 +28,8 @@ * See the file algorithm.doc for the compression algorithms and file formats. */ -static char *license_msg[] = { -"Copyright (C) 2006 Free Software Foundation, Inc.", +static char const *const license_msg[] = { +"Copyright (C) 2007 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 .", @@ -53,10 +54,6 @@ static char *license_msg[] = { * For the meaning of all compilation flags, see comments in Makefile.in. */ -#ifdef RCSID -static char rcsid[] = "$Id: gzip.c,v 1.11 2006/12/12 00:03:17 eggert Exp $"; -#endif - #include #include #include @@ -64,6 +61,7 @@ static char rcsid[] = "$Id: gzip.c,v 1.11 2006/12/12 00:03:17 eggert Exp $"; #include #include +#include "closein.h" #include "tailor.h" #include "gzip.h" #include "lzw.h" @@ -71,34 +69,16 @@ static char rcsid[] = "$Id: gzip.c,v 1.11 2006/12/12 00:03:17 eggert Exp $"; #include "fcntl-safer.h" #include "getopt.h" +#include "ignore-value.h" #include "stat-time.h" -#include "timespec.h" /* configuration */ -#ifdef HAVE_TIME_H -# include -#else -# include -#endif - -#ifdef HAVE_FCNTL_H -# include -#endif - -#ifdef HAVE_LIMITS_H -# include -#endif - -#ifdef HAVE_UNISTD_H -# include -#endif - -#if defined STDC_HEADERS || defined HAVE_STDLIB_H -# include -#else - extern int errno; -#endif +#include +#include +#include +#include +#include #ifndef NO_DIR # define NO_DIR 0 @@ -199,7 +179,7 @@ int verbose = 0; /* be verbose (-v) */ int quiet = 0; /* be very quiet (-q) */ int do_lzw = 0; /* generate output compatible with old compress (-Z) */ int test = 0; /* test .gz file integrity */ -int foreground; /* set if program run in foreground */ +int foreground = 0; /* set if program run in foreground */ char *program_name; /* program name */ int maxbits = BITS; /* max bits per code for LZW */ int method = DEFLATED;/* compression method */ @@ -212,13 +192,13 @@ struct timespec time_stamp; /* original time stamp (modification time) */ off_t ifile_size; /* input file size, -1 for devices (debug only) */ char *env; /* contents of GZIP env variable */ char **args = NULL; /* argv pointer if GZIP env variable defined */ -char *z_suffix; /* default suffix (can be set with --suffix) */ +char const *z_suffix; /* default suffix (can be set with --suffix) */ size_t z_len; /* strlen(z_suffix) */ /* The set of signals that are caught. */ static sigset_t caught_signals; -/* If nonzero then exit with status 1, rather than with the usual +/* If nonzero then exit with status WARNING, rather than with the usual signal status, on receipt of a signal with this value. This suppresses a "Broken Pipe" message with some shells. */ static int volatile exiting_signal; @@ -238,7 +218,30 @@ int ofd; /* output file descriptor */ unsigned insize; /* valid bytes in inbuf */ unsigned inptr; /* index of next byte to be processed in inbuf */ unsigned outcnt; /* bytes in output buffer */ -int rsync = 0; /* make ryncable chunks */ + +static int handled_sig[] = + { + /* SIGINT must be first, as 'foreground' depends on it. */ + SIGINT + +#ifdef SIGHUP + , SIGHUP +#endif +#ifdef SIGPIPE + , SIGPIPE +#else +# define SIGPIPE 0 +#endif +#ifdef SIGTERM + , SIGTERM +#endif +#ifdef SIGXCPU + , SIGXCPU +#endif +#ifdef SIGXFSZ + , SIGXFSZ +#endif + }; struct option longopts[] = { @@ -268,7 +271,6 @@ struct option longopts[] = {"best", 0, 0, '9'}, /* compress better */ {"lzw", 0, 0, 'Z'}, /* make output compatible with old compress */ {"bits", 1, 0, 'b'}, /* max number of bits per code (implies -Z) */ - {"rsyncable", 0, 0, 'R'}, /* make rsync-friendly archive */ { 0, 0, 0, 0 } }; @@ -314,7 +316,7 @@ try_help () /* ======================================================================== */ local void help() { - static char *help_msg[] = { + static char const* const help_msg[] = { "Compress or uncompress FILEs (by default, compress FILES in-place).", "", "Mandatory arguments to long options are mandatory for short options too.", @@ -350,13 +352,12 @@ local void help() " -Z, --lzw produce output compatible with old compress", " -b, --bits=BITS max number of bits per code (implies -Z)", #endif - " --rsyncable Make rsync-friendly archive", "", "With no FILE, or when FILE is -, read standard input.", "", "Report bugs to .", 0}; - char **p = help_msg; + char const *const *p = help_msg; printf ("Usage: %s [OPTION]... [FILE]...\n", program_name); while (*p) printf ("%s\n", *p++); @@ -365,7 +366,7 @@ local void help() /* ======================================================================== */ local void license() { - char **p = license_msg; + char const *const *p = license_msg; printf ("%s %s\n", program_name, VERSION); while (*p) printf ("%s\n", *p++); @@ -379,8 +380,7 @@ local void version() printf ("Written by Jean-loup Gailly.\n"); } -local void progerror (string) - char *string; +local void progerror (char const *string) { int e = errno; fprintf (stderr, "%s: ", program_name); @@ -390,9 +390,7 @@ local void progerror (string) } /* ======================================================================== */ -int main (argc, argv) - int argc; - char **argv; +int main (int argc, char **argv) { int file_count; /* number of files to process */ size_t proglen; /* length of program_name */ @@ -403,6 +401,8 @@ int main (argc, argv) program_name = gzip_base_name (argv[0]); proglen = strlen (program_name); + atexit (close_stdin); + /* Suppress .exe for MSDOS, OS/2 and VMS: */ if (4 < proglen && strequ (program_name + proglen - 4, ".exe")) program_name[proglen - 4] = '\0'; @@ -412,8 +412,11 @@ int main (argc, argv) if (env != NULL) args = argv; #ifndef GNU_STANDARD +# define GNU_STANDARD 1 +#endif +#if !GNU_STANDARD /* For compatibility with old compress, use program name as an option. - * If you compile with -DGNU_STANDARD, this program will behave as + * Unless you compile with -DGNU_STANDARD=0, this program will behave as * gzip even if it is invoked under the name gunzip or zcat. * * Systems which do not support links can still use -d or -dc. @@ -475,9 +478,7 @@ int main (argc, argv) #else recursive = 1; #endif - case 'R': - rsync = 1; break; - + break; case 'S': #ifdef NO_MULTIPLE_DOTS if (*optarg == '.') optarg++; @@ -621,26 +622,21 @@ local void treat_stdin() strcpy(ifname, "stdin"); strcpy(ofname, "stdout"); - /* Get the time stamp on the input file. */ - time_stamp.tv_nsec = -1; /* The time is unknown by default. */ - -#ifndef NO_STDIN_FSTAT - if (list || !no_time) { - if (fstat(fileno(stdin), &istat) != 0) { - progerror("standard input"); - do_exit(ERROR); - } -# ifdef NO_PIPE_TIMESTAMP - if (S_ISREG(istat.st_mode)) -# endif - time_stamp = get_stat_mtime (&istat); -#endif /* NO_STDIN_FSTAT */ - } - ifile_size = -1L; /* convention for unknown size */ + /* Get the file's time stamp and size. */ + if (fstat (fileno (stdin), &istat) != 0) + { + progerror ("standard input"); + do_exit (ERROR); + } + ifile_size = S_ISREG (istat.st_mode) ? istat.st_size : -1; + time_stamp.tv_nsec = -1; + if (!no_time || list) + time_stamp = get_stat_mtime (&istat); clear_bufs(); /* clear input and output buffers */ to_stdout = 1; part_nb = 0; + ifd = fileno(stdin); if (decompress) { method = get_method(ifd); @@ -715,48 +711,57 @@ local void treat_file(iname) program_name, ifname)); return; } - if (!S_ISREG(istat.st_mode)) { - WARN((stderr, - "%s: %s is not a directory or a regular file - ignored\n", - program_name, ifname)); - close (ifd); - return; - } - if (istat.st_mode & S_ISUID) - { - WARN ((stderr, "%s: %s is set-user-ID on execution - ignored\n", - program_name, ifname)); - close (ifd); - return; - } - if (istat.st_mode & S_ISGID) + if (! to_stdout) { - WARN ((stderr, "%s: %s is set-group-ID on execution - ignored\n", - program_name, ifname)); - close (ifd); - return; - } - if (istat.st_mode & S_ISVTX) - { - WARN ((stderr, "%s: %s has the sticky bit set - file ignored\n", - program_name, ifname)); - close (ifd); - return; - } + if (! S_ISREG (istat.st_mode)) + { + WARN ((stderr, + "%s: %s is not a directory or a regular file - ignored\n", + program_name, ifname)); + close (ifd); + return; + } + if (istat.st_mode & S_ISUID) + { + WARN ((stderr, "%s: %s is set-user-ID on execution - ignored\n", + program_name, ifname)); + close (ifd); + return; + } + if (istat.st_mode & S_ISGID) + { + WARN ((stderr, "%s: %s is set-group-ID on execution - ignored\n", + program_name, ifname)); + close (ifd); + return; + } - if (istat.st_nlink > 1 && !to_stdout && !force) { - WARN((stderr, "%s: %s has %lu other link%c -- unchanged\n", - program_name, ifname, (unsigned long) istat.st_nlink - 1, - istat.st_nlink > 2 ? 's' : ' ')); - close (ifd); - return; - } + if (! force) + { + if (istat.st_mode & S_ISVTX) + { + WARN ((stderr, + "%s: %s has the sticky bit set - file ignored\n", + program_name, ifname)); + close (ifd); + return; + } + if (2 <= istat.st_nlink) + { + WARN ((stderr, "%s: %s has %lu other link%c -- unchanged\n", + program_name, ifname, + (unsigned long int) istat.st_nlink - 1, + istat.st_nlink == 2 ? ' ' : 's')); + close (ifd); + return; + } + } + } - ifile_size = istat.st_size; - if (no_time && !list) - time_stamp.tv_nsec = -1; - else + ifile_size = S_ISREG (istat.st_mode) ? istat.st_size : -1; + time_stamp.tv_nsec = -1; + if (!no_time || list) time_stamp = get_stat_mtime (&istat); /* Generate output file name. For -r and (-t or -l), skip files @@ -954,13 +959,13 @@ local char *get_suffix(name) { int nlen, slen; char suffix[MAX_SUFFIX+3]; /* last chars of name, forced to lower case */ - static char *known_suffixes[] = + static char const *known_suffixes[] = {NULL, ".gz", ".z", ".taz", ".tgz", "-gz", "-z", "_z", #ifdef MAX_EXT_CHARS "z", #endif NULL}; - char **suf = known_suffixes; + char const **suf = known_suffixes; *suf = z_suffix; if (strequ(z_suffix, "z")) suf++; /* check long suffixes first */ @@ -1045,9 +1050,9 @@ open_input_file (iname, sbuf) { int ilen; /* strlen(ifname) */ int z_suffix_errno = 0; - static char *suffixes[] = {NULL, ".gz", ".z", "-z", ".Z", NULL}; - char **suf = suffixes; - char *s; + static char const *suffixes[] = {NULL, ".gz", ".z", "-z", ".Z", NULL}; + char const **suf = suffixes; + char const *s; #ifdef NO_MULTIPLE_DOTS char *dot; /* pointer to ifname extension, or NULL */ #endif @@ -1091,7 +1096,7 @@ open_input_file (iname, sbuf) /* Search for all suffixes */ do { - char *s0 = s = *suf; + char const *s0 = s = *suf; strcpy (ifname, iname); #ifdef NO_MULTIPLE_DOTS if (*s == '.') s++; @@ -1171,7 +1176,7 @@ local int make_ofname() } /* ofname might be changed later if infile contains an original name */ - } else if (suff != NULL) { + } else if (suff && ! force) { /* Avoid annoying messages with -r (see treat_dir()) */ if (verbose || (!recursive && !quiet)) { /* Don't use WARN, as it affects exit status. */ @@ -1247,8 +1252,13 @@ local int get_method(in) /* If try_byte returned EOF, magic[1] == (char) EOF. */ } else { magic[0] = (char)get_byte(); - magic[1] = (char)get_byte(); - imagic1 = 0; /* avoid lint warning */ + if (magic[0]) { + magic[1] = (char)get_byte(); + imagic1 = 0; /* avoid lint warning */ + } else { + imagic1 = try_byte (); + magic[1] = (char) imagic1; + } } method = -1; /* unknown yet */ part_nb++; /* number of parts in gzip file */ @@ -1279,7 +1289,7 @@ local int get_method(in) } if ((flags & CONTINUATION) != 0) { fprintf(stderr, - "%s: %s is a a multi-part gzip file -- not supported\n", + "%s: %s is a multi-part gzip file -- not supported\n", program_name, ifname); exit_code = ERROR; if (force <= 1) return -1; @@ -1427,7 +1437,7 @@ local void do_list(ifd, method) { ulg crc; /* original crc */ static int first_time = 1; - static char* methods[MAX_METHODS] = { + static char const *const methods[MAX_METHODS] = { "store", /* 0 */ "compr", /* 1 */ "pack ", /* 2 */ @@ -1643,7 +1653,7 @@ local void copy_stat(ifstat) } } - if (futimens (ofd, ofname, timespec) != 0) + if (gl_futimens (ofd, ofname, timespec) != 0) { int e = errno; WARN ((stderr, "%s: ", program_name)); @@ -1656,10 +1666,11 @@ local void copy_stat(ifstat) #endif #ifndef NO_CHOWN + /* Copy ownership */ # if HAVE_FCHOWN - fchown (ofd, ifstat->st_uid, ifstat->st_gid); /* Copy ownership */ + ignore_value (fchown (ofd, ifstat->st_uid, ifstat->st_gid)); # elif HAVE_CHOWN - chown(ofname, ifstat->st_uid, ifstat->st_gid); /* Copy ownership */ + ignore_value (chown (ofname, ifstat->st_uid, ifstat->st_gid)); # endif #endif @@ -1693,18 +1704,11 @@ local void treat_dir (fd, dir) char nbuf[MAX_PATH_LEN]; int len; -#if HAVE_FDOPENDIR dirp = fdopendir (fd); -#else - close (fd); - dirp = opendir(dir); -#endif if (dirp == NULL) { progerror(dir); -#if HAVE_FDOPENDIR close (fd); -#endif return ; } /* @@ -1761,30 +1765,7 @@ local void treat_dir (fd, dir) static void install_signal_handlers () { - static int sig[] = - { - /* SIGINT must be first, as 'foreground' depends on it. */ - SIGINT - -#ifdef SIGHUP - , SIGHUP -#endif -#ifdef SIGPIPE - , SIGPIPE -#else -# define SIGPIPE 0 -#endif -#ifdef SIGTERM - , SIGTERM -#endif -#ifdef SIGXCPU - , SIGXCPU -#endif -#ifdef SIGXFSZ - , SIGXFSZ -#endif - }; - int nsigs = sizeof sig / sizeof sig[0]; + int nsigs = sizeof handled_sig / sizeof handled_sig[0]; int i; #if SA_NOCLDSTOP @@ -1793,9 +1774,9 @@ install_signal_handlers () sigemptyset (&caught_signals); for (i = 0; i < nsigs; i++) { - sigaction (sig[i], NULL, &act); + sigaction (handled_sig[i], NULL, &act); if (act.sa_handler != SIG_IGN) - sigaddset (&caught_signals, sig[i]); + sigaddset (&caught_signals, handled_sig[i]); } act.sa_handler = abort_gzip_signal; @@ -1803,20 +1784,20 @@ install_signal_handlers () act.sa_flags = 0; for (i = 0; i < nsigs; i++) - if (sigismember (&caught_signals, sig[i])) + if (sigismember (&caught_signals, handled_sig[i])) { if (i == 0) foreground = 1; - sigaction (sig[i], &act, NULL); + sigaction (handled_sig[i], &act, NULL); } #else for (i = 0; i < nsigs; i++) - if (signal (sig[i], SIG_IGN) != SIG_IGN) + if (signal (handled_sig[i], SIG_IGN) != SIG_IGN) { if (i == 0) foreground = 1; - signal (sig[i], abort_gzip_signal); - siginterrupt (sig[i], 1); + signal (handled_sig[i], abort_gzip_signal); + siginterrupt (handled_sig[i], 1); } #endif } @@ -1831,8 +1812,10 @@ local void do_exit(exitcode) if (in_exit) exit(exitcode); in_exit = 1; - if (env != NULL) free(env), env = NULL; - if (args != NULL) free((char*)args), args = NULL; + free(env); + env = NULL; + free(args); + args = NULL; FREE(inbuf); FREE(outbuf); FREE(d_buf); @@ -1887,7 +1870,7 @@ abort_gzip_signal (sig) signal (sig, SIG_IGN); remove_output_file (); if (sig == exiting_signal) - _exit (ERROR); + _exit (WARNING); signal (sig, SIG_DFL); raise (sig); }