📄 gzip.c
字号:
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 + -