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

📄 decompress_unzip.c

📁 busybox-1.5.1.tar.gz linux内核编译用到的工具
💻 C
📖 第 1 页 / 共 3 页
字号:
		}		for (; i < 280; i++) {			l[i] = 7;		}		for (; i < 288; i++) {	/* make a complete, but wrong code set */			l[i] = 8;		}		bl = 7;		i = huft_build(l, 288, 257, cplens, cplext, &tl, &bl);		if (i != 0) {			return i;		}		/* set up distance table */		for (i = 0; i < 30; i++) {	/* make an incomplete code set */			l[i] = 5;		}		bd = 5;		i = huft_build(l, 30, 0, cpdist, cpdext, &td, &bd);		if (i > 1) {			huft_free(tl);			return i;		}		/* decompress until an end-of-block code */		inflate_codes_setup(PASS_STATE tl, td, bl, bd); // Setup inflate_codes		/* huft_free code moved into inflate_codes */		return -2;	}	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 */		huft_t *tl;		/* literal/length code table */		huft_t *td;		/* distance code table */		unsigned i;			/* temporary variables */		unsigned j;		unsigned l;		/* last length */		unsigned m;		/* mask for bit lengths table */		unsigned n;		/* number of lengths to get */		unsigned bl;			/* lookup bits for tl */		unsigned 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 */		unsigned b_dynamic;	/* bit buffer */		unsigned k_dynamic;	/* number of bits in bit buffer */		/* make local bit buffer */		b_dynamic = gunzip_bb;		k_dynamic = gunzip_bk;		/* read in table lengths */		b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 5);		nl = 257 + ((unsigned) b_dynamic & 0x1f);	/* number of literal/length codes */		b_dynamic >>= 5;		k_dynamic -= 5;		b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 5);		nd = 1 + ((unsigned) b_dynamic & 0x1f);	/* number of distance codes */		b_dynamic >>= 5;		k_dynamic -= 5;		b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 4);		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++) {			b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 3);			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;		i = huft_build(ll, 19, 19, NULL, NULL, &tl, &bl);		if (i != 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) {			b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, (unsigned)bl);			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 */				b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 2);				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 */				b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 3);				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 */				b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 7);				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 */		gunzip_bb = b_dynamic;		gunzip_bk = k_dynamic;		/* build the decoding tables for literal/length and distance codes */		bl = lbits;		i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl);		if (i != 0) {			if (i == 1) {//shouldn't we propagate error?				bb_error_msg_and_die("incomplete literal tree");				/* huft_free(tl); */			}			return i;	/* incomplete code set */		}		bd = dbits;		i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd);		if (i != 0) {			if (i == 1) {//shouldn't we propagate error?				bb_error_msg_and_die("incomplete distance tree");				/* huft_free(td); */			}			huft_free(tl);			return i;	/* incomplete code set */		}		/* decompress until an end-of-block code */		inflate_codes_setup(PASS_STATE tl, td, bl, bd); // Setup inflate_codes		/* huft_free code moved into inflate_codes */		return -2;	}	default:		/* bad block type *///shouldn't we propagate error?		bb_error_msg_and_die("bad block type %d", t);	}}/* Two callsites, both in inflate_get_next_window */static void calculate_gunzip_crc(STATE_PARAM_ONLY){	int n;	for (n = 0; n < gunzip_outbuf_count; n++) {		gunzip_crc = gunzip_crc_table[((int) gunzip_crc ^ (gunzip_window[n])) & 0xff] ^ (gunzip_crc >> 8);	}	gunzip_bytes_out += gunzip_outbuf_count;}/* One callsite in inflate_unzip_internal */static int inflate_get_next_window(STATE_PARAM_ONLY){	gunzip_outbuf_count = 0;	while (1) {		int ret;		if (need_another_block) {			if (end_reached) {				calculate_gunzip_crc(PASS_STATE_ONLY);				end_reached = 0;				need_another_block = 1;				return 0; /* Last block */			}			method = inflate_block(PASS_STATE &end_reached);			need_another_block = 0;		}		switch (method) {		case -1:			ret = inflate_stored(PASS_STATE_ONLY);			break;		case -2:			ret = inflate_codes(PASS_STATE_ONLY);			break;		default://shouldn't we propagate error?			bb_error_msg_and_die("inflate error %d", method);		}		if (ret == 1) {			calculate_gunzip_crc(PASS_STATE_ONLY);			return 1; // More data left		}		need_another_block = 1; // End of that block	}	/* Doesnt get here */}/* Called from inflate_gunzip() and inflate_unzip() *//* NB: bytebuffer is allocated here but freeing it is left to the caller! */static USE_DESKTOP(long long) intinflate_unzip_internal(STATE_PARAM int in, int out){	USE_DESKTOP(long long) int n = 0;	ssize_t nwrote;	/* Allocate all global buffers (for DYN_ALLOC option) */	gunzip_window = xmalloc(GUNZIP_WSIZE);	gunzip_outbuf_count = 0;	gunzip_bytes_out = 0;	gunzip_src_fd = in;	/* initialize gunzip_window, bit buffer */	gunzip_bk = 0;	gunzip_bb = 0;	/* Create the crc table */	gunzip_crc_table = crc32_filltable(0);	gunzip_crc = ~0;	/* Allocate space for buffer */	bytebuffer = xmalloc(bytebuffer_max);	while (1) {		int r = inflate_get_next_window(PASS_STATE_ONLY);		nwrote = full_write(out, gunzip_window, gunzip_outbuf_count);		if (nwrote != gunzip_outbuf_count) {			bb_perror_msg("write");			n = -1;			goto ret;		}		USE_DESKTOP(n += nwrote;)		if (r == 0) break;	}	/* Store unused bytes in a global buffer so calling applets can access it */	if (gunzip_bk >= 8) {		/* Undo too much lookahead. The next read will be byte aligned		 * so we can discard unused bits in the last meaningful byte. */		bytebuffer_offset--;		bytebuffer[bytebuffer_offset] = gunzip_bb & 0xff;		gunzip_bb >>= 8;		gunzip_bk -= 8;	} ret:	/* Cleanup */	free(gunzip_window);	free(gunzip_crc_table);	return n;}USE_DESKTOP(long long) intinflate_unzip(inflate_unzip_result *res, unsigned bufsize, int in, int out){	USE_DESKTOP(long long) int n;	DECLARE_STATE;	ALLOC_STATE;	bytebuffer_max = bufsize + 8;	bytebuffer_offset = 4;	n = inflate_unzip_internal(PASS_STATE in, out);	res->crc = gunzip_crc;	res->bytes_out = gunzip_bytes_out;	free(bytebuffer);	DEALLOC_STATE;	return n;}USE_DESKTOP(long long) intinflate_gunzip(int in, int out){	uint32_t stored_crc = 0;	unsigned count;	USE_DESKTOP(long long) int n;	DECLARE_STATE;	ALLOC_STATE;	bytebuffer_max = 0x8000;	n = inflate_unzip_internal(PASS_STATE in, out);	if (n < 0) goto ret;	/* top up the input buffer with the rest of the trailer */	count = bytebuffer_size - bytebuffer_offset;	if (count < 8) {		xread(in, &bytebuffer[bytebuffer_size], 8 - count);//shouldn't we propagate error?		bytebuffer_size += 8 - count;	}	for (count = 0; count != 4; count++) {		stored_crc |= (bytebuffer[bytebuffer_offset] << (count * 8));		bytebuffer_offset++;	}	/* Validate decompression - crc */	if (stored_crc != (~gunzip_crc)) {		bb_error_msg("crc error");		n = -1;		goto ret;	}	/* Validate decompression - size */	if (gunzip_bytes_out !=		(bytebuffer[bytebuffer_offset] | (bytebuffer[bytebuffer_offset+1] << 8) |		(bytebuffer[bytebuffer_offset+2] << 16) | (bytebuffer[bytebuffer_offset+3] << 24))	) {		bb_error_msg("incorrect length");		n = -1;	} ret:	free(bytebuffer);	DEALLOC_STATE;	return n;}

⌨️ 快捷键说明

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