From 88ef261eaffd1b09f23eb73d8259336f694d9324 Mon Sep 17 00:00:00 2001 From: Stelian Pop Date: Thu, 16 Aug 2001 15:24:21 +0000 Subject: [PATCH] Added bzip2 compression to dump. --- CHANGES | 9 +- TODO | 14 ++- compat/include/protocols/dumprestore.h | 8 +- config.h.in | 3 + configure | 125 +++++++++++++++++++++---- configure.in | 13 +++ dump/Makefile.in | 4 +- dump/dump.8.in | 12 ++- dump/dump.h | 3 +- dump/main.c | 28 +++++- dump/tape.c | 61 +++++++++--- restore/Makefile.in | 4 +- restore/tape.c | 120 +++++++++++++++++------- 13 files changed, 320 insertions(+), 84 deletions(-) diff --git a/CHANGES b/CHANGES index ffbb11d..dccc4ed 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,4 @@ -$Id: CHANGES,v 1.133 2001/08/16 13:12:30 stelian Exp $ +$Id: CHANGES,v 1.134 2001/08/16 15:24:21 stelian Exp $ Changes between versions 0.4b23 and 0.4b24 (released ?????????????) =================================================================== @@ -20,6 +20,13 @@ Changes between versions 0.4b23 and 0.4b24 (released ?????????????) 5. Detect the use of incompatible options to dump and refuse them (like -a and -B options together). +6. Added bzip2 compression to dump/restore (use option -j level + to select it). Note that you will need a restore version + >= 0.4b24 in order to restore a bzip2 compressed dump. + The same warning as for the zlib compression applies: + the tape format of a bzip2 dump is not compatible with the + original BSD tape format. + Changes between versions 0.4b22 and 0.4b23 (released July 20, 2001) =================================================================== diff --git a/TODO b/TODO index dd4b7ff..a928652 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,4 @@ -$Id: TODO,v 1.22 2001/08/16 13:15:21 stelian Exp $ +$Id: TODO,v 1.23 2001/08/16 15:24:21 stelian Exp $ Need to verify: --------------- @@ -29,22 +29,20 @@ All others: 4. Implement a DEBUG option which doesn't fork on each tape, making it able to debug dump with gdb. -5. Extend the compression patch to use bzip2. +5. Make a bootable dump tape? I don't know if it is possible... -6. Make a bootable dump tape? I don't know if it is possible... - -7. From Kjetil Torgrim Homme : +6. From Kjetil Torgrim Homme : a archive_file Archive file. Archive a dump table-of-contents in the specified archive_file to be used by ufsrestore(1M) to determine whether a file is in the dump file that is being restored. -8. EA/ACL support in dump (requested by Michael Ju. Tokarev +7. EA/ACL support in dump (requested by Michael Ju. Tokarev . -9. Better readline completition in restore (escape spaces etc). +8. Better readline completition in restore (escape spaces etc). -10. Dump compiled with RedHat's 7.0 gcc seems to hang for some +9. Dump compiled with RedHat's 7.0 gcc seems to hang for some people. When compiled with kgcc all the problems disappear. Will the RedHat's 7.1 gcc resolve this ? diff --git a/compat/include/protocols/dumprestore.h b/compat/include/protocols/dumprestore.h index 885b9e0..49e14f1 100644 --- a/compat/include/protocols/dumprestore.h +++ b/compat/include/protocols/dumprestore.h @@ -5,7 +5,7 @@ * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 2000 * - * $Id: dumprestore.h,v 1.13 2001/05/12 11:36:12 stelian Exp $ + * $Id: dumprestore.h,v 1.14 2001/08/16 15:24:21 stelian Exp $ */ /* @@ -123,6 +123,12 @@ union u_spcl { #define DR_NEWINODEFMT 0x0002 /* new format inodes on tape */ #define DR_COMPRESSED 0x0080 /* dump tape is compressed */ +/* + * compression flags for the tapebuf header. + */ +#define COMPRESS_ZLIB 0 +#define COMPRESS_BZLIB 1 + /* used for compressed dump tapes */ struct tapebuf { unsigned int compressed:1; diff --git a/config.h.in b/config.h.in index c64ec5d..7bb86b6 100644 --- a/config.h.in +++ b/config.h.in @@ -65,6 +65,9 @@ /* Define this if you have zlib compression library */ #undef HAVE_ZLIB +/* Define this if you have bzlib compression library */ +#undef HAVE_BZLIB + /* Define this if you want Quick File Access support */ #undef USE_QFA diff --git a/configure b/configure index 3c4404c..3e461eb 100755 --- a/configure +++ b/configure @@ -2050,15 +2050,101 @@ else fi +ac_safe=`echo "bzlib.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for bzlib.h""... $ac_c" 1>&6 +echo "configure:2056: checking for bzlib.h" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2066: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + bzlib_h=yes +else + echo "$ac_t""no" 1>&6 +bzlib_h=no +fi + +echo $ac_n "checking for BZ2_bzBuffToBuffCompress in -lbz2""... $ac_c" 1>&6 +echo "configure:2089: checking for BZ2_bzBuffToBuffCompress in -lbz2" >&5 +ac_lib_var=`echo bz2'_'BZ2_bzBuffToBuffCompress | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lbz2 $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + bzlib_lib=yes +else + echo "$ac_t""no" 1>&6 +bzlib_lib=no +fi + +if test "$bzlib_h" = yes -a "$bzlib_lib" = yes; then + BZLIB="-lbz2" + cat >> confdefs.h <<\EOF +#define HAVE_BZLIB 1 +EOF + +else + BZLIB="" +fi + + for ac_func in err errx verr verrx vwarn vwarnx warn warnx realpath lchown do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:2057: checking for $ac_func" >&5 +echo "configure:2143: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2171: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -2106,12 +2192,12 @@ fi done echo $ac_n "checking for glob""... $ac_c" 1>&6 -echo "configure:2110: checking for glob" >&5 +echo "configure:2196: checking for glob" >&5 if eval "test \"`echo '$''{'ac_cv_func_glob'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2224: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_glob=yes" else @@ -2155,10 +2241,10 @@ fi echo $ac_n "checking for extended glob routines""... $ac_c" 1>&6 -echo "configure:2159: checking for extended glob routines" >&5 +echo "configure:2245: checking for extended glob routines" >&5 if test "$ac_cv_func_glob" = "yes"; then cat > conftest.$ac_ext < @@ -2189,12 +2275,12 @@ rm -f conftest* fi echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:2193: checking for ANSI C header files" >&5 +echo "configure:2279: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -2202,7 +2288,7 @@ else #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2206: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2292: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2219,7 +2305,7 @@ rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -2237,7 +2323,7 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -2258,7 +2344,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -2269,7 +2355,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF -if { (eval echo configure:2273: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2359: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else @@ -2293,12 +2379,12 @@ EOF fi echo $ac_n "checking for quad_t""... $ac_c" 1>&6 -echo "configure:2297: checking for quad_t" >&5 +echo "configure:2383: checking for quad_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_quad_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -2326,12 +2412,12 @@ EOF fi echo $ac_n "checking for u_quad_t""... $ac_c" 1>&6 -echo "configure:2330: checking for u_quad_t" >&5 +echo "configure:2416: checking for u_quad_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_u_quad_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -2539,6 +2625,7 @@ s%@MANMODE@%$MANMODE%g s%@DUMPDATESPATH@%$DUMPDATESPATH%g s%@CPP@%$CPP%g s%@ZLIB@%$ZLIB%g +s%@BZLIB@%$BZLIB%g s%@top_builddir@%$top_builddir%g CEOF diff --git a/configure.in b/configure.in index fc28967..e8bc852 100644 --- a/configure.in +++ b/configure.in @@ -368,6 +368,19 @@ else fi AC_SUBST(ZLIB) +dnl +dnl Check for bzlib headers and libraries +dnl +AC_CHECK_HEADER(bzlib.h, [bzlib_h=yes], [bzlib_h=no]) +AC_CHECK_LIB(bz2, BZ2_bzBuffToBuffCompress, [bzlib_lib=yes], [bzlib_lib=no]) +if test "$bzlib_h" = yes -a "$bzlib_lib" = yes; then + BZLIB="-lbz2" + AC_DEFINE(HAVE_BZLIB) +else + BZLIB="" +fi +AC_SUBST(BZLIB) + dnl dnl Check for library functions dnl diff --git a/dump/Makefile.in b/dump/Makefile.in index 19f2aca..52b7c15 100644 --- a/dump/Makefile.in +++ b/dump/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.7 2001/04/12 16:03:29 stelian Exp $ +# $Id: Makefile.in,v 1.8 2001/08/16 15:24:21 stelian Exp $ top_srcdir= @top_srcdir@ srcdir= @srcdir@ @@ -7,7 +7,7 @@ srcdir= @srcdir@ CFLAGS= @CCOPTS@ -pipe $(OPT) $(GINC) $(INC) $(DEFS) @DUMPDEBUG@ LDFLAGS:= $(LDFLAGS) @STATIC@ -LIBS= $(GLIBS) @ZLIB@ +LIBS= $(GLIBS) @ZLIB@ @BZLIB@ DEPLIBS= ../compat/lib/libcompat.a PROG= dump diff --git a/dump/dump.8.in b/dump/dump.8.in index 206356b..129001c 100644 --- a/dump/dump.8.in +++ b/dump/dump.8.in @@ -30,7 +30,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: dump.8.in,v 1.31 2001/08/16 09:37:59 stelian Exp $ +.\" $Id: dump.8.in,v 1.32 2001/08/16 15:24:21 stelian Exp $ .\" .Dd __DATE__ .Dt DUMP 8 @@ -49,6 +49,7 @@ .Op Fl f Ar file .Op Fl F Ar script .Op Fl h Ar level +.Op Fl j Ar compression level .Op Fl L Ar label .Op Fl Q Ar file .Op Fl s Ar feet @@ -220,6 +221,15 @@ For security reasons, .Nm reverts back to the real user ID and the real group ID before running the script. +.It Fl j Ar compression level +Compress every block to be written on the tape using bzlib library. This +option will work only when dumping to a file or pipe or, when dumping +to a tape drive, if the tape drive is capable of writing variable +length blocks. You will need at least the 0.4b24 version of restore in +order to extract compressed tapes. Tapes written using compression will +not be compatible with the BSD tape format. The (optional) parameter +specifies the compression level bzlib will use. The default compression +level is 2. .It Fl k Use Kerberos authentication to talk to remote tape servers. (Only available if this option was enabled when diff --git a/dump/dump.h b/dump/dump.h index 0e276b5..4f46fa4 100644 --- a/dump/dump.h +++ b/dump/dump.h @@ -5,7 +5,7 @@ * Stelian Pop , 1999-2000 * Stelian Pop - Alcôve , 2000 * - * $Id: dump.h,v 1.31 2001/08/16 09:37:59 stelian Exp $ + * $Id: dump.h,v 1.32 2001/08/16 15:24:21 stelian Exp $ */ /*- @@ -73,6 +73,7 @@ extern char *tapeprefix; /* prefix of the tape file */ extern char *dumpdates; /* name of the file containing dump date information*/ extern char lastlevel; /* dump level of previous dump */ extern char level; /* dump level of this dump */ +extern int bzipflag; /* compression is done using bzlib */ extern int uflag; /* update flag */ extern int Mflag; /* multi-volume flag */ extern int qflag; /* quit on errors flag */ diff --git a/dump/main.c b/dump/main.c index 8f33f95..5e9c111 100644 --- a/dump/main.c +++ b/dump/main.c @@ -41,7 +41,7 @@ #ifndef lint static const char rcsid[] = - "$Id: main.c,v 1.58 2001/08/16 13:12:30 stelian Exp $"; + "$Id: main.c,v 1.59 2001/08/16 15:24:21 stelian Exp $"; #endif /* not lint */ #include @@ -102,6 +102,7 @@ char *tapeprefix; /* prefix of the tape file */ char *dumpdates; /* name of the file containing dump date information*/ char lastlevel; /* dump level of previous dump */ char level; /* dump level of this dump */ +int bzipflag; /* compression is done using bzlib */ int uflag; /* update flag */ int Mflag; /* multi-volume flag */ int qflag; /* quit on errors flag */ @@ -234,7 +235,11 @@ main(int argc, char *argv[]) #endif /* USE_QFA */ while ((ch = getopt(argc, argv, - "0123456789aB:b:cd:e:E:f:F:h:L:" + "0123456789aB:b:cd:e:E:f:F:h:" +#ifdef HAVE_BZLIB + "j::" +#endif + "L:" #ifdef KERBEROS "k" #endif @@ -318,6 +323,15 @@ main(int argc, char *argv[]) honorlevel = numarg("honor level", 0L, 10L); break; +#ifdef HAVE_BZLIB + case 'j': + compressed = 2; + bzipflag = 1; + if (optarg) + compressed = numarg("compress level", 1L, 9L); + break; +#endif /* HAVE_BZLIB */ + #ifdef KERBEROS case 'k': dokerberos = 1; @@ -693,8 +707,8 @@ main(int argc, char *argv[]) msg("Label: %s\n", spcl.c_label); if (compressed) - msg("Compressing output at compression level %d\n", - compressed); + msg("Compressing output at compression level %d (%s)\n", + compressed, bzipflag ? "bzlib" : "zlib"); } #if defined(SIGINFO) @@ -961,10 +975,14 @@ usage(void) "MnqSu" "] [-B records] [-b blocksize] [-d density]\n" "\t%s [-e inode#,inode#,...] [-E file] [-f file] [-h level] " +#ifdef HAVE_BZLIB + "[-j zlevel] " +#endif + "\n\t%s " #ifdef USE_QFA "[-Q file] " #endif - "\n\t%s [-s feet] [-T date] " + "[-s feet] [-T date] " #ifdef HAVE_ZLIB "[-z zlevel] " #endif diff --git a/dump/tape.c b/dump/tape.c index 5e79fd2..8d8933f 100644 --- a/dump/tape.c +++ b/dump/tape.c @@ -41,7 +41,7 @@ #ifndef lint static const char rcsid[] = - "$Id: tape.c,v 1.53 2001/07/20 11:02:45 stelian Exp $"; + "$Id: tape.c,v 1.54 2001/08/16 15:24:21 stelian Exp $"; #endif /* not lint */ #include @@ -95,6 +95,10 @@ int write(), read(); #include #endif /* HAVE_ZLIB */ +#ifdef HAVE_BZLIB +#include +#endif /* HAVE_BZLIB */ + #include "dump.h" int writesize; /* size of malloc()ed buffer for tape */ @@ -1017,11 +1021,14 @@ doslave(int cmd, int slave_number, int first) int nextslave, size, eot_count, bufsize; volatile int wrote = 0; char *buffer; -#ifdef HAVE_ZLIB +#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) struct tapebuf *comp_buf = NULL; int compresult, do_compress = !first; unsigned long worklen; -#endif /* HAVE_ZLIB */ +#ifdef HAVE_BZLIB + unsigned int worklen2; +#endif +#endif /* HAVE_ZLIB || HAVE_BZLIB */ struct slave_results returns; #ifdef __linux__ errcode_t retval; @@ -1053,15 +1060,18 @@ doslave(int cmd, int slave_number, int first) quit("master/slave protocol botched - didn't get pid of next slave.\n"); } -#ifdef HAVE_ZLIB +#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) /* if we're doing a compressed dump, allocate the compress buffer */ if (compressed) { comp_buf = malloc(sizeof(struct tapebuf) + TP_BSIZE + writesize); if (comp_buf == NULL) quit("couldn't allocate a compress buffer.\n"); - comp_buf->flags = 0; + if (bzipflag) + comp_buf->flags = COMPRESS_BZLIB; + else + comp_buf->flags = COMPRESS_ZLIB; } -#endif /* HAVE_ZLIB */ +#endif /* HAVE_ZLIB || HAVE_BZLIB */ /* * Get list of blocks to dump, read the blocks into tape buffer @@ -1090,7 +1100,7 @@ doslave(int cmd, int slave_number, int first) bufsize = writesize; /* length to write */ returns.clen = returns.unclen = bufsize; -#ifdef HAVE_ZLIB +#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) /* * When writing a compressed dump, each block except * the first one on each tape is written @@ -1107,9 +1117,38 @@ doslave(int cmd, int slave_number, int first) if (compressed && do_compress) { comp_buf->length = bufsize; worklen = TP_BSIZE + writesize; - compresult = compress2(comp_buf->buf, &worklen, - (char *)slp->tblock[0], writesize, compressed); - if (compresult == Z_OK && worklen <= (writesize - 16)) { +#ifdef HAVE_ZLIB + if (!bzipflag) { + compresult = compress2(comp_buf->buf, + &worklen, + (char *)slp->tblock[0], + writesize, + compressed); + if (compresult == Z_OK) + compresult = 1; + else + compresult = 0; + } +#endif /* HAVE_ZLIB */ +#ifdef HAVE_BZLIB + if (bzipflag) { + worklen2 = worklen; + compresult = BZ2_bzBuffToBuffCompress( + comp_buf->buf, + &worklen2, + (char *)slp->tblock[0], + writesize, + compressed, + 0, 30); + worklen = worklen2; + if (compresult == BZ_OK) + compresult = 1; + else + compresult = 0; + } + +#endif /* HAVE_BZLIB */ + if (compresult && worklen <= (writesize - 16)) { /* write the compressed buffer */ comp_buf->length = worklen; comp_buf->compressed = 1; @@ -1128,7 +1167,7 @@ doslave(int cmd, int slave_number, int first) } /* compress the remaining blocks if we're compressing */ do_compress = compressed; -#endif /* HAVE_ZLIB */ +#endif /* HAVE_ZLIB || HAVE_BZLIB */ if (sigsetjmp(jmpbuf, 1) == 0) { ready = 1; diff --git a/restore/Makefile.in b/restore/Makefile.in index 527e910..3f2ed45 100644 --- a/restore/Makefile.in +++ b/restore/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.8 2001/04/12 16:03:30 stelian Exp $ +# $Id: Makefile.in,v 1.9 2001/08/16 15:24:21 stelian Exp $ top_srcdir= @top_srcdir@ srcdir= @srcdir@ @@ -7,7 +7,7 @@ srcdir= @srcdir@ CFLAGS= @CCOPTS@ -pipe $(OPT) $(DEFS) $(GINC) $(INC) @RESTOREDEBUG@ LDFLAGS:= $(LDFLAGS) @STATIC@ -LIBS= $(GLIBS) -le2p @READLINE@ @ZLIB@ +LIBS= $(GLIBS) -le2p @READLINE@ @ZLIB@ @BZLIB@ DEPLIBS= ../compat/lib/libcompat.a PROG= restore diff --git a/restore/tape.c b/restore/tape.c index 8864e2a..fb5c816 100644 --- a/restore/tape.c +++ b/restore/tape.c @@ -46,7 +46,7 @@ #ifndef lint static const char rcsid[] = - "$Id: tape.c,v 1.45 2001/07/20 09:01:46 stelian Exp $"; + "$Id: tape.c,v 1.46 2001/08/16 15:24:22 stelian Exp $"; #endif /* not lint */ #include @@ -84,6 +84,10 @@ static const char rcsid[] = #include #endif /* HAVE_ZLIB */ +#ifdef HAVE_BZLIB +#include +#endif /* HAVE_BZLIB */ + #include "restore.h" #include "extern.h" #include "pathnames.h" @@ -102,7 +106,7 @@ static int numtrec; static char *tapebuf; /* input buffer for read */ static int bufsize; /* buffer size without prefix */ static char *tbufptr = NULL; /* active tape buffer */ -#ifdef HAVE_ZLIB +#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) static char *comprbuf; /* uncompress work buf */ static size_t comprlen; /* size including prefix */ #endif @@ -148,7 +152,7 @@ static void xtrmapskip __P((char *, size_t)); static void xtrskip __P((char *, size_t)); static void setmagtapein __P((void)); -#ifdef HAVE_ZLIB +#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) static void newcomprbuf __P((int)); static void readtape_set __P((char *)); static void readtape_uncompr __P((char *)); @@ -235,7 +239,7 @@ newtapebuf(long size) tapebufsize = size; } -#ifdef HAVE_ZLIB +#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) static void newcomprbuf(int size) { @@ -249,7 +253,7 @@ newcomprbuf(int size) if (comprbuf == NULL) errx(1, "Cannot allocate space for decompress buffer"); } -#endif /* HAVE_ZLIB */ +#endif /* HAVE_ZLIB || HAVE_BZLIB */ /* * Verify that the tape drive can be accessed and @@ -298,7 +302,7 @@ setup(void) if (zflag) { fprintf(stderr, "Dump tape is compressed.\n"); -#ifdef HAVE_ZLIB +#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) newcomprbuf(ntrec); #else errx(1,"This restore version doesn't support decompression"); @@ -1295,7 +1299,7 @@ comparefile(char *name) /* NOTREACHED */ } -#ifdef HAVE_ZLIB +#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) static void (*readtape_func)(char *) = readtape_set; /* @@ -1328,7 +1332,7 @@ readtape_set(char *buf) readtape(buf); } -#endif /* HAVE_ZLIB */ +#endif /* HAVE_ZLIB || HAVE_BZLIB */ /* * This is the original readtape(), it's used for reading uncompressed input. @@ -1336,7 +1340,7 @@ readtape_set(char *buf) * Handle read errors, and end of media. */ static void -#ifdef HAVE_ZLIB +#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) readtape_uncompr(char *buf) #else readtape(char *buf) @@ -1460,7 +1464,7 @@ getmore: tpblksread++; } -#ifdef HAVE_ZLIB +#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) /* * Read a compressed format block from a file or pipe and uncompress it. @@ -1646,6 +1650,9 @@ decompress_tapebuf(struct tapebuf *tpbin, int readsize) /* zflag gets set in setup() from the dump header */ int cresult, blocklen; unsigned long worklen; +#ifdef HAVE_BZLIB + unsigned int worklen2; +#endif char *output = NULL,*reason = NULL, *lengtherr = NULL; /* build a length error message */ @@ -1657,41 +1664,88 @@ decompress_tapebuf(struct tapebuf *tpbin, int readsize) lengtherr = "long"; worklen = comprlen; - cresult = Z_OK; + cresult = 1; if (tpbin->compressed) { /* uncompress whatever we read, if it fails, complain later */ - cresult = uncompress(comprbuf, &worklen, tpbin->buf, blocklen); - output = comprbuf; + if (tpbin->flags == COMPRESS_ZLIB) { +#ifndef HAVE_ZLIB + errx(1,"This restore version doesn't support zlib decompression"); +#else + cresult = uncompress(comprbuf, &worklen, + tpbin->buf, blocklen); + output = comprbuf; + switch (cresult) { + case Z_OK: + break; + case Z_MEM_ERROR: + reason = "not enough memory"; + break; + case Z_BUF_ERROR: + reason = "buffer too small"; + break; + case Z_DATA_ERROR: + reason = "data error"; + break; + default: + reason = "unknown"; + } + if (cresult == Z_OK) + cresult = 1; + else + cresult = 0; +#endif /* HAVE_ZLIB */ + } + if (tpbin->flags == COMPRESS_BZLIB) { +#ifndef HAVE_BZLIB + errx(1,"This restore version doesn't support bzlib decompression"); +#else + worklen2 = worklen; + cresult = BZ2_bzBuffToBuffDecompress( + comprbuf, &worklen2, + tpbin->buf, blocklen, 0, 0); + worklen = worklen2; + output = comprbuf; + switch (cresult) { + case BZ_OK: + break; + case BZ_MEM_ERROR: + reason = "not enough memory"; + break; + case BZ_OUTBUFF_FULL: + reason = "buffer too small"; + break; + case BZ_DATA_ERROR: + case BZ_DATA_ERROR_MAGIC: + case BZ_UNEXPECTED_EOF: + reason = "data error"; + break; + default: + reason = "unknown"; + } + if (cresult == BZ_OK) + cresult = 1; + else + cresult = 0; +#endif /* HAVE_BZLIB */ + } } else { output = tpbin->buf; worklen = blocklen; } - switch (cresult) { - case Z_OK: - numtrec = worklen / TP_BSIZE; - if (worklen % TP_BSIZE != 0) - reason = "length mismatch"; - break; - case Z_MEM_ERROR: - reason = "not enough memory"; - break; - case Z_BUF_ERROR: - reason = "buffer too small"; - break; - case Z_DATA_ERROR: - reason = "data error"; - break; - default: - reason = "unknown"; - } /*switch */ + if (cresult) { + numtrec = worklen / TP_BSIZE; + if (worklen % TP_BSIZE != 0) + reason = "length mismatch"; + } if (reason) { if (lengtherr) fprintf(stderr, "%s compressed block: %d expected: %d\n", lengtherr, readsize, tpbin->length + PREFIXSIZE); fprintf(stderr, "decompression error, block %ld: %s\n", tpblksread+1, reason); - if (cresult != Z_OK) output = NULL; + if (!cresult) + output = NULL; } return output; } @@ -1719,7 +1773,7 @@ msg_read_error(char *m) break; } } -#endif /* HAVE_ZLIB */ +#endif /* HAVE_ZLIB || HAVE_BZLIB */ /* * Read the first block and get the blocksize from it. Test -- 2.39.2