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

📄 gzip.c

📁 GZip Compress Souce Code
💻 C
📖 第 1 页 / 共 5 页
字号:
			DBGPrintfo(("treat_stdin(out2)\r\n"));			return -1;         }		if (!decompress || last_member || inptr == insize) break;		/* end of file */		method = get_method(ifd);		if (method < 0) 		{			DBGPrintfo(("treat_stdin(out21)\r\n"));			return -1; /* 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	}    }  }  DBGPrintfo(("treat_stdin(out)\r\n"));}#endif/* ======================================================================== * Compress or decompress the given file */local int treat_file(iname)    char *iname;{  DBGPrintfi(("treat_file(In)\r\n"));  {  }  DBGPrintfo(("treat_file(out)\r\n"));  return 0;}#if 0local int treat_file(iname)    char *iname;{  DBGPrintfi(("treat_file(In)\r\n"));  {    /* Accept "-" as synonym for stdin */    if (strequ(iname, "-")) {		int cflag = to_stdout;		if ( treat_stdin() < 0 ) return -1;		// by bskim		to_stdout = cflag;				DBGPrintfo(("treat_file(out1)\r\n"));		return 0;    }    /* Check if the input file is present, set ifname and istat: */    if (get_istat(iname, &istat) != OK) {                                          DBGPrintfo(("treat_file(out2)\r\n"));                                         return 1;                                         }    /* 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));		DBGPrintfo(("treat_file(out3)\r\n"));	return ;    }    if (!S_ISREG(istat.st_mode)) {	WARN((stderr,	      "%s: %s is not a directory or a regular file - ignored\n",	      progname, ifname));		DBGPrintfo(("treat_file(out4)\r\n"));	return 1;    }    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' : ' '));		DBGPrintfo(("treat_file(out5)\r\n"));	return 1;    }    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) {	DBGPrintfo(("treat_file(out6)\r\n"));	return 1;    }    /* 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;		DBGPrintfo(("treat_file(out7)\r\n"));	return 1;    }    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);	        	DBGPrintfo(("treat_file(out8)\r\n"));    	return 1;               /* error message already emitted */	}    }    if (list) {        do_list(ifd, method);        close(ifd);                DBGPrintfo(("treat_file(out9)\r\n"));        return 1;    }    /* 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) {                             	 DBGPrintfo(("treat_file(out10)\r\n"));                            	 return 1;                             	}	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();		return -1;    }    if (method == -1) {	if (!to_stdout) unlink (ofname);		DBGPrintfo(("treat_file(out11)\r\n"));	return 1;    }    /* 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);    }  }  DBGPrintfo(("treat_file(out)\r\n"));  return 0;}#endif/* ======================================================================== * 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(){  DBGPrintfi(("create_outfile(In)\r\n"));  {    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);	        	DBGPrintfo(("create_outfile(out1)\r\n"));    	return  ERROR;	}	/* Create the output file */	remove_ofname = 1;	ofd = OPEN(ofname, flags, RW_USER);	if (ofd == -1) {	    perror(ofname);	    close(ifd);	    exit_code = ERROR;	        	DBGPrintfo(("create_outfile(out2)\r\n"));    	return  ERROR;	}	/* Check for name truncation on new file (1234567890123.gz) */#ifdef NO_FSTAT	if (stat(ofname, &ostat) != 0) {#else	if (fstat(ofd, &ostat) != 0) {#endif	    fprintf(stderr, "%s: ", progname);	    perror(ofname);	    close(ifd); close(ofd);	    unlink(ofname);	    exit_code = ERROR;	        	DBGPrintfo(("create_outfile(out3)\r\n"));    	return  ERROR;	}	if (!name_too_long(ofname, &ostat)) {                                     	 DBGPrintfo(("create_outfile(out4)\r\n"));                                    	 return  OK;                                     	}	if (decompress) {	    /* name might be too long if an original name was saved */	    WARN((stderr, "%s: %s: warning, name truncated\n",		  progname, ofname));	        	DBGPrintfo(("create_outfile(out5)\r\n"));    	return  OK;	}	close(ofd);	unlink(ofname);#ifdef NO_MULTIPLE_DOTS	/* Should never happen, see check_ofname() */	fprintf(stderr, "%s: %s: name too long\n", progname, ofname);	do_exit(ERROR);#endif		if ( shorten_name(ofname) < 0 ) 		{			DBGPrintfo(("create_outfile(out41)\r\n"));			return -1;		}    }  }}/* ======================================================================== * Use lstat if available, except for -c or -f. Use stat otherwise. * This allows links when not removing the original file. */local int do_stat(name, sbuf)    char *name;    struct stat *sbuf;{  DBGPrintfi(("do_stat(In)\r\n"));  {    errno = 0;#if (defined(S_IFLNK) || defined (S_ISLNK)) && !defined(NO_SYMLINK)    if (!to_stdout && !force) {	int retTemp;	retTemp=(int)( lstat(name, sbuf));	DBGPrintfo(("do_stat(out1)\r\n"));	return retTemp;    }#endif    {      int retTemp;     retTemp=(int)( stat(name, sbuf));     DBGPrintfo(("do_stat(out2)\r\n"));     return retTemp;    }  }}/* ======================================================================== * Return a pointer to the 'z' suffix of a file name, or NULL. For all * systems, ".gz", ".z", ".Z", ".taz", ".tgz", "-gz", "-z" and "_z" are * accepted suffixes, in addition to the value of the --suffix option. * ".tgz" is a useful convention for tar.z files on systems limited * to 3 characters extensions. On such systems, ".?z" and ".??z" are * also accepted suffixes. For Unix, we do not want to accept any * .??z suffix as indicating a compressed file; some people use .xyz * to denote volume data. *   On systems allowing multiple versions of the same file (such as VMS), * this function removes any version suffix in the given name. */local char *get_suffix(name)    char *name;{  DBGPrintfi(("get_suffix(In)\r\n"));  {    int nlen, slen;    char suffix[MAX_SUFFIX+3]; /* last chars of name, forced to lower case */    static char *known_suffixes[] =       {z_suffix, ".gz", ".z", ".taz", ".tgz", "-gz", "-z", "_z",#ifdef MAX_EXT_CHARS          "z",#endif          NULL};    char **suf = known_suffixes;    if (strequ(z_suffix, "z")) suf++; /* check long suffixes first */#ifdef SUFFIX_SEP    /* strip a version number from the file name */    {	char *v = strrchr(name, SUFFIX_SEP); 	if (v != NULL) *v = '\0';    }#endif    nlen = (int)strlen(name);    if (nlen <= MAX_SUFFIX+2) {        strcpy(suffix, name);    } else {        strcpy(suffix, name+nlen-MAX_SUFFIX-2);    }    strlwr(suffix);    slen = (int)strlen(suffix);    do {       int s = (int)strlen(*suf);       if (slen > s && suffix[slen-s-1] != PATH_SEP           && strequ(suffix + slen - s, *suf)) {           DBGPrintfo(("get_suffix(out1)\r\n"));           return  name+nlen-s;       }    } while (*++suf != NULL);    DBGPrintfo(("get_suffix(out2)\r\n"));    return  NULL;  }}/* ======================================================================== * Set ifname to the input file name (with a suffix appended if necessary) * and istat to its stats. For decompression, if no file exists with the * original name, try adding successively z_suffix, .gz, .z, -z and .Z. * For MSDOS, we try only z_suffix and z. * Return OK or ERROR. */local int get_istat(iname, sbuf)    char *iname;    struct stat *sbuf;{  DBGPrintfi(("get_istat(In)\r\n"));  {    int ilen;  /* strlen(ifname) */    static char *suffixes[] = {z_suffix, ".gz", ".z", "-z", ".Z", NULL};    char **suf = suffixes;    char *s;#ifdef NO_MULTIPLE_DOTS    char *dot; /* pointer to ifname extension, or NULL */#endif    strcpy(ifname, iname);    /* If input file exists, return OK. */    if (do_stat(ifname, sbuf) == 0) {                                      DBGPrintfo(("get_istat(out1)\r\n"));                                     return  OK;                                     }    if (!decompress || errno != ENOENT) {	perror(ifname);	exit_code = ERROR;		DBGPrintfo(("get_istat(out2)\r\n"));	return  ERROR;    }    /* file.ext doesn't exist, try adding a suffix (after removing any     * version number for VMS).     */    s = get_suffix(ifname);    if (s != NULL) {	perror(ifname); /* ifname already has z suffix and does not exist */	exit_code = ERROR;		DBGPrintfo(("get_istat(out3)\r\n"));	return  ERROR;    }#ifdef NO_MULTIPLE_DOTS    dot = strrchr(ifname, '.');    if (dot == NULL) {        strcat(ifname, ".");        dot = strrchr(ifname, '.');

⌨️ 快捷键说明

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