📄 unzip.c
字号:
8193, 12289, 16385, 24577};static const extra_bits_t cpdext[] = { /* Extra bits for distance codes */ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13};/* Tables for deflate from PKZIP's appnote.txt. */static const extra_bits_t border[] = { /* Order of the bit length code lengths */ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};/* * decompress an inflated block * e: last block flag * * GLOBAL VARIABLES: bb, kk, */static int inflate_block(int *e){ unsigned t; /* block type */ register unsigned long b; /* bit buffer */ register unsigned k; /* number of bits in bit buffer */ /* make local bit buffer */ b = bb; k = bk; /* read in last block bit */ while (k < 1) { b |= ((unsigned long)fgetc(in_file)) << k; k += 8; } *e = (int) b & 1; b >>= 1; k -= 1; /* read in block type */ while (k < 2) { b |= ((unsigned long)fgetc(in_file)) << k; k += 8; } t = (unsigned) b & 3; b >>= 2; k -= 2; /* restore the global bit buffer */ bb = b; bk = k; /* inflate that block type */ switch (t) { case 0: /* Inflate stored */ { unsigned long n; /* number of bytes in block */ unsigned long w; /* current window position */ register unsigned long b_stored; /* bit buffer */ register unsigned long k_stored; /* number of bits in bit buffer */ /* make local copies of globals */ b_stored = bb; /* initialize bit buffer */ k_stored = bk; w = outcnt; /* initialize window position */ /* go to byte boundary */ n = k_stored & 7; b_stored >>= n; k_stored -= n; /* get the length and its complement */ while (k_stored < 16) { b_stored |= ((unsigned long)fgetc(in_file)) << k_stored; k_stored += 8; } n = ((unsigned) b_stored & 0xffff); b_stored >>= 16; k_stored -= 16; while (k_stored < 16) { b_stored |= ((unsigned long)fgetc(in_file)) << k_stored; k_stored += 8; } if (n != (unsigned) ((~b_stored) & 0xffff)) { return 1; /* error in compressed data */ } b_stored >>= 16; k_stored -= 16; /* read and output the compressed data */ while (n--) { while (k_stored < 8) { b_stored |= ((unsigned long)fgetc(in_file)) << k_stored; k_stored += 8; } window[w++] = (unsigned char) b_stored; if (w == (unsigned long)WSIZE) { outcnt=(w), flush_window(); w = 0; } b_stored >>= 8; k_stored -= 8; } /* restore the globals from the locals */ outcnt = w; /* restore global window pointer */ bb = b_stored; /* restore global bit buffer */ bk = k_stored; return 0; } case 1: /* Inflate fixed * decompress an inflated type 1 (fixed Huffman codes) block. We should * either replace this with a custom decoder, or at least precompute the * Huffman tables. */ { int i; /* temporary variable */ huft_t *tl; /* literal/length code table */ huft_t *td; /* distance code table */ int bl; /* lookup bits for tl */ int bd; /* lookup bits for td */ unsigned int l[288]; /* length list for huft_build */ /* set up literal table */ for (i = 0; i < 144; i++) { l[i] = 8; } for (; i < 256; i++) { l[i] = 9; } for (; i < 280; i++) { l[i] = 7; } for (; i < 288; i++) { /* make a complete, but wrong code set */ l[i] = 8; } bl = 7; if ((i = huft_build(l, 288, 257, cplens, cplext, &tl, &bl)) != 0) { return i; } /* set up distance table */ for (i = 0; i < 30; i++) { /* make an incomplete code set */ l[i] = 5; } bd = 5; if ((i = huft_build(l, 30, 0, cpdist, cpdext, &td, &bd)) > 1) { huft_free(tl); return i; } /* decompress until an end-of-block code */ if (inflate_codes(tl, td, bl, bd)) return 1; /* free the decoding tables, return */ huft_free(tl); huft_free(td); return 0; } case 2: /* Inflate dynamic */ { const int dbits = 6; /* bits in base distance lookup table */ const int lbits = 9; /* bits in base literal/length lookup table */ int i; /* temporary variables */ unsigned j; unsigned l; /* last length */ unsigned m; /* mask for bit lengths table */ unsigned n; /* number of lengths to get */ huft_t *tl; /* literal/length code table */ huft_t *td; /* distance code table */ int bl; /* lookup bits for tl */ int bd; /* lookup bits for td */ unsigned nb; /* number of bit length codes */ unsigned nl; /* number of literal/length codes */ unsigned nd; /* number of distance codes */ unsigned ll[286 + 30]; /* literal/length and distance code lengths */ register unsigned long b_dynamic; /* bit buffer */ register unsigned k_dynamic; /* number of bits in bit buffer */ /* make local bit buffer */ b_dynamic = bb; k_dynamic = bk; /* read in table lengths */ while (k_dynamic < 5) { b_dynamic |= ((unsigned long)fgetc(in_file)) << k_dynamic; k_dynamic += 8; } nl = 257 + ((unsigned) b_dynamic & 0x1f); /* number of literal/length codes */ b_dynamic >>= 5; k_dynamic -= 5; while (k_dynamic < 5) { b_dynamic |= ((unsigned long)fgetc(in_file)) << k_dynamic; k_dynamic += 8; } nd = 1 + ((unsigned) b_dynamic & 0x1f); /* number of distance codes */ b_dynamic >>= 5; k_dynamic -= 5; while (k_dynamic < 4) { b_dynamic |= ((unsigned long)fgetc(in_file)) << k_dynamic; k_dynamic += 8; } nb = 4 + ((unsigned) b_dynamic & 0xf); /* number of bit length codes */ b_dynamic >>= 4; k_dynamic -= 4; if (nl > 286 || nd > 30) { return 1; /* bad lengths */ } /* read in bit-length-code lengths */ for (j = 0; j < nb; j++) { while (k_dynamic < 3) { b_dynamic |= ((unsigned long)fgetc(in_file)) << k_dynamic; k_dynamic += 8; } ll[border[j]] = (unsigned) b_dynamic & 7; b_dynamic >>= 3; k_dynamic -= 3; } for (; j < 19; j++) { ll[border[j]] = 0; } /* build decoding table for trees--single level, 7 bit lookup */ bl = 7; if ((i = huft_build(ll, 19, 19, NULL, NULL, &tl, &bl)) != 0) { if (i == 1) { huft_free(tl); } return i; /* incomplete code set */ } /* read in literal and distance code lengths */ n = nl + nd; m = mask_bits[bl]; i = l = 0; while ((unsigned) i < n) { while (k_dynamic < (unsigned) bl) { b_dynamic |= ((unsigned long)fgetc(in_file)) << k_dynamic; k_dynamic += 8; } j = (td = tl + ((unsigned) b_dynamic & m))->b; b_dynamic >>= j; k_dynamic -= j; j = td->v.n; if (j < 16) { /* length of code in bits (0..15) */ ll[i++] = l = j; /* save last length in l */ } else if (j == 16) { /* repeat last length 3 to 6 times */ while (k_dynamic < 2) { b_dynamic |= ((unsigned long)fgetc(in_file)) << k_dynamic; k_dynamic += 8; } j = 3 + ((unsigned) b_dynamic & 3); b_dynamic >>= 2; k_dynamic -= 2; if ((unsigned) i + j > n) { return 1; } while (j--) { ll[i++] = l; } } else if (j == 17) { /* 3 to 10 zero length codes */ while (k_dynamic < 3) { b_dynamic |= ((unsigned long)fgetc(in_file)) << k_dynamic; k_dynamic += 8; } j = 3 + ((unsigned) b_dynamic & 7); b_dynamic >>= 3; k_dynamic -= 3; if ((unsigned) i + j > n) { return 1; } while (j--) { ll[i++] = 0; } l = 0; } else { /* j == 18: 11 to 138 zero length codes */ while (k_dynamic < 7) { b_dynamic |= ((unsigned long)fgetc(in_file)) << k_dynamic; k_dynamic += 8; } j = 11 + ((unsigned) b_dynamic & 0x7f); b_dynamic >>= 7; k_dynamic -= 7; if ((unsigned) i + j > n) { return 1; } while (j--) { ll[i++] = 0; } l = 0; } } /* free decoding table for trees */ huft_free(tl); /* restore the global bit buffer */ bb = b_dynamic; bk = k_dynamic; /* build the decoding tables for literal/length and distance codes */ bl = lbits; if ((i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl)) != 0) { if (i == 1) { error_msg("Incomplete literal tree"); huft_free(tl); } return i; /* incomplete code set */ } bd = dbits; if ((i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd)) != 0) { if (i == 1) { error_msg("incomplete distance tree"); huft_free(td); } huft_free(tl); return i; /* incomplete code set */ } /* decompress until an end-of-block code */ if (inflate_codes(tl, td, bl, bd)) return 1; /* free the decoding tables, return */ huft_free(tl); huft_free(td); return 0; } default: /* bad block type */ return 2; }}/* * decompress an inflated entry * * GLOBAL VARIABLES: outcnt, bk, bb, hufts, inptr */extern int inflate(FILE *in, FILE *out){ int e; /* last block flag */ int r; /* result code */ unsigned h = 0; /* maximum struct huft's malloc'ed */ /* initialize window, bit buffer */ outcnt = 0; bk = 0; bb = 0; in_file = in; out_file = out; /* Allocate all global buffers (for DYN_ALLOC option) */ window = xmalloc((size_t)(((2L*WSIZE)+1L)*sizeof(unsigned char))); bytes_out = 0L; /* Create the crc table */ make_crc_table(); /* decompress until the last block */ do { hufts = 0; if ((r = inflate_block(&e)) != 0) { return r; } if (hufts > h) { h = hufts; } } while (!e); /* Undo too much lookahead. The next read will be byte aligned so we * can discard unused bits in the last meaningful byte. */ while (bk >= 8) { bk -= 8; ungetc((bb << bk), in_file); } /* flush out window */ flush_window(); free(window); free(crc_table); /* return success */ return 0;}/* =========================================================================== * Unzip in to out. This routine works on gzip files only. * * IN assertions: the buffer inbuf contains already the beginning of * the compressed data, from offsets inptr to insize-1 included. * The magic header has already been checked. The output buffer is cleared. * in, out: input and output file descriptors */extern int unzip(FILE *l_in_file, FILE *l_out_file){ unsigned char buf[8]; /* extended local header */ unsigned char flags; /* compression flags */ typedef void (*sig_type) (int); unsigned short i; unsigned char magic [2]; if (signal(SIGINT, SIG_IGN) != SIG_IGN) { (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 magic [0] = fgetc(l_in_file); magic [1] = fgetc(l_in_file); #ifdef CONFIG_FEATURE_UNCOMPRESS /* Magic header for compress files, 1F 9d = \037\235 */ if (( magic [0] == 0x1F ) && ( magic [1] == 0x9d)) { return uncompress ( l_in_file, l_out_file ); }#endif /* Magic header for gzip files, 1F 8B = \037\213 */ if (( magic [0] != 0x1F ) || ( magic [1] != 0x8b)) { error_msg("Invalid gzip magic"); return EXIT_FAILURE; } /* Check the compression method */ if (fgetc(l_in_file) != 8) { error_msg("Unknown compression method"); return(-1); } flags = (unsigned char) fgetc(l_in_file); /* Ignore time stamp(4), extra flags(1), OS type(1) */ for (i = 0; i < 6; i++) { fgetc(l_in_file); } if (flags & 0x04) { /* bit 2 set: extra field present */ const unsigned short extra = fgetc(l_in_file) + (fgetc(l_in_file) << 8); for (i = 0; i < extra; i++) { fgetc(l_in_file); } } /* Discard original name if any */ if (flags & 0x08) { /* bit 3 set: original file name present */ while (fgetc(l_in_file) != 0); /* null */ } /* Discard file comment if any */ if (flags & 0x10) { /* bit 4 set: file comment present */ while (fgetc(l_in_file) != 0); /* null */ } /* Decompress */ if (inflate(l_in_file, l_out_file) != 0) { error_msg("invalid compressed data--format violated"); } /* Get the crc and original length * crc32 (see algorithm.doc) * uncompressed input size modulo 2^32 */ fread(buf, 1, 8, l_in_file); /* Validate decompression - crc */ if ((unsigned int)((buf[0] | (buf[1] << 8)) |((buf[2] | (buf[3] << 8)) << 16)) != (crc ^ 0xffffffffL)) { error_msg("invalid compressed data--crc error"); } /* Validate decompression - size */ if (((buf[4] | (buf[5] << 8)) |((buf[6] | (buf[7] << 8)) << 16)) != (unsigned long) bytes_out) { error_msg("invalid compressed data--length error"); } return 0;}/* * This needs access to global variables window and crc_table, so its not in its own file. */extern void gz_close(int gunzip_pid){ if (kill(gunzip_pid, SIGTERM) == -1) { error_msg_and_die("*** Couldnt kill old gunzip process *** aborting"); } if (waitpid(gunzip_pid, NULL, 0) == -1) { printf("Couldnt wait ?"); } free(window); free(crc_table);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -