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

📄 gzip.c

📁 一些关于HTTP协议处理的文档,还包括了gzip包(它是用来解压缩HTTP传送的压缩数据)
💻 C
📖 第 1 页 / 共 4 页
字号:
	    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;	    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;	    return ERROR;	}	if (!name_too_long(ofname, &ostat)) 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));	    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	shorten_name(ofname);    }}/* ======================================================================== * 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;{    errno = 0;#if (defined(S_IFLNK) || defined (S_ISLNK)) && !defined(NO_SYMLINK)    if (!to_stdout && !force) {	return lstat(name, sbuf);    }#endif    return stat(name, sbuf);}/* ======================================================================== * 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;{    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 = strlen(name);    if (nlen <= MAX_SUFFIX+2) {        strcpy(suffix, name);    } else {        strcpy(suffix, name+nlen-MAX_SUFFIX-2);    }    strlwr(suffix);    slen = strlen(suffix);    do {       int s = strlen(*suf);       if (slen > s && suffix[slen-s-1] != PATH_SEP           && strequ(suffix + slen - s, *suf)) {           return name+nlen-s;       }    } while (*++suf != NULL);    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;{    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) return OK;    if (!decompress || errno != ENOENT) {	perror(ifname);	exit_code = ERROR;	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;	return ERROR;    }#ifdef NO_MULTIPLE_DOTS    dot = strrchr(ifname, '.');    if (dot == NULL) {        strcat(ifname, ".");        dot = strrchr(ifname, '.');    }#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) 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;    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(){    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)) return OK;	    /* Avoid annoying messages with -r */	    if (verbose || (!recursive && !quiet)) {		WARN((stderr,"%s: %s: unknown suffix -- ignored\n",		      progname, ifname));	    }	    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;	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 */		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 ? */    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 */{    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;	    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;	    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");		    }		}                /* 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) 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) return method;    if (part_nb == 1) {	fprintf(stderr, "\n%s: %s: not in gzip format\n", progname, ifname);	exit_code = ERROR;	return -1;    } else {	WARN((stderr, "\n%s: %s: decompression OK, trailing garbage ignored\n",	      progname, ifname));	return -2;    }

⌨️ 快捷键说明

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