📄 unzip.c
字号:
/* read in table lengths */ while (k_dynamic < 5) { input_char = fgetc(in_file); if (input_char == EOF) return 1; b_dynamic |= ((unsigned long)input_char) << 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) { input_char = fgetc(in_file); if (input_char == EOF) return 1; b_dynamic |= ((unsigned long)input_char) << 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) { input_char = fgetc(in_file); if (input_char == EOF) return 1; b_dynamic |= ((unsigned long)input_char) << 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) { input_char = fgetc(in_file); if (input_char == EOF) return 1; b_dynamic |= ((unsigned long)input_char) << 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) { input_char = fgetc(in_file); if (input_char == EOF) return 1; b_dynamic |= ((unsigned long)input_char) << 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) { input_char = fgetc(in_file); if (input_char == EOF) return 1; b_dynamic |= ((unsigned long)input_char) << 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) { input_char = fgetc(in_file); if (input_char == EOF) return 1; b_dynamic |= ((unsigned long)input_char) << 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) { input_char = fgetc(in_file); if (input_char == EOF) return 1; b_dynamic |= ((unsigned long)input_char) << 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 */static int inflate(){ 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; /* 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(); /* return success */ return 0;}/* =========================================================================== * Unzip in to out. This routine works on both gzip and pkzip files. * * 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){ const int extra_field = 0x04; /* bit 2 set: extra field present */ const int orig_name = 0x08; /* bit 3 set: original file name present */ const int comment = 0x10; /* bit 4 set: file comment present */ unsigned char buf[8]; /* extended local header */ unsigned char flags; /* compression flags */ char magic[2]; /* magic header */ int method; typedef void (*sig_type) (int); int exit_code=0; /* program exit code */ int i; in_file = l_in_file; out_file = l_out_file; 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 /* Allocate all global buffers (for DYN_ALLOC option) */ window = xmalloc((size_t)(((2L*WSIZE)+1L)*sizeof(unsigned char))); outcnt = 0; bytes_out = 0L; magic[0] = fgetc(in_file); magic[1] = fgetc(in_file); /* Magic header for gzip files, 1F 8B = \037\213 */ if (memcmp(magic, "\037\213", 2) != 0) { error_msg("Invalid gzip magic"); return EXIT_FAILURE; } method = (int) fgetc(in_file); if (method != 8) { /* also catches EOF */ error_msg("unknown method %d -- get newer version of gzip", method); exit_code = 1; return -1; } flags = (unsigned char) fgetc(in_file); /* Ignore time stamp(4), extra flags(1), OS type(1) */ for (i = 0; i < 6; i++) fgetc(in_file); if ((flags & extra_field) != 0) { size_t extra; extra = fgetc(in_file); extra += fgetc(in_file) << 8; if (feof(in_file)) return 1; for (i = 0; i < extra; i++) fgetc(in_file); } /* Discard original name if any */ if ((flags & orig_name) != 0) { while (fgetc(in_file) != 0 && !feof(in_file)); /* null */ } /* Discard file comment if any */ if ((flags & comment) != 0) { while (fgetc(in_file) != 0 && !feof(in_file)); /* null */ } if (method < 0) { printf("it failed\n"); return(exit_code); /* error message already emitted */ } make_crc_table(); /* Decompress */ if (method == 8) { int res = inflate(); if (res == 3) { error_msg(memory_exhausted); exit_code = 1; } else if (res != 0) { error_msg("invalid compressed data--format violated"); exit_code = 1; } } else { error_msg("internal error, invalid method"); exit_code = 1; } /* Get the crc and original length * crc32 (see algorithm.doc) * uncompressed input size modulo 2^32 */ fread(buf, 1, 8, in_file); /* Validate decompression - crc */ if (!exit_code && (unsigned int)((buf[0] | (buf[1] << 8)) |((buf[2] | (buf[3] << 8)) << 16)) != (crc ^ 0xffffffffL)) { error_msg("invalid compressed data--crc error"); exit_code = 1; } /* Validate decompression - size */ if (!exit_code && ((buf[4] | (buf[5] << 8)) |((buf[6] | (buf[7] << 8)) << 16)) != (unsigned long) bytes_out) { error_msg("invalid compressed data--length error"); exit_code = 1; } free(window); free(crc_table); return exit_code;}/* * This needs access to global variables wondow 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 + -