⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gzip.c

📁 一些关于HTTP协议处理的文档,还包括了gzip包(它是用来解压缩HTTP传送的压缩数据)
💻 C
📖 第 1 页 / 共 4 页
字号:
    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) {	(void) signal (SIGINT, (sig_type)abort_gzip);    }#ifdef SIGTERM    if (signal(SIGTERM, SIG_IGN) != SIG_IGN) {	(void) signal(SIGTERM, (sig_type)abort_gzip);    }#endif#ifdef SIGHUP    if (signal(SIGHUP, SIG_IGN) != SIG_IGN) {	(void) 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, gcat */	    || strequ(progname, "gzcat")) {    /* gzcat */	decompress = to_stdout = 1;    }#endif    strncpy(z_suffix, Z_SUFFIX, sizeof(z_suffix)-1);    z_len = strlen(z_suffix);    while ((optc = getopt_long (argc, argv, "ab:cdfhH?lLmMnNqrS:tvVZ123456789",				longopts, (int *)0)) != EOF) {	switch (optc) {        case 'a':            ascii = 1; break;	case 'b':	    maxbits = atoi(optarg);	    break;	case 'c':	    to_stdout = 1; break;	case 'd':	    decompress = 1; break;	case 'f':	    force++; break;	case 'h': case 'H': case '?':	    help(); do_exit(OK); break;	case 'l':	    list = decompress = to_stdout = 1; break;	case 'L':	    license(); do_exit(OK); break;	case 'm': /* undocumented, may change later */	    no_time = 1; break;	case 'M': /* undocumented, may change later */	    no_time = 0; break;	case 'n':	    no_name = no_time = 1; break;	case 'N':	    no_name = no_time = 0; 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 'S':#ifdef NO_MULTIPLE_DOTS            if (*optarg == '.') optarg++;#endif            z_len = strlen(optarg);            strcpy(z_suffix, optarg);            break;	case 't':	    test = decompress = to_stdout = 1;	    break;	case 'v':	    verbose++; quiet = 0; break;	case 'V':	    version(); do_exit(OK); break;	case 'Z':#ifdef LZW	    do_lzw = 1; break;#else	    fprintf(stderr, "%s: -Z not supported in this version\n",		    progname);	    usage();	    do_exit(ERROR); break;#endif	case '1':  case '2':  case '3':  case '4':	case '5':  case '6':  case '7':  case '8':  case '9':	    level = optc - '0';	    break;	default:	    /* Error message already emitted by getopt_long. */	    usage();	    do_exit(ERROR);	}    } /* loop on all arguments */    /* By default, save name and timestamp on compression but do not     * restore them on decompression.     */    if (no_time < 0) no_time = decompress;    if (no_name < 0) no_name = decompress;    file_count = argc - optind;#if O_BINARY#else    if (ascii && !quiet) {	fprintf(stderr, "%s: option --ascii ignored on this system\n",		progname);    }#endif    if ((z_len == 0 && !decompress) || z_len > MAX_SUFFIX) {        fprintf(stderr, "%s: incorrect suffix '%s'\n",                progname, optarg);        do_exit(ERROR);    }    if (do_lzw && !decompress) work = lzw;    /* Allocate all global buffers (for DYN_ALLOC option) */    ALLOC(uch, inbuf,  INBUFSIZ +INBUF_EXTRA);    ALLOC(uch, outbuf, OUTBUFSIZ+OUTBUF_EXTRA);    ALLOC(ush, d_buf,  DIST_BUFSIZE);    ALLOC(uch, window, 2L*WSIZE);#ifndef MAXSEG_64K    ALLOC(ush, tab_prefix, 1L<<BITS);#else    ALLOC(ush, tab_prefix0, 1L<<(BITS-1));    ALLOC(ush, tab_prefix1, 1L<<(BITS-1));#endif    /* And get to work */    if (file_count != 0) {	if (to_stdout && !test && !list && (!decompress || !ascii)) {	    SET_BINARY_MODE(fileno(stdout));	}        while (optind < argc) {	    treat_file(argv[optind++]);	}    } else {  /* Standard input */	treat_stdin();    }    if (list && !quiet && file_count > 1) {	do_list(-1, -1); /* print totals */    }    do_exit(exit_code);    return exit_code; /* just to avoid lint warning */}/* ======================================================================== * Compress or decompress stdin */local void treat_stdin(){    if (!force && !list &&	isatty(fileno((FILE *)(decompress ? stdin : stdout)))) {	/* Do not send compressed data to the terminal or read it from	 * the terminal. We get here when user invoked the program	 * without parameters, so be helpful. According to the GNU standards:	 *	 *   If there is one behavior you think is most useful when the output	 *   is to a terminal, and another that you think is most useful when	 *   the output is a file or a pipe, then it is usually best to make	 *   the default behavior the one that is useful with output to a	 *   terminal, and have an option for the other behavior.	 *	 * Here we use the --force option to get the other behavior.	 */	fprintf(stderr,    "%s: compressed data not %s a terminal. Use -f to force %scompression.\n",		progname, decompress ? "read from" : "written to",		decompress ? "de" : "");	fprintf(stderr,"For help, type: %s -h\n", progname);	do_exit(ERROR);    }    if (decompress || !ascii) {	SET_BINARY_MODE(fileno(stdin));    }    if (!test && !list && (!decompress || !ascii)) {	SET_BINARY_MODE(fileno(stdout));    }    strcpy(ifname, "stdin");    strcpy(ofname, "stdout");    /* Get the time stamp on the input file. */    time_stamp = 0; /* time unknown by default */#ifndef NO_STDIN_FSTAT    if (list || !no_time) {	if (fstat(fileno(stdin), &istat) != 0) {	    error("fstat(stdin)");	}# ifdef NO_PIPE_TIMESTAMP	if (S_ISREG(istat.st_mode))# endif	    time_stamp = istat.st_mtime;#endif /* NO_STDIN_FSTAT */    }    ifile_size = -1L; /* convention for unknown size */    clear_bufs(); /* clear input and output buffers */    to_stdout = 1;    part_nb = 0;    if (decompress) {	method = get_method(ifd);	if (method < 0) {	    do_exit(exit_code); /* error message already emitted */	}    }    if (list) {        do_list(ifd, method);        return;    }    /* Actually do the compression/decompression. Loop over zipped members.     */    for (;;) {	if ((*work)(fileno(stdin), fileno(stdout)) != OK) return;	if (!decompress || last_member || inptr == insize) break;	/* end of file */	method = get_method(ifd);	if (method < 0) return; /* error message already emitted */	bytes_out = 0;            /* required for length check */    }    if (verbose) {	if (test) {	    fprintf(stderr, " OK\n");	} else if (!decompress) {	    display_ratio(bytes_in-(bytes_out-header_bytes), bytes_in, stderr);	    fprintf(stderr, "\n");#ifdef DISPLAY_STDIN_RATIO	} else {	    display_ratio(bytes_out-(bytes_in-header_bytes), bytes_out,stderr);	    fprintf(stderr, "\n");#endif	}    }}/* ======================================================================== * Compress or decompress the given file */local void treat_file(iname)    char *iname;{    /* Accept "-" as synonym for stdin */    if (strequ(iname, "-")) {	int cflag = to_stdout;	treat_stdin();	to_stdout = cflag;	return;    }    /* Check if the input file is present, set ifname and istat: */    if (get_istat(iname, &istat) != OK) return;    /* If the input name is that of a directory, recurse or ignore: */    if (S_ISDIR(istat.st_mode)) {#ifndef NO_DIR	if (recursive) {	    struct stat st;	    st = istat;	    treat_dir(iname);	    /* Warning: ifname is now garbage */#  ifndef NO_UTIME	    reset_times (iname, &st);#  endif	} else#endif	WARN((stderr,"%s: %s is a directory -- ignored\n", progname, ifname));	return;    }    if (!S_ISREG(istat.st_mode)) {	WARN((stderr,	      "%s: %s is not a directory or a regular file - ignored\n",	      progname, ifname));	return;    }    if (istat.st_nlink > 1 && !to_stdout && !force) {	WARN((stderr, "%s: %s has %d other link%c -- unchanged\n",	      progname, ifname,	      (int)istat.st_nlink - 1, istat.st_nlink > 2 ? 's' : ' '));	return;    }    ifile_size = istat.st_size;    time_stamp = no_time && !list ? 0 : istat.st_mtime;    /* Generate output file name. For -r and (-t or -l), skip files     * without a valid gzip suffix (check done in make_ofname).     */    if (to_stdout && !list && !test) {	strcpy(ofname, "stdout");    } else if (make_ofname() != OK) {	return;    }    /* Open the input file and determine compression method. The mode     * parameter is ignored but required by some systems (VMS) and forbidden     * on other systems (MacOS).     */    ifd = OPEN(ifname, ascii && !decompress ? O_RDONLY : O_RDONLY | O_BINARY,	       RW_USER);    if (ifd == -1) {	fprintf(stderr, "%s: ", progname);	perror(ifname);	exit_code = ERROR;	return;    }    clear_bufs(); /* clear input and output buffers */    part_nb = 0;    if (decompress) {	method = get_method(ifd); /* updates ofname if original given */	if (method < 0) {	    close(ifd);	    return;               /* error message already emitted */	}    }    if (list) {        do_list(ifd, method);        close(ifd);        return;    }    /* If compressing to a file, check if ofname is not ambiguous     * because the operating system truncates names. Otherwise, generate     * a new ofname and save the original name in the compressed file.     */    if (to_stdout) {	ofd = fileno(stdout);	/* keep remove_ofname as zero */    } else {	if (create_outfile() != OK) return;	if (!decompress && save_orig_name && !verbose && !quiet) {	    fprintf(stderr, "%s: %s compressed to %s\n",		    progname, ifname, ofname);	}    }    /* Keep the name even if not truncated except with --no-name: */    if (!save_orig_name) save_orig_name = !no_name;    if (verbose) {	fprintf(stderr, "%s:\t%s", ifname, (int)strlen(ifname) >= 15 ? 		"" : ((int)strlen(ifname) >= 7 ? "\t" : "\t\t"));    }    /* Actually do the compression/decompression. Loop over zipped members.     */    for (;;) {	if ((*work)(ifd, ofd) != OK) {	    method = -1; /* force cleanup */	    break;	}	if (!decompress || last_member || inptr == insize) break;	/* end of file */	method = get_method(ifd);	if (method < 0) break;    /* error message already emitted */	bytes_out = 0;            /* required for length check */    }    close(ifd);    if (!to_stdout && close(ofd)) {	write_error();    }    if (method == -1) {	if (!to_stdout) unlink (ofname);	return;    }    /* Display statistics */    if(verbose) {	if (test) {	    fprintf(stderr, " OK");	} else if (decompress) {	    display_ratio(bytes_out-(bytes_in-header_bytes), bytes_out,stderr);	} else {	    display_ratio(bytes_in-(bytes_out-header_bytes), bytes_in, stderr);	}	if (!test && !to_stdout) {	    fprintf(stderr, " -- replaced with %s", ofname);	}	fprintf(stderr, "\n");    }    /* Copy modes, times, ownership, and remove the input file */    if (!to_stdout) {	copy_stat(&istat);    }}/* ======================================================================== * Create the output file. Return OK or ERROR. * Try several times if necessary to avoid truncating the z_suffix. For * example, do not create a compressed file of name "1234567890123." * Sets save_orig_name to true if the file name has been truncated. * IN assertions: the input file has already been open (ifd is set) and *   ofname has already been updated if there was an original name. * OUT assertions: ifd and ofd are closed in case of error. */local int create_outfile(){    struct stat	ostat; /* stat for ofname */    int flags = O_WRONLY | O_CREAT | O_EXCL | O_BINARY;    if (ascii && decompress) {	flags &= ~O_BINARY; /* force ascii text mode */    }    for (;;) {	/* Make sure that ofname is not an existing file */	if (check_ofname() != OK) {	    close(ifd);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -