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

📄 gzip.c

📁 GZip Compress Souce Code
💻 C
📖 第 1 页 / 共 5 页
字号:
    }#endif    ilen = strlen(ifname);    if (strequ(z_suffix, ".gz")) suf++;    /* Search for all suffixes */    do {        s = *suf;#ifdef NO_MULTIPLE_DOTS        if (*s == '.') s++;#endif#ifdef MAX_EXT_CHARS        strcpy(ifname, iname);        /* Needed if the suffixes are not sorted by increasing length */        if (*dot == '\0') strcpy(dot, ".");        dot[MAX_EXT_CHARS+1-strlen(s)] = '\0';#endif        strcat(ifname, s);        if (do_stat(ifname, sbuf) == 0) {                                          DBGPrintfo(("get_istat(out4)\r\n"));                                         return  OK;                                         }	ifname[ilen] = '\0';    } while (*++suf != NULL);    /* No suffix found, complain using z_suffix: */#ifdef MAX_EXT_CHARS    strcpy(ifname, iname);    if (*dot == '\0') strcpy(dot, ".");    dot[MAX_EXT_CHARS+1-z_len] = '\0';#endif    strcat(ifname, z_suffix);    perror(ifname);    exit_code = ERROR;        DBGPrintfo(("get_istat(out5)\r\n"));    return  ERROR;  }}/* ======================================================================== * Generate ofname given ifname. Return OK, or WARNING if file must be skipped. * Sets save_orig_name to true if the file name has been truncated. */local int make_ofname(){  DBGPrintfi(("make_ofname(In)\r\n"));  {    char *suff;            /* ofname z suffix */    strcpy(ofname, ifname);    /* strip a version number if any and get the gzip suffix if present: */    suff = get_suffix(ofname);    if (decompress) {	if (suff == NULL) {	    /* Whith -t or -l, try all files (even without .gz suffix)	     * except with -r (behave as with just -dr).             */            if (!recursive && (list || test)) {                                                DBGPrintfo(("make_ofname(out1)\r\n"));                                               return  OK;                                               }	    /* Avoid annoying messages with -r */	    if (verbose || (!recursive && !quiet)) {		WARN((stderr,"%s: %s: unknown suffix -- ignored\n",		      progname, ifname));	    }	    DBGPrintfo(("make_ofname(out2)\r\n"));    	return  WARNING;	}	/* Make a special case for .tgz and .taz: */	strlwr(suff);	if (strequ(suff, ".tgz") || strequ(suff, ".taz")) {	    strcpy(suff, ".tar");	} else {	    *suff = '\0'; /* strip the z suffix */	}        /* ofname might be changed later if infile contains an original name */    } else if (suff != NULL) {	/* Avoid annoying messages with -r (see treat_dir()) */	if (verbose || (!recursive && !quiet)) {	    fprintf(stderr, "%s: %s already has %s suffix -- unchanged\n",		    progname, ifname, suff);	}	if (exit_code == OK) exit_code = WARNING;		DBGPrintfo(("make_ofname(out3)\r\n"));	return  WARNING;    } else {        save_orig_name = 0;#ifdef NO_MULTIPLE_DOTS	suff = strrchr(ofname, '.');	if (suff == NULL) {            strcat(ofname, ".");#  ifdef MAX_EXT_CHARS	    if (strequ(z_suffix, "z")) {		strcat(ofname, "gz"); /* enough room */				DBGPrintfo(("make_ofname(out4)\r\n"));		return  OK;	    }        /* On the Atari and some versions of MSDOS, name_too_long()         * does not work correctly because of a bug in stat(). So we         * must truncate here.         */        } else if (strlen(suff)-1 + z_len > MAX_SUFFIX) {            suff[MAX_SUFFIX+1-z_len] = '\0';            save_orig_name = 1;#  endif        }#endif /* NO_MULTIPLE_DOTS */	strcat(ofname, z_suffix);    } /* decompress ? */    DBGPrintfo(("make_ofname(out5)\r\n"));    return  OK;  }}/* ======================================================================== * Check the magic number of the input file and update ofname if an * original name was given and to_stdout is not set. * Return the compression method, -1 for error, -2 for warning. * Set inptr to the offset of the next byte to be processed. * Updates time_stamp if there is one and --no-time is not used. * This function may be called repeatedly for an input file consisting * of several contiguous gzip'ed members. * IN assertions: there is at least one remaining compressed member. *   If the member is a zip file, it must be the only one. */local int get_method(in)    int in;        /* input file descriptor */{  DBGPrintfi(("get_method(In)\r\n"));  {    uch flags;     /* compression flags */    char magic[2]; /* magic header */    ulg stamp;     /* time stamp */    /* If --force and --stdout, zcat == cat, so do not complain about     * premature end of file: use try_byte instead of get_byte.     */    if (force && to_stdout) {		magic[0] = (char)try_byte();		magic[1] = (char)try_byte();		/* If try_byte returned EOF, magic[1] == 0xff */    } else {		magic[0] = (char)get_byte();		magic[1] = (char)get_byte();    }		    method = -1;                 /* unknown yet */    part_nb++;                   /* number of parts in gzip file */    header_bytes = 0;    last_member = RECORD_IO;    /* assume multiple members in gzip file except for record oriented I/O */	    if (memcmp(magic, GZIP_MAGIC, 2) == 0        || memcmp(magic, OLD_GZIP_MAGIC, 2) == 0) {	method = (int)get_byte();	if (method != DEFLATED) {	    fprintf(stderr,		    "%s: %s: unknown method %d -- get newer version of gzip\n",		    progname, ifname, method);	    exit_code = ERROR;	        	DBGPrintfo(("get_method(out1)\r\n"));    	return  -1;	}	work = unzip;	flags  = (uch)get_byte();	if ((flags & ENCRYPTED) != 0) {	    fprintf(stderr,		    "%s: %s is encrypted -- get newer version of gzip\n",		    progname, ifname);	    exit_code = ERROR;	        	DBGPrintfo(("get_method(out2)\r\n"));    	return  -1;	}	if ((flags & CONTINUATION) != 0) {	    fprintf(stderr,	   "%s: %s is a a multi-part gzip file -- get newer version of gzip\n",		    progname, ifname);	    exit_code = ERROR;	    if (force <= 1) return -1;	}	if ((flags & RESERVED) != 0) {	    fprintf(stderr,		    "%s: %s has flags 0x%x -- get newer version of gzip\n",		    progname, ifname, flags);	    exit_code = ERROR;	    if (force <= 1) return -1;	}		stamp  = (ulg)get_byte();	stamp |= ((ulg)get_byte()) << 8;	stamp |= ((ulg)get_byte()) << 16;	stamp |= ((ulg)get_byte()) << 24;	if (stamp != 0 && !no_time) time_stamp = stamp;	(void)get_byte();  /* Ignore extra flags for the moment */	(void)get_byte();  /* Ignore OS type for the moment */	if ((flags & CONTINUATION) != 0) {	    unsigned part = (unsigned)get_byte();	    part |= ((unsigned)get_byte())<<8;	    if (verbose) {		fprintf(stderr,"%s: %s: part number %u\n",			progname, ifname, part);	    }	}	if ((flags & EXTRA_FIELD) != 0) {	    unsigned len = (unsigned)get_byte();	    len |= ((unsigned)get_byte())<<8;	    if (verbose) {		fprintf(stderr,"%s: %s: extra field of %u bytes ignored\n",			progname, ifname, len);	    }	    while (len--) (void)get_byte();	}		/* Get original file name if it was truncated */	if ((flags & ORIG_NAME) != 0) {	    if (no_name || (to_stdout && !list) || part_nb > 1) {		/* Discard the old name */		char c; /* dummy used for NeXTstep 3.0 cc optimizer bug */		do {c=get_byte();} while (c != 0);	    } else {		/* Copy the base name. Keep a directory prefix intact. */                char *p = basename(ofname);                char *base = p;		for (;;) {		    *p = (char)get_char();		    if (*p++ == '\0') break;		    if (p >= ofname+sizeof(ofname)) {				error("corrupted input -- file name too large");				return -1;		    }		}                /* If necessary, adapt the name to local OS conventions: */                if (!list) {                   MAKE_LEGAL_NAME(base);		   if (base) list=0; /* avoid warning about unused variable */                }	    } /* no_name || to_stdout */	} /* ORIG_NAME */	/* Discard file comment if any */	if ((flags & COMMENT) != 0) {	    while (get_char() != 0) /* null */ ;	}	if (part_nb == 1) {	    header_bytes = inptr + 2*sizeof(long); /* include crc and size */	}    } else if (memcmp(magic, PKZIP_MAGIC, 2) == 0 && inptr == 2	    && memcmp((char*)inbuf, PKZIP_MAGIC, 4) == 0) {	/* To simplify the code, we support a zip file when alone only.         * We are thus guaranteed that the entire local header fits in inbuf.         */        inptr = 0;	work = unzip;	if (check_zipfile(in) != OK) {                              	 DBGPrintfo(("get_method(out3)\r\n"));                             	 return  -1;                              	}	/* check_zipfile may get ofname from the local header */	last_member = 1;	    } else if (memcmp(magic, PACK_MAGIC, 2) == 0) {	work = unpack;	method = PACKED;    } else if (memcmp(magic, LZW_MAGIC, 2) == 0) {	work = unlzw;	method = COMPRESSED;	last_member = 1;	    } else if (memcmp(magic, LZH_MAGIC, 2) == 0) {	work = unlzh;	method = LZHED;	last_member = 1;    } else if (force && to_stdout && !list) { /* pass input unchanged */	method = STORED;	work = copy;        inptr = 0;	last_member = 1;    }    if (method >= 0) {                       DBGPrintfo(("get_method(out4)\r\n"));                      return  method;                      }	    if (part_nb == 1) {	fprintf(stderr, "\n%s: %s: not in gzip format\n", progname, ifname);	exit_code = ERROR;	DBGPrintfo(("get_method(out5)\r\n"));	return  -1;    } else {	WARN((stderr, "\n%s: %s: decompression OK, trailing garbage ignored\n",	      progname, ifname));		DBGPrintfo(("get_method(out6)\r\n"));	return  -2;    }  }  }/* ======================================================================== * Display the characteristics of the compressed file. * If the given method is < 0, display the accumulated totals. * IN assertions: time_stamp, header_bytes and ifile_size are initialized. */local int do_list(ifd, method)    int ifd;     /* input file descriptor */    int method;  /* compression method */{  DBGPrintfi(("do_list(In)\r\n"));  {    ulg crc;  /* original crc */	static int first_time = 1;    static char* methods[MAX_METHODS] = {        "store",  /* 0 */        "compr",  /* 1 */        "pack ",  /* 2 */        "lzh  ",  /* 3 */        "", "", "", "", /* 4 to 7 reserved */        "defla"}; /* 8 */    char *date;    if (first_time && method >= 0) {		first_time = 0;		if (verbose)  {	//		printf("method  crc     date  time  ");		}		if (!quiet) {		//	printf("compressed  uncompr. ratio uncompressed_name\n");		}    } else if (method < 0) {		if (total_in <= 0 || total_out <= 0) 		{			DBGPrintfo(("do_list(out10)\r\n"));			return -1;		}		if (verbose) {		//	printf("                            %9lu %9lu ",  total_in, total_out);		} else if (!quiet) {		//	printf("%9ld %9ld ", total_in, total_out);		}		display_ratio(total_out-(total_in-header_bytes), total_out, stdout);		/* header_bytes is not meaningful but used to ensure the same		 * ratio if there is a single file.		 */		//printf(" (totals)\n");				DBGPrintfo(("do_list(out1)\r\n"));		return -1;    }    crc = (ulg)~0; /* unknown */    bytes_out = -1L;    bytes_in = ifile_size;#if RECORD_IO == 0    if (method == DEFLATED && !last_member) {        /* Get the crc and uncompressed size for gzip'ed (not zip'ed) files.         * If the lseek fails, we could use read() to get to the end, but         * --list is used to get quick results.         * Use "gunzip < foo.gz | wc -c" to get the uncompressed size if         * you are not concerned about speed.         */        bytes_in = (long)lseek(ifd, (off_t)(-8), SEEK_END);        if (bytes_in != -1L) {            uch buf[8];            bytes_in += 8L;            if (read(ifd, (char*)buf, sizeof(buf)) != sizeof(buf)) {                read_error();				DBGPrintfo(("do_list(out11)\r\n"));				return -1;            }            crc       = LG(buf);	    bytes_out = LG(buf+4);	}    }#endif /* RECORD_IO */    date = ctime((time_t*)&time_stamp) + 4; /* skip the day of the week */    date[12] = '\0';               /* suppress the 1/100sec and the year */    if (verbose) {//        printf("%5s %08lx %11s ", methods[method], crc, date);    }//    printf("%9ld %9ld ", bytes_in, bytes_out);    if (bytes_in  == -1L) {	total_in = -1L;	bytes_in = bytes_out = header_bytes = 0;    } else if (total_in >= 0) {	total_in  += bytes_in;    }    if (bytes_out == -1L) {	total_out = -1L;	bytes_in = bytes_out = header_bytes = 0;    } else if (total_out >= 0) {	total_out += bytes_out;    }    display_ratio(bytes_out-(bytes_in-header_bytes), bytes_out, stdout);  //  printf(" %s\n", ofname);  }  DBGPrintfo(("do_list(out)\r\n"));  return 0;}/* ======================================================================== * Return true if the two stat structures correspond to the same file. */local int same_file(stat1, stat2)    struct stat *stat1;    struct stat *stat2;{  DBGPrintfi(("same_file(In)\r\n"));  {    DBGPrintfo(("same_file(out1)\r\n"));    return  stat1->st_ino   == stat2->st_ino	&& stat1->st_dev   == stat2->st_dev#ifdef NO_ST_INO        /* Can't rely on st_ino and st_dev, use other fields: */	&& stat1->st_mode  == stat2->st_mode	&& stat1->st_uid   == stat2->st_uid	&& stat1->st_gid   == stat2->st_gid	&& stat1->st_size  == stat2->st_size	&& stat1->st_atime == stat2->st_atime	&& stat1->st_mtime == stat2->st_mtime	&& stat1->st_ctime == stat2->st_ctime#endif	    ;  }}/* ========================================================================

⌨️ 快捷键说明

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