unbzip2.c revision 1.9
137960Ssos/*	$NetBSD: unbzip2.c,v 1.9 2005/11/22 09:05:30 mrg Exp $	*/
237960Ssos
337960Ssos/* This file is #included by gzip.c */
437960Ssos
537960Ssosstatic off_t
637960Ssosunbzip2(int in, int out, char *pre, size_t prelen, off_t *bytes_in)
743334Syokota{
837960Ssos	int		ret, end_of_file;
937960Ssos	off_t		bytes_out = 0;
1037960Ssos	bz_stream	bzs;
1137960Ssos	static char	*inbuf, *outbuf;
1237960Ssos
1337960Ssos	if (inbuf == NULL)
1437960Ssos		inbuf = malloc(BUFLEN);
1537960Ssos	if (outbuf == NULL)
1637960Ssos		outbuf = malloc(BUFLEN);
1737960Ssos	if (inbuf == NULL || outbuf == NULL)
1837960Ssos	        maybe_err("malloc");
1937960Ssos
2037960Ssos	bzs.bzalloc = NULL;
2137960Ssos	bzs.bzfree = NULL;
2237960Ssos	bzs.opaque = NULL;
2337960Ssos
2437960Ssos	end_of_file = 0;
2537960Ssos	ret = BZ2_bzDecompressInit(&bzs, 0, 0);
2637960Ssos	if (ret != BZ_OK)
2737960Ssos	        maybe_errx("bzip2 init");
2837960Ssos
2937960Ssos	/* Prepend. */
3037960Ssos	bzs.avail_in = prelen;
3137960Ssos	bzs.next_in = pre;
3237960Ssos
3337960Ssos	if (bytes_in)
3437960Ssos		*bytes_in = prelen;
3537960Ssos
3637960Ssos	while (ret >= BZ_OK && ret != BZ_STREAM_END) {
3737960Ssos	        if (bzs.avail_in == 0 && !end_of_file) {
3837960Ssos			ssize_t	n;
3937960Ssos
4037960Ssos	                n = read(in, inbuf, BUFLEN);
4137960Ssos	                if (n < 0)
4237960Ssos	                        maybe_err("read");
4337960Ssos	                if (n == 0)
4437960Ssos	                        end_of_file = 1;
4537960Ssos	                bzs.next_in = inbuf;
4638140Syokota	                bzs.avail_in = n;
4737960Ssos			if (bytes_in)
4837960Ssos				*bytes_in += n;
4937960Ssos	        }
5037960Ssos
5137960Ssos	        bzs.next_out = outbuf;
5237960Ssos	        bzs.avail_out = BUFLEN;
5337960Ssos	        ret = BZ2_bzDecompress(&bzs);
5437960Ssos
5537960Ssos	        switch (ret) {
5637960Ssos	        case BZ_STREAM_END:
5737960Ssos	        case BZ_OK:
5837960Ssos	                if (ret == BZ_OK && end_of_file)
5937960Ssos	                        maybe_err("read");
6037960Ssos	                if (!tflag) {
6143334Syokota				ssize_t	n;
6237960Ssos
6337960Ssos	                        n = write(out, outbuf, BUFLEN - bzs.avail_out);
6437960Ssos	                        if (n < 0)
6537960Ssos	                                maybe_err("write");
6637960Ssos	                	bytes_out += n;
6737960Ssos	                }
6837960Ssos	                break;
6937960Ssos
7037960Ssos	        case BZ_DATA_ERROR:
7137960Ssos	                maybe_warnx("bzip2 data integrity error");
7237960Ssos			break;
7337960Ssos
7437960Ssos	        case BZ_DATA_ERROR_MAGIC:
7537960Ssos	                maybe_warnx("bzip2 magic number error");
7637960Ssos			break;
7737960Ssos
7837960Ssos	        case BZ_MEM_ERROR:
7937960Ssos	                maybe_warnx("bzip2 out of memory");
8037960Ssos			break;
8137960Ssos
8237960Ssos	        }
8337960Ssos	}
8437960Ssos
8537960Ssos	if (ret != BZ_STREAM_END || BZ2_bzDecompressEnd(&bzs) != BZ_OK)
8637960Ssos	        return (-1);
8737960Ssos
8837960Ssos	return (bytes_out);
8937960Ssos}
9043334Syokota