📄 gzip.c
字号:
/* gzip (GNU zip) -- compress files with zip algorithm and 'compress' interface * 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 (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)"," any later version.",""," This program is distributed in the hope that it will be useful,"," but WITHOUT ANY WARRANTY; without even the implied warranty of"," MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the"," GNU General Public License for more details.",""," You should have received a copy of the GNU General Public License"," along with this program; if not, write to the Free Software"," Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.",0};/* Compress files with zip algorithm and 'compress' interface. * See usage() and help() functions below for all options. * Outputs: * file.z: compressed file with same mode, owner, and utimes * file.Z: same with -Z option (old compress format) * or stdout with -c option or if stdin used as input. * If the OS does not support file names with multiple dots (MSDOS, VMS) or * if the output file name had to be truncated, the original name is kept * in the compressed .z file. (Feature not available in old compress format.) * On MSDOS, file.tmp -> file.tmz. On VMS, file.tmp -> file.tmp-z. * * For the meaning of all compilation flags, see comments in Makefile.in. */#ifndef lintstatic char rcsid[] = "$Id: gzip.c,v 0.17 1993/03/18 18:14:56 jloup Exp $";#endif#include "tailor.h"#include "gzip.h"#include "lzw.h"#include "revision.h"#include "getopt.h"#include <stdio.h>#include <ctype.h>#include <sys/types.h>#include <signal.h>#include <sys/stat.h>#include <errno.h> /* configuration */#ifndef NO_FCNTL_H# include <fcntl.h>#endif#ifdef HAVE_UNISTD_H# include <unistd.h>#endif#if defined(STDC_HEADERS) || !defined(NO_STDLIB_H)# include <stdlib.h>#else extern int errno;#endif#if defined(DIRENT) || defined(_POSIX_VERSION)# include <dirent.h> typedef struct dirent dir_type;# define NLENGTH(dirent) ((int)strlen((dirent)->d_name))# define DIR_OPT "DIRENT"#else# define NLENGTH(dirent) ((dirent)->d_namlen)# ifdef SYSDIR# include <sys/dir.h> typedef struct direct dir_type;# define DIR_OPT "SYSDIR"# else# ifdef SYSNDIR# include <sys/ndir.h> typedef struct direct dir_type;# define DIR_OPT "SYSNDIR"# else# ifdef NDIR# include <ndir.h> typedef struct direct dir_type;# define DIR_OPT "NDIR"# else# define NO_DIR# define DIR_OPT "NO_DIR"# endif# endif# endif#endif#ifndef NO_UTIME# ifndef NO_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 ""# 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)();#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#define RW_USER 0600 /* creation mode for open() */#ifndef MAX_PATH_LEN# define MAX_PATH_LEN 1024 /* max pathname length */#endif#define MAX_HEADER_LEN 16/* max length of a compressed file header, fixed part only */ /* 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 to_stdout = 0; /* output to stdout (-c) */int decompress = 0; /* decompress (-d) */int force = 0; /* don't ask questions, compress links (-f) */int recursive = 0; /* recurse through directories (-r) */int verbose = 0; /* be verbose (-v) */int quiet = 0; /* be very quiet (-q) */int quit_on_tty = 0; /* quit if compressing to or decompressing from a tty */int do_lzw = 0; /* generate output compatible with old compress (-Z) */int test = 0; /* test .z 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 = 5; /* 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 .z file */ulg time_stamp; /* original time stamp (modification time) */long 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 */long bytes_in; /* number of input bytes */long bytes_out; /* number of output bytes */char ifname[MAX_PATH_LEN]; /* input filename */char ofname[MAX_PATH_LEN]; /* output filename */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 */ {"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 .z file contents */ {"license", 0, 0, 'L'}, /* display software license */ {"quiet", 0, 0, 'q'}, /* quiet mode */ {"recurse", 0, 0, 'r'}, /* recurse through directories */ {"test", 0, 0, 't'}, /* test compressed file integrity */ {"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 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 int get_method OF((int in));local int check_ofname OF((void));local void reset_times OF((char *name, struct stat *statb));local void copy_stat OF((struct stat *ifstat));local void treat_dir OF((char *dir));local void do_exit OF((int exitcode)); int main OF((int argc, char **argv));void (*work) OF((int infile, int outfile)) = zip; /* function to call */#define strequ(s1, s2) (strcmp((s1),(s2)) == 0)/* ======================================================================== */local void usage(){ fprintf(stderr,#ifdef LZW# ifdef NO_DIR "usage: %s [-cdfhLtvVZ19] [-b maxbits] [file ...]\n",# else "usage: %s [-cdfhLrtvVZ19] [-b maxbits] [file ...]\n",# endif#else /* !LZW */# ifdef NO_DIR "usage: %s [-cdfhLtvV19] [file ...]\n",# else "usage: %s [-cdfhLrtvV19] [file ...]\n",# endif#endif /* LZW */ progname);}/* ======================================================================== */local void help(){ static char *help_msg[] = {/* -a --ascii ascii text; convert end-of-lines to local OS conventions */ " -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 .z file contents */ " -L --license display software license", " -q --quiet suppress all warnings",#ifndef NO_DIR " -r --recurse recurse through directories",#endif " -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.", 0}; char **p = help_msg; fprintf(stderr,"%s %s (%s)\n", progname, VERSION, REVDATE); usage(); while (*p) fprintf(stderr, "%s\n", *p++);}/* ======================================================================== */local void license(){ char **p = license_msg; fprintf(stderr,"%s %s (%s)\n", progname, VERSION, REVDATE); while (*p) fprintf(stderr, "%s\n", *p++);}/* ======================================================================== */local void version(){ fprintf(stderr,"%s %s (%s)\n", progname, VERSION, REVDATE); fprintf(stderr, "Compilation options:\n%s %s ", DIR_OPT, TIME_OPT);#ifdef STDC_HEADERS fprintf(stderr, "STDC_HEADERS ");#endif#ifdef HAVE_UNISTD_H fprintf(stderr, "HAVE_UNISTD_H ");#endif#ifdef NO_MEMORY_H fprintf(stderr, "NO_MEMORY_H ");#endif#ifdef NO_STRING_H fprintf(stderr, "NO_STRING_H ");#endif#ifdef NO_SYMLINK fprintf(stderr, "NO_SYMLINK ");#endif#ifdef NO_MULTIPLE_DOTS fprintf(stderr, "NO_MULTIPLE_DOTS ");#endif#ifdef NO_CHOWN fprintf(stderr, "NO_CHOWN ");#endif#ifdef PROTO fprintf(stderr, "PROTO ");#endif#ifdef ASMV fprintf(stderr, "ASMV ");#endif#ifdef DEBUG fprintf(stderr, "DEBUG ");#endif#ifdef DYN_ALLOC fprintf(stderr, "DYN_ALLOC ");#endif#ifdef MAXSEG_64K fprintf(stderr, "MAXSEG_64K");#endif fprintf(stderr, "\n");}/* ======================================================================== */int main (argc, argv) int argc; char **argv;{ int file_count = 0; /* number of files to precess */ int proglen; /* length of progname */ int optc; /* current option */ EXPAND(argc, argv); /* wild card expansion if necessary */ progname = basename(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); if (env != NULL) args = argv; foreground = signal(SIGINT, SIG_IGN) != SIG_IGN; if (foreground) { signal (SIGINT, (sig_type)abort_gzip); }#ifdef SIGTERM signal(SIGTERM, (sig_type)abort_gzip);#endif#ifdef SIGHUP signal(SIGHUP, (sig_type)abort_gzip);#endif#ifndef GNU_STANDARD /* For compatibility with old compress, use program name as an option. * If you compile with -DGNU_STANDARD, 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. * Ignore an .exe extension for MSDOS, OS/2 and VMS. */ if ( strncmp(progname, "un", 2) == 0 /* ungzip, uncompress */ || strncmp(progname, "gun", 3) == 0) { /* gunzip */ decompress = 1; } else if (strequ(progname+1, "cat") /* zcat, pcat */ || strequ(progname, "gzcat")) { /* gzcat */ decompress = to_stdout = 1; }#endif while ((optc = getopt_long (argc, argv, "b:cdfhLqrtvVZ123456789", longopts, (int *)0)) != EOF) { switch (optc) { case 'b': maxbits = atoi(optarg); break; case 'c': to_stdout = 1; break; case 'd': decompress = 1; break; case 'f': force++; break; case 'h': help(); do_exit(OK); break; case 'L': license(); do_exit(OK); break; case 'q': quiet = 1; verbose = 0; break; case 'r':#ifdef NO_DIR fprintf(stderr, "%s: -r not supported on this system\n", progname); usage(); do_exit(ERROR); break;#else recursive = 1; break;#endif case 't': test = decompress = to_stdout = 1; break; case 'v': verbose++; quiet = 0; break; case 'V': version(); quit_on_tty = 1; break; case 'Z':#ifdef LZW do_lzw = 1; break;#else fprintf(stderr, "%s: -Z not supported in this version\n", progname);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -