📄 gzip.c
字号:
/* gzip (GNU zip) -- compress files with zip algorithm and 'compress' interface * Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc. * Copyright (C) 1992-1993 Jean-loup Gailly * The unzip code was written and put in the public domain by Mark Adler. * Portions of the lzw code are derived from the public domain 'compress' * written by Spencer Thomas, Joe Orost, James Woods, Jim McKie, Steve Davies, * Ken Turkowski, Dave Mack and Peter Jannesen. * * See the license_msg below and the file COPYING for the software license. * See the file algorithm.doc for the compression algorithms and file formats. */static char *license_msg[] = {"Copyright 2002 Free Software Foundation","Copyright 1992-1993 Jean-loup Gailly","This program comes with ABSOLUTELY NO WARRANTY.","You may redistribute copies of this program","under the terms of the GNU General Public License.","For more information about these matters, see the file named COPYING.",0};/* Compress files with zip algorithm and 'compress' interface. * See usage() and help() functions below for all options. * Outputs: * file.gz: compressed file with same mode, owner, and utimes * or stdout with -c option or if stdin used as input. * If the output file name had to be truncated, the original name is kept * in the compressed file. * On MSDOS, file.tmp -> file.tmz. On VMS, file.tmp -> file.tmp-gz. * * Using gz on MSDOS would create too many file name conflicts. For * example, foo.txt -> foo.tgz (.tgz must be reserved as shorthand for * tar.gz). Similarly, foo.dir and foo.doc would both be mapped to foo.dgz. * I also considered 12345678.txt -> 12345txt.gz but this truncates the name * too heavily. There is no ideal solution given the MSDOS 8+3 limitation. * * For the meaning of all compilation flags, see comments in Makefile.in. */#ifdef RCSIDstatic char rcsid[] = "$Id: gzip.c,v 0.24 1993/06/24 10:52:07 jloup Exp $";#endif#include <config.h>#include <ctype.h>#include <sys/types.h>#include <signal.h>#include <sys/stat.h>#include <errno.h>#include "tailor.h"#include "gzip.h"#include "lzw.h"#include "revision.h"#include "getopt.h" /* configuration */#ifdef HAVE_TIME_H# include <time.h>#else# include <sys/time.h>#endif#ifdef HAVE_FCNTL_H# include <fcntl.h>#endif#ifdef HAVE_LIMITS_H# include <limits.h>#endif#ifdef HAVE_UNISTD_H# include <unistd.h>#endif#if defined STDC_HEADERS || defined HAVE_STDLIB_H# include <stdlib.h>#else extern int errno;#endif#ifdef HAVE_DIRENT_H# include <dirent.h># define NAMLEN(direct) strlen((direct)->d_name)# define DIR_OPT "DIRENT"#else# define dirent direct# define NAMLEN(direct) ((direct)->d_namlen)# ifdef HAVE_SYS_NDIR_H# include <sys/ndir.h># define DIR_OPT "SYS_NDIR"# endif# ifdef HAVE_SYS_DIR_H# include <sys/dir.h># define DIR_OPT "SYS_DIR"# endif# ifdef HAVE_NDIR_H# include <ndir.h># define DIR_OPT "NDIR"# endif# ifndef DIR_OPT# define DIR_OPT "NO_DIR"# endif#endif#ifdef CLOSEDIR_VOID# define CLOSEDIR(d) (closedir(d), 0)#else# define CLOSEDIR(d) closedir(d)#endif#ifdef HAVE_UTIME# ifdef HAVE_UTIME_H# include <utime.h># define TIME_OPT "UTIME"# else# ifdef HAVE_SYS_UTIME_H# include <sys/utime.h># define TIME_OPT "SYS_UTIME"# else struct utimbuf { time_t actime; time_t modtime; };# define TIME_OPT "STRUCT_UTIMBUF"# endif# endif#else# define TIME_OPT "NO_UTIME"#endif#if !defined(S_ISDIR) && defined(S_IFDIR)# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)#endif#if !defined(S_ISREG) && defined(S_IFREG)# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)#endiftypedef RETSIGTYPE (*sig_type) OF((int));#ifndef O_BINARY# define O_BINARY 0 /* creation mode for open() */#endif#ifndef O_CREAT /* Pure BSD system? */# include <sys/file.h># ifndef O_CREAT# define O_CREAT FCREAT# endif# ifndef O_EXCL# define O_EXCL FEXCL# endif#endif#ifndef S_IRUSR# define S_IRUSR 0400#endif#ifndef S_IWUSR# define S_IWUSR 0200#endif#define RW_USER (S_IRUSR | S_IWUSR) /* creation mode for open() */#ifndef MAX_PATH_LEN# define MAX_PATH_LEN 1024 /* max pathname length */#endif#ifndef SEEK_END# define SEEK_END 2#endif#ifndef CHAR_BIT# define CHAR_BIT 8#endif#ifdef off_t off_t lseek OF((int fd, off_t offset, int whence));#endif#ifndef OFF_T_MIN#define OFF_T_MIN (~ (off_t) 0 << (sizeof (off_t) * CHAR_BIT - 1))#endif#ifndef OFF_T_MAX#define OFF_T_MAX (~ (off_t) 0 - OFF_T_MIN)#endif/* Separator for file name parts (see shorten_name()) */#ifdef NO_MULTIPLE_DOTS# define PART_SEP "-"#else# define PART_SEP "."#endif /* global buffers */DECLARE(uch, inbuf, INBUFSIZ +INBUF_EXTRA);DECLARE(uch, outbuf, OUTBUFSIZ+OUTBUF_EXTRA);DECLARE(ush, d_buf, DIST_BUFSIZE);DECLARE(uch, window, 2L*WSIZE);#ifndef MAXSEG_64K DECLARE(ush, tab_prefix, 1L<<BITS);#else DECLARE(ush, tab_prefix0, 1L<<(BITS-1)); DECLARE(ush, tab_prefix1, 1L<<(BITS-1));#endif /* local variables */int ascii = 0; /* convert end-of-lines to local OS conventions */int to_stdout = 0; /* output to stdout (-c) */int decompress = 0; /* decompress (-d) */int force = 0; /* don't ask questions, compress links (-f) */int no_name = -1; /* don't save or restore the original file name */int no_time = -1; /* don't save or restore the original file time */int recursive = 0; /* recurse through directories (-r) */int list = 0; /* list the file contents (-l) */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 */char *progname; /* program name */int maxbits = BITS; /* max bits per code for LZW */int method = DEFLATED;/* compression method */int level = 6; /* compression level */int exit_code = OK; /* program exit code */int save_orig_name; /* set if original name must be saved */int last_member; /* set for .zip and .Z files */int part_nb; /* number of parts in .gz file */time_t 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) */size_t z_len; /* strlen(z_suffix) */off_t bytes_in; /* number of input bytes */off_t bytes_out; /* number of output bytes */off_t total_in; /* input bytes for all files */off_t total_out; /* output bytes for all files */char ifname[MAX_PATH_LEN]; /* input file name */char ofname[MAX_PATH_LEN]; /* output file name */int remove_ofname = 0; /* remove output file on error */struct stat istat; /* status for input file */int ifd; /* input file descriptor */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 */struct option longopts[] ={ /* { name has_arg *flag val } */ {"ascii", 0, 0, 'a'}, /* ascii text mode */ {"to-stdout", 0, 0, 'c'}, /* write output on standard output */ {"stdout", 0, 0, 'c'}, /* write output on standard output */ {"decompress", 0, 0, 'd'}, /* decompress */ {"uncompress", 0, 0, 'd'}, /* decompress */ /* {"encrypt", 0, 0, 'e'}, encrypt */ {"force", 0, 0, 'f'}, /* force overwrite of output file */ {"help", 0, 0, 'h'}, /* give help */ /* {"pkzip", 0, 0, 'k'}, force output in pkzip format */ {"list", 0, 0, 'l'}, /* list .gz file contents */ {"license", 0, 0, 'L'}, /* display software license */ {"no-name", 0, 0, 'n'}, /* don't save or restore original name & time */ {"name", 0, 0, 'N'}, /* save or restore original name & time */ {"quiet", 0, 0, 'q'}, /* quiet mode */ {"silent", 0, 0, 'q'}, /* quiet mode */ {"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 */ {"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) */ { 0, 0, 0, 0 }};/* local functions */local void usage OF((void));local void help OF((void));local void license OF((void));local void version OF((void));local int input_eof OF((void));local void treat_stdin OF((void));local void treat_file OF((char *iname));local int create_outfile OF((void));local int do_stat OF((char *name, struct stat *sbuf));local char *get_suffix OF((char *name));local int get_istat OF((char *iname, struct stat *sbuf));local int make_ofname OF((void));local int same_file OF((struct stat *stat1, struct stat *stat2));local int name_too_long OF((char *name, struct stat *statb));local void shorten_name OF((char *name));local int get_method OF((int in));local void do_list OF((int ifd, int method));local int check_ofname OF((void));local void copy_stat OF((struct stat *ifstat));local void do_exit OF((int exitcode)); int main OF((int argc, char **argv));int (*work) OF((int infile, int outfile)) = zip; /* function to call */#ifndef NO_DIRlocal void treat_dir OF((char *dir));#endif#ifdef HAVE_UTIMElocal void reset_times OF((char *name, struct stat *statb));#endif#define strequ(s1, s2) (strcmp((s1),(s2)) == 0)/* ======================================================================== */local void usage(){ printf ("usage: %s [-%scdfhlLnN%stvV19] [-S suffix] [file ...]\n", progname,#if O_BINARY "a",#else "",#endif#ifdef NO_DIR ""#else "r"#endif );}/* ======================================================================== */local void help(){ static char *help_msg[] = {#if O_BINARY " -a --ascii ascii text; convert end-of-lines using local conventions",#endif " -c --stdout write on standard output, keep original files unchanged", " -d --decompress decompress",/* -e --encrypt encrypt */ " -f --force force overwrite of output file and compress links", " -h --help give this help",/* -k --pkzip force output in pkzip format */ " -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 --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", " -q --quiet suppress all warnings",#ifndef NO_DIR " -r --recursive operate recursively on directories",#endif " -S .suf --suffix .suf use suffix .suf on compressed files", " -t --test test compressed file integrity", " -v --verbose verbose mode", " -V --version display version number", " -1 --fast compress faster", " -9 --best compress better",#ifdef LZW " -Z --lzw produce output compatible with old compress", " -b --bits maxbits max number of bits per code (implies -Z)",#endif " file... files to (de)compress. If none given, use standard input.", "Report bugs to <bug-gzip@gnu.org>.", 0}; char **p = help_msg; printf ("%s %s\n(%s)\n", progname, VERSION, REVDATE); usage(); while (*p) printf ("%s\n", *p++);}/* ======================================================================== */local void license(){ char **p = license_msg; printf ("%s %s\n(%s)\n", progname, VERSION, REVDATE); while (*p) printf ("%s\n", *p++);}/* ======================================================================== */local void version(){ license (); printf ("Compilation options:\n%s %s ", DIR_OPT, TIME_OPT);#ifdef STDC_HEADERS printf ("STDC_HEADERS ");#endif#ifdef HAVE_UNISTD_H printf ("HAVE_UNISTD_H ");#endif#ifdef HAVE_MEMORY_H printf ("HAVE_MEMORY_H ");#endif#ifdef HAVE_STRING_H printf ("HAVE_STRING_H ");#endif#ifdef HAVE_LSTAT printf ("HAVE_LSTAT ");#endif#ifdef NO_MULTIPLE_DOTS printf ("NO_MULTIPLE_DOTS ");#endif#ifdef HAVE_CHOWN printf ("HAVE_CHOWN ");#endif#ifdef PROTO printf ("PROTO ");#endif#ifdef ASMV printf ("ASMV ");#endif#ifdef DEBUG printf ("DEBUG ");#endif#ifdef DYN_ALLOC printf ("DYN_ALLOC ");#endif#ifdef MAXSEG_64K printf ("MAXSEG_64K");#endif printf ("\n"); printf ("Written by Jean-loup Gailly.\n");}local void progerror (string) char *string;{ int e = errno; fprintf(stderr, "%s: ", progname); errno = e; perror(string); exit_code = ERROR;}/* ======================================================================== */int main (argc, argv) int argc; char **argv;{ int file_count; /* number of files to precess */ int proglen; /* length of progname */ int optc; /* current option */ EXPAND(argc, argv); /* wild card expansion if necessary */ progname = base_name (argv[0]); proglen = strlen(progname); /* Suppress .exe for MSDOS, OS/2 and VMS: */ if (proglen > 4 && strequ(progname+proglen-4, ".exe")) { progname[proglen-4] = '\0'; } /* Add options in GZIP environment variable if there is one */ env = add_envopt(&argc, &argv, OPTIONS_VAR);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -