Index: compress.h =================================================================== --- compress.h (revision 2) +++ compress.h (revision 3) @@ -65,6 +65,12 @@ extern int gz_close(void *, struct z_info *); extern int gz_flush(void *, int); +extern void *bz2_open(int, const char *, char *, int, u_int32_t, int); +extern int bz2_read(void *, char *, int); +extern int bz2_write(void *, const char *, int); +extern int bz2_close(void *, struct z_info *); +extern int bz2_flush(void *, int); + extern void *lzh_open(int, const char *, char *, int, u_int32_t, int); extern int lzh_read(void *, char *, int); extern int lzh_write(void *, const char *, int); Index: bz2open.c =================================================================== --- bz2open.c (revision 0) +++ bz2open.c (revision 3) @@ -0,0 +1,181 @@ +/* $NetBSD$ */ + +/* + * Copyright (c) 1997 Michael Shalayeff + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/* delivered from gzopen.c */ + +#include +#include +#include +#include +#include +#include + +#include "compress.h" + +#define BZ2_BUFSIZE (64*1024) + +typedef +struct _bz2_stream { + int z_fd; /* .bz2 file */ + bz_stream z_stream; /* libbz2 stream */ + int z_eof; /* set if end of input file */ + char z_buf[BZ2_BUFSIZE]; /* i/o buffer */ + char z_mode; /* 'w' or 'r' */ +} bz2_stream; + +void * +bz2_open(int fd, const char *mode, char *name, int bits, + u_int32_t mtime, int gotmagic) +{ + bz2_stream *s; + + if (fd < 0 || !mode) + return NULL; + + if ((mode[0] != 'r' && mode[0] != 'w') || mode[1] != '\0') { + errno = EINVAL; + return NULL; + } + if ((s = (bz2_stream *)calloc(1, sizeof(bz2_stream))) == NULL) + return NULL; + + s->z_mode = mode[0]; + + if (s->z_mode == 'w') { + errno = EOPNOTSUPP; + return (NULL); + } else { + if (BZ2_bzDecompressInit(&(s->z_stream), 0, 0) != BZ_OK) { + free (s); + return NULL; + } + s->z_stream.next_in = s->z_buf; + memcpy(s->z_buf, "\102\132", 2); + s->z_stream.avail_in = 2; + } + + errno = 0; + s->z_fd = fd; + + return s; +} + +int +bz2_close(void *cookie, struct z_info *info) +{ + bz2_stream *s = (bz2_stream*)cookie; + int error, error2; + + if (s == NULL) + return -1; + + if (s->z_mode == 'r') + error = BZ2_bzDecompressEnd(&s->z_stream); + + error2 = close(s->z_fd); + + if (info != NULL) { + memset(info, 0, sizeof(*info)); + info->total_in = + (((uint64_t)s->z_stream.total_in_hi32 << 32) + | s->z_stream.total_in_lo32); + info->total_out = + (((uint64_t)s->z_stream.total_out_hi32 << 32) + | s->z_stream.total_out_lo32); + } + + free(s); + + return error ? error : error2; +} + +int +bz2_flush(void *cookie, int flush) +{ + /* XXX */ + + return 0; +} + +int +bz2_read(void *cookie, char *buf, int len) +{ + bz2_stream *s = (bz2_stream*)cookie; + int error = BZ_OK; + + s->z_stream.next_out = buf; + s->z_stream.avail_out = len; + + while (error != BZ_STREAM_END && + !s->z_eof && s->z_stream.avail_out > 0) { + if (s->z_stream.avail_in == 0 && !s->z_eof) { + ssize_t n; + + errno = 0; + n = read(s->z_fd, s->z_buf, Z_BUFSIZE); + if (n == (ssize_t)-1) + return -1; + if (n == 0) + s->z_eof = 1; + s->z_stream.next_in = s->z_buf; + s->z_stream.avail_in = n; + } + + error = BZ2_bzDecompress(&(s->z_stream)); + switch (error) { + case BZ_STREAM_END: + s->z_eof = 1; + break; + case BZ_OK: + if (s->z_eof) { + errno = EIO; /* unexpected eof */ + return -1; + } + break; + case BZ_DATA_ERROR: + case BZ_DATA_ERROR_MAGIC: + case BZ_MEM_ERROR: + /* XXX should report more precise error */ + default: + errno = EINVAL; + return -1; + } + } + + len -= s->z_stream.avail_out; + + return (len); +} + +int +bz2_write(void *cookie, const char *buf, int len) +{ + + return 0; +} Index: main.c =================================================================== --- main.c (revision 2) +++ main.c (revision 3) @@ -74,16 +74,20 @@ } c_table[] = { #define M_DEFLATE (&c_table[0]) { "deflate", ".gz", "\037\213", gz_open, gz_read, gz_write, gz_close }, -#define M_COMPRESS (&c_table[1]) +#define M_BZIP2 (&c_table[1]) + { "bzip2", ".bz2", "\102\132", bz2_open, bz2_read, bz2_write, bz2_close }, +#ifndef SMALL +#endif /* SMALL */ +#define M_COMPRESS (&c_table[2]) #ifndef SMALL { "compress", ".Z", "\037\235", z_open, zread, zwrite, z_close }, #endif /* SMALL */ #if 0 -#define M_LZH (&c_table[2]) +#define M_LZH (&c_table[3]) { "lzh", ".lzh", "\037\240", lzh_open, lzh_read, lzh_write, lzh_close }, -#define M_ZIP (&c_table[3]) +#define M_ZIP (&c_table[4]) { "zip", ".zip", "PK", zip_open, zip_read, zip_write, zip_close }, -#define M_PACK (&c_table[4]) +#define M_PACK (&c_table[5]) { "pack", ".pak", "\037\036", pak_open, pak_read, pak_write, pak_close }, #endif { NULL } @@ -734,7 +738,8 @@ { int i; char *suf, *sep, *separators = ".-_"; - static char *suffixes[] = { "Z", "gz", "z", "tgz", "taz", NULL }; + static const char *suffixes[] = + { "Z", "gz", "z", "tgz", "taz", "bz2", NULL }; for (sep = separators; *sep != '\0'; sep++) { if ((suf = strrchr(infile, *sep)) == NULL) Index: Makefile =================================================================== --- Makefile (revision 2) +++ Makefile (revision 3) @@ -1,7 +1,7 @@ # $OpenBSD: Makefile,v 1.19 2003/09/05 04:46:35 tedu Exp $ PROG= compress -SRCS= main.c zopen.c gzopen.c nullopen.c +SRCS= main.c zopen.c gzopen.c bz2open.c nullopen.c MAN= compress.1 zmore.1 zdiff.1 zforce.1 gzexe.1 znew.1 LINKS= ${BINDIR}/compress ${BINDIR}/uncompress \ ${BINDIR}/compress ${BINDIR}/zcat \ @@ -17,8 +17,8 @@ compress.1 gzcat.1 \ zdiff.1 zcmp.1 -LDADD=-lz -DPADD=${LIBZ} +LDADD=-lz -lbz2 +DPADD=${LIBZ} ${LIBBZ2} afterinstall: install -c -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \