diff --git a/.gitignore b/.gitignore index e69de29..77b71c1 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1,9 @@ +*.o +*.sho +*.a +*.so +*.dylib +bzip2 +bzip2recover +*.rb2 +*.tst diff --git a/CHANGES b/CHANGES index 6e4f65e..34f1d25 100644 --- a/CHANGES +++ b/CHANGES @@ -312,7 +312,6 @@ Fixes some minor bugs since the last version, 1.0.3. * Fix minor doc/comment bugs. - 1.0.5 (10 Dec 07) ~~~~~~~~~~~~~~~~~ Security fix only. Fixes CERT-FI 20469 as it applies to bzip2. diff --git a/Makefile b/Makefile index eb09753..82453b1 100644 --- a/Makefile +++ b/Makefile @@ -26,6 +26,21 @@ CFLAGS=-Wall -Winline -O2 -g $(BIGFILES) # Where you want it installed when you do 'make install' PREFIX=/usr/local +uname := $(shell uname) + +ifeq ($(uname), Linux) + CXXFLAGS = + SHLIBEXT := .so + SHLIBFLAGS := -shared + LD_PATH := LD_LIBRARY_PATH +endif +ifeq ($(uname), Darwin) + CXXFLAGS = + SHLIBEXT := .dylib + SHLIBFLAGS = -undefined dynamic_lookup -dynamiclib -install_name $(PREFIX)/lib/$(@) + LD_PATH := DYLD_LIBRARY_PATH +endif + OBJS= blocksort.o \ huffman.o \ @@ -35,9 +50,9 @@ OBJS= blocksort.o \ decompress.o \ bzlib.o -all: libbz2.a bzip2 bzip2recover test +all: libbz2.a bzip2 bzip2recover # test -bzip2: libbz2.a bzip2.o +bzip2: libbz2$(SHLIBEXT) bzip2.o $(CC) $(CFLAGS) $(LDFLAGS) -o bzip2 bzip2.o -L. -lbz2 bzip2recover: bzip2recover.o @@ -46,20 +61,36 @@ bzip2recover: bzip2recover.o libbz2.a: $(OBJS) rm -f libbz2.a $(AR) cq libbz2.a $(OBJS) - @if ( test -f $(RANLIB) -o -f /usr/bin/ranlib -o \ - -f /bin/ranlib -o -f /usr/ccs/bin/ranlib ) ; then \ + @if ( test -f $(RANLIB) || test -f /usr/bin/ranlib || \ + test -f /bin/ranlib || test -f /usr/ccs/bin/ranlib ) ; then \ echo $(RANLIB) libbz2.a ; \ $(RANLIB) libbz2.a ; \ fi +libbz2$(SHLIBEXT): $(OBJS:%.o=%.sho) + $(CC) -o libbz2$(SHLIBEXT) -shared \ + $(SHLIBFLAGS) $^ -lc + +%.sho: %.c + $(CC) $(CFLAGS) -D_REENTRANT -fPIC -o $@ -c $< + +%.o: %.c + $(CC) $(CFLAGS) -D_REENTRANT -o $@ -c $< + check: test test: bzip2 @cat words1 + $(LD_PATH)=.:$$$(LD_PATH) \ ./bzip2 -1 < sample1.ref > sample1.rb2 + $(LD_PATH)=.:$$$(LD_PATH) \ ./bzip2 -2 < sample2.ref > sample2.rb2 + $(LD_PATH)=.:$$$(LD_PATH) \ ./bzip2 -3 < sample3.ref > sample3.rb2 + $(LD_PATH)=.:$$$(LD_PATH) \ ./bzip2 -d < sample1.bz2 > sample1.tst + $(LD_PATH)=.:$$$(LD_PATH) \ ./bzip2 -d < sample2.bz2 > sample2.tst + $(LD_PATH)=.:$$$(LD_PATH) \ ./bzip2 -ds < sample3.bz2 > sample3.tst cmp sample1.bz2 sample1.rb2 cmp sample2.bz2 sample2.rb2 @@ -69,15 +100,15 @@ test: bzip2 cmp sample3.tst sample3.ref @cat words3 -install: bzip2 bzip2recover +install: bzip2 bzip2recover libbz2.a if ( test ! -d $(PREFIX)/bin ) ; then mkdir -p $(PREFIX)/bin ; fi if ( test ! -d $(PREFIX)/lib ) ; then mkdir -p $(PREFIX)/lib ; fi if ( test ! -d $(PREFIX)/man ) ; then mkdir -p $(PREFIX)/man ; fi if ( test ! -d $(PREFIX)/man/man1 ) ; then mkdir -p $(PREFIX)/man/man1 ; fi if ( test ! -d $(PREFIX)/include ) ; then mkdir -p $(PREFIX)/include ; fi cp -f bzip2 $(PREFIX)/bin/bzip2 - cp -f bzip2 $(PREFIX)/bin/bunzip2 - cp -f bzip2 $(PREFIX)/bin/bzcat + ln -f $(PREFIX)/bin/bzip2 $(PREFIX)/bin/bunzip2 + ln -f $(PREFIX)/bin/bzip2 $(PREFIX)/bin/bzcat cp -f bzip2recover $(PREFIX)/bin/bzip2recover chmod a+x $(PREFIX)/bin/bzip2 chmod a+x $(PREFIX)/bin/bunzip2 @@ -87,8 +118,10 @@ install: bzip2 bzip2recover chmod a+r $(PREFIX)/man/man1/bzip2.1 cp -f bzlib.h $(PREFIX)/include chmod a+r $(PREFIX)/include/bzlib.h - cp -f libbz2.a $(PREFIX)/lib + cp -fa libbz2.a libbz2$(SHLIBEXT)* $(PREFIX)/lib chmod a+r $(PREFIX)/lib/libbz2.a + cp -f bzexe $(PREFIX)/bin/bzexe + chmod a+x $(PREFIX)/bin/bzexe cp -f bzgrep $(PREFIX)/bin/bzgrep ln -s -f $(PREFIX)/bin/bzgrep $(PREFIX)/bin/bzegrep ln -s -f $(PREFIX)/bin/bzgrep $(PREFIX)/bin/bzfgrep @@ -99,7 +132,8 @@ install: bzip2 bzip2recover cp -f bzdiff $(PREFIX)/bin/bzdiff ln -s -f $(PREFIX)/bin/bzdiff $(PREFIX)/bin/bzcmp chmod a+x $(PREFIX)/bin/bzdiff - cp -f bzgrep.1 bzmore.1 bzdiff.1 $(PREFIX)/man/man1 + cp -f bzexe.1 bzgrep.1 bzmore.1 bzdiff.1 $(PREFIX)/man/man1 + chmod a+r $(PREFIX)/man/man1/bzexe.1 chmod a+r $(PREFIX)/man/man1/bzgrep.1 chmod a+r $(PREFIX)/man/man1/bzmore.1 chmod a+r $(PREFIX)/man/man1/bzdiff.1 @@ -109,33 +143,13 @@ install: bzip2 bzip2recover echo ".so man1/bzdiff.1" > $(PREFIX)/man/man1/bzcmp.1 clean: - rm -f *.o libbz2.a bzip2 bzip2recover \ + rm -f *.o *.sho libbz2.a libbz2$(SHLIBEXT)* bzip2 bzip2recover \ sample1.rb2 sample2.rb2 sample3.rb2 \ sample1.tst sample2.tst sample3.tst -blocksort.o: blocksort.c - @cat words0 - $(CC) $(CFLAGS) -c blocksort.c -huffman.o: huffman.c - $(CC) $(CFLAGS) -c huffman.c -crctable.o: crctable.c - $(CC) $(CFLAGS) -c crctable.c -randtable.o: randtable.c - $(CC) $(CFLAGS) -c randtable.c -compress.o: compress.c - $(CC) $(CFLAGS) -c compress.c -decompress.o: decompress.c - $(CC) $(CFLAGS) -c decompress.c -bzlib.o: bzlib.c - $(CC) $(CFLAGS) -c bzlib.c -bzip2.o: bzip2.c - $(CC) $(CFLAGS) -c bzip2.c -bzip2recover.o: bzip2recover.c - $(CC) $(CFLAGS) -c bzip2recover.c - distclean: clean - rm -f manual.ps manual.html manual.pdf + #rm -f manual.ps manual.html manual.pdf DISTNAME=bzip2-1.0.5 dist: check manual @@ -187,6 +201,8 @@ dist: check manual $(DISTNAME)/bzdiff.1 \ $(DISTNAME)/bzmore \ $(DISTNAME)/bzmore.1 \ + $(DISTNAME)/bzexe \ + $(DISTNAME)/bzexe.1 \ $(DISTNAME)/bzgrep \ $(DISTNAME)/bzgrep.1 \ $(DISTNAME)/Makefile-libbz2_so \ diff --git a/bzdiff b/bzdiff index 6fc38f9..bd96c27 100644 --- a/bzdiff +++ b/bzdiff @@ -37,10 +37,6 @@ if test -z "$FILES"; then echo "Usage: $prog [${comp}_options] file [file]" exit 1 fi -tmp=`mktemp ${TMPDIR:-/tmp}/bzdiff.XXXXXXXXXX` || { - echo 'cannot create a temporary file' >&2 - exit 1 -} set $FILES if test $# -eq 1; then FILE=`echo "$1" | sed 's/.bz2$//'` @@ -53,10 +49,14 @@ elif test $# -eq 2; then case "$2" in *.bz2) F=`echo "$2" | sed 's|.*/||;s|.bz2$||'` - bzip2 -cdfq "$2" > $tmp - bzip2 -cdfq "$1" | $comp $OPTIONS - $tmp + tmp=`mktemp "${TMPDIR:-/tmp}"/bzdiff.XXXXXXXXXX` || { + echo 'cannot create a temporary file' >&2 + exit 1 + } + bzip2 -cdfq "$2" > "$tmp" + bzip2 -cdfq "$1" | $comp $OPTIONS - "$tmp" STAT="$?" - /bin/rm -f $tmp;; + /bin/rm -f "$tmp";; *) bzip2 -cdfq "$1" | $comp $OPTIONS - "$2" STAT="$?";; @@ -69,8 +69,8 @@ elif test $# -eq 2; then STAT="$?";; esac;; esac - exit "$STAT" else echo "Usage: $prog [${comp}_options] file [file]" exit 1 fi +exit "$STAT" diff --git a/bzexe b/bzexe new file mode 100644 index 0000000..cee68ee --- /dev/null +++ b/bzexe @@ -0,0 +1,182 @@ +#!/bin/sh +# gzexe: compressor for Unix executables. +# Use this only for binaries that you do not use frequently. +# +# The compressed version is a shell script which decompresses itself after +# skipping $skip lines of shell commands. We try invoking the compressed +# executable with the original name (for programs looking at their name). +# We also try to retain the original file permissions on the compressed file. +# For safety reasons, gzexe will not create setuid or setgid shell scripts. + +# WARNING: the first line of this file must be either : or #!/bin/sh +# The : is required for some old versions of csh. +# On Ultrix, /bin/sh is too buggy, change the first line to: #!/bin/sh5 + + +# Copyright (C) 1998, 2002 Free Software Foundation +# Copyright (C) 1993 Jean-loup Gailly + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + + +PATH="/usr/bin:$PATH" +x=`basename $0` +if test $# = 0; then + echo compress executables. original file foo is renamed to foo~ + echo usage: ${x} [-d] files... + echo " -d decompress the executables" + exit 1 +fi + +set -C +tmp=gz$$ +trap "rm -f $tmp; exit 1" HUP INT QUIT TRAP USR1 PIPE TERM +: > $tmp || exit 1 + +decomp=0 +res=0 +test "$x" = "ungzexe" && decomp=1 +if test "x$1" = "x-d"; then + decomp=1 + shift +fi + +echo hi > zfoo1$$ || exit 1 +echo hi > zfoo2$$ || exit 1 +if test -z "`(${CPMOD-cpmod} zfoo1$$ zfoo2$$) 2>&1`"; then + cpmod=${CPMOD-cpmod} +fi +rm -f zfoo[12]$$ + +tail="" +IFS="${IFS= }"; saveifs="$IFS"; IFS="${IFS}:" +for dir in $PATH; do + test -z "$dir" && dir=. + if test -f $dir/tail; then + tail="$dir/tail" + break + fi +done +IFS="$saveifs" +if test -z "$tail"; then + echo cannot find tail + exit 1 +fi +case `echo foo | $tail -n +1 2>/dev/null` in +foo) tail="$tail -n";; +esac + +for i do + if test ! -f "$i" ; then + echo ${x}: $i not a file + res=1 + continue + fi + if test $decomp -eq 0; then + if sed -e 1d -e 2q "$i" | grep "^skip=[0-9]*$" >/dev/null; then + echo "${x}: $i is already gzexe'd" + continue + fi + fi + if ls -l "$i" | grep '^...[sS]' > /dev/null; then + echo "${x}: $i has setuid permission, unchanged" + continue + fi + if ls -l "$i" | grep '^......[sS]' > /dev/null; then + echo "${x}: $i has setgid permission, unchanged" + continue + fi + case "`basename $i`" in + bzip2 | tail | sed | chmod | ln | sleep | rm) + echo "${x}: $i would depend on itself"; continue ;; + esac + if test -z "$cpmod"; then + cp -p "$i" $tmp 2>/dev/null || cp "$i" $tmp + if test -w $tmp 2>/dev/null; then + writable=1 + else + writable=0 + chmod u+w $tmp 2>/dev/null + fi + : >| $tmp # truncate the file, ignoring set -C + fi + if test $decomp -eq 0; then + sed 1q $0 >> $tmp + sed "s|^if tail|if $tail|" >> $tmp <<'EOF' +skip=23 +set -C +umask=`umask` +umask 77 +tmpfile=`tempfile -p gztmp -d /tmp` || exit 1 +if tail +$skip "$0" | /bin/bzip2 -cd >> $tmpfile; then + umask $umask + /bin/chmod 700 $tmpfile + prog="`echo $0 | /bin/sed 's|^.*/||'`" + if /bin/ln $tmpfile "/tmp/$prog" 2>/dev/null; then + trap '/bin/rm -f $tmpfile "/tmp/$prog"; exit $res' 0 + (/bin/sleep 5; /bin/rm -f $tmpfile "/tmp/$prog") 2>/dev/null & + /tmp/"$prog" ${1+"$@"}; res=$? + else + trap '/bin/rm -f $tmpfile; exit $res' 0 + (/bin/sleep 5; /bin/rm -f $tmpfile) 2>/dev/null & + $tmpfile ${1+"$@"}; res=$? + fi +else + echo Cannot decompress $0; exit 1 +fi; exit $res +EOF + bzip2 -cv9 "$i" >> $tmp || { + /bin/rm -f $tmp + echo ${x}: compression not possible for $i, file unchanged. + res=1 + continue + } + + else + # decompression + skip=23 + if sed -e 1d -e 2q "$i" | grep "^skip=[0-9]*$" >/dev/null; then + eval `sed -e 1d -e 2q "$i"` + fi + if tail +$skip "$i" | bzip2 -cd > $tmp; then + : + else + echo ${x}: $i probably not in gzexe format, file unchanged. + res=1 + continue + fi + fi + rm -f "$i~" + mv "$i" "$i~" || { + echo ${x}: cannot backup $i as $i~ + rm -f $tmp + res=1 + continue + } + mv $tmp "$i" || cp -p $tmp "$i" 2>/dev/null || cp $tmp "$i" || { + echo ${x}: cannot create $i + rm -f $tmp + res=1 + continue + } + rm -f $tmp + if test -n "$cpmod"; then + $cpmod "$i~" "$i" 2>/dev/null + elif test $writable -eq 0; then + chmod u-w $i 2>/dev/null + fi +done +exit $res diff --git a/bzexe.1 b/bzexe.1 new file mode 100644 index 0000000..3ed83df --- /dev/null +++ b/bzexe.1 @@ -0,0 +1,43 @@ +.TH BZEXE 1 +.SH NAME +bzexe \- compress executable files in place +.SH SYNOPSIS +.B bzexe +[ name ... ] +.SH DESCRIPTION +The +.I bzexe +utility allows you to compress executables in place and have them +automatically uncompress and execute when you run them (at a penalty +in performance). For example if you execute ``bzexe /bin/cat'' it +will create the following two files: +.nf +.br + -r-xr-xr-x 1 root bin 9644 Feb 11 11:16 /bin/cat + -r-xr-xr-x 1 bin bin 24576 Nov 23 13:21 /bin/cat~ +.fi +/bin/cat~ is the original file and /bin/cat is the self-uncompressing +executable file. You can remove /bin/cat~ once you are sure that +/bin/cat works properly. +.PP +This utility is most useful on systems with very small disks. +.SH OPTIONS +.TP +.B \-d +Decompress the given executables instead of compressing them. +.SH "SEE ALSO" +bzip2(1), znew(1), zmore(1), zcmp(1), zforce(1) +.SH CAVEATS +The compressed executable is a shell script. This may create some +security holes. In particular, the compressed executable relies +on the PATH environment variable to find +.I gzip +and some other utilities +.I (tail, chmod, ln, sleep). +.SH "BUGS" +.I bzexe +attempts to retain the original file attributes on the compressed executable, +but you may have to fix them manually in some cases, using +.I chmod +or +.I chown. diff --git a/bzgrep b/bzgrep index 9a04b83..37de592 100644 --- a/bzgrep +++ b/bzgrep @@ -1,27 +1,75 @@ #!/bin/sh -# Bzgrep wrapped for bzip2, -# adapted from zgrep by Philippe Troin for Debian GNU/Linux. -## zgrep notice: -## zgrep -- a wrapper around a grep program that decompresses files as needed -## Adapted from a version sent by Charles Levert +# bzgrep -- a wrapper around a grep program that decompresses files as needed +# Adapted from zgrep of the Debian gzip package by Anibal Monsalve Salazar. +# Adapted from a version sent by Charles Levert + +# Copyright (C) 1998, 2001, 2002 Free Software Foundation +# Copyright (C) 1993 Jean-loup Gailly + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. PATH="/usr/bin:$PATH"; export PATH -prog=`echo $0 | sed 's|.*/||'` +prog=`echo "$0" | sed 's|.*/||'` case "$prog" in *egrep) grep=${EGREP-egrep} ;; *fgrep) grep=${FGREP-fgrep} ;; *) grep=${GREP-grep} ;; esac + pat="" +after_dash_dash="" +files_with_matches=0 +files_without_matches=0 +no_filename=0 +with_filename=0 + while test $# -ne 0; do - case "$1" in - -e | -f) opt="$opt $1"; shift; pat="$1" + case "$after_dash_dash$1" in + --d* | --rec*) echo >&2 "$0: $1: option not supported"; exit 2;; + --files-with-*) files_with_matches=1;; + --files-witho*) files_without_matches=1;; + --no-f*) no_filename=1;; + --wi*) with_filename=1;; + --*) ;; + -*) + case "$1" in + -*[dr]*) echo >&2 "$0: $1: option not supported"; exit 2;; + esac + case "$1" in + -*H*) with_filename=1;; + esac + case "$1" in + -*h*) no_filename=1;; + esac + case "$1" in + -*L*) files_without_matches=1;; + esac + case "$1" in + -*l*) files_with_matches=1;; + esac;; + esac + case "$after_dash_dash$1" in + -[ef]) opt="$opt $1"; shift; pat="$1" if test "$grep" = grep; then # grep is buggy with -e on SVR4 grep=egrep fi;; - -A | -B) opt="$opt $1 $2"; shift;; + -[ABCdm])opt="$opt $1 $2"; shift;; + --) opt="$opt $1"; after_dash_dash=1;; -*) opt="$opt $1";; *) if test -z "$pat"; then pat="$1" @@ -35,19 +83,9 @@ done if test -z "$pat"; then echo "grep through bzip2 files" echo "usage: $prog [grep_options] pattern [files]" - exit 1 + exit 2 fi -list=0 -silent=0 -op=`echo "$opt" | sed -e 's/ //g' -e 's/-//g'` -case "$op" in - *l*) list=1 -esac -case "$op" in - *h*) silent=1 -esac - if test $# -eq 0; then bzip2 -cdfq | $grep $opt "$pat" exit $? @@ -55,21 +93,40 @@ fi res=0 for i do - if test -f "$i"; then :; else if test -f "$i.bz2"; then i="$i.bz2"; fi; fi - if test $list -eq 1; then - bzip2 -cdfq "$i" | $grep $opt "$pat" 2>&1 > /dev/null && echo $i - r=$? - elif test $# -eq 1 -o $silent -eq 1; then - bzip2 -cdfq "$i" | $grep $opt "$pat" - r=$? - else - j=${i//\\/\\\\} - j=${j//|/\\|} - j=${j//&/\\&} - j=`printf "%s" "$j" | tr '\n' ' '` - bzip2 -cdfq "$i" | $grep $opt "$pat" | sed "s|^|${j}:|" - r=$? - fi - test "$r" -ne 0 && res="$r" + bzip2 -cdfq -- "$i" | + if test $files_with_matches -eq 1; then + $grep $opt "$pat" > /dev/null && printf "%s\n" "$i" + elif test $files_without_matches -eq 1; then + $grep $opt "$pat" > /dev/null || printf "%s\n" "$i" + elif test $with_filename -eq 0 && { test $# -eq 1 || test $no_filename -eq 1; }; then + $grep $opt "$pat" + else + i=$(echo "$i" | sed -e 's/[\\|&]/\\&/g') + if test $with_filename -eq 1; then + sed_script="s|^[^:]*:|${i}:|" + else + sed_script="s|^|${i}:|" + fi + # Hack adapted from GPLed code at + # http://home.comcast.net/~j.p.h/cus-faq-2 + # Has the same effect as the following two lines of bash: + # + # $grep $opt "$pat" | sed "$sed_script" + # exit ${PIPESTATUS[0]} + # + # Inside the `...`, fd4 goes to the pipe whose other end is read + # and passed to eval; fd1 is the normal standard output + # preserved the line before with exec 3>&1 + exec 3>&1 + eval ` + exec 4>&1 >&3 3>&- + { + $grep $opt "$pat" 4>&-; echo "r=$?;" >&4 + } | sed "$sed_script" + ` + exit $r + fi + r=$? + test $res -lt $r && res=$r done exit $res diff --git a/bzip2.c b/bzip2.c index 3904107..e80e40c 100644 --- a/bzip2.c +++ b/bzip2.c @@ -1890,7 +1890,9 @@ IntNative main ( IntNative argc, Char *argv[] ) case '8': blockSize100k = 8; break; case '9': blockSize100k = 9; break; case 'V': - case 'L': license(); break; + case 'L': license(); + exit ( 0 ); + break; case 'v': verbosity++; break; case 'h': usage ( progName ); exit ( 0 ); @@ -1916,8 +1918,8 @@ IntNative main ( IntNative argc, Char *argv[] ) if (ISFLAG("--keep")) keepInputFiles = True; else if (ISFLAG("--small")) smallMode = True; else if (ISFLAG("--quiet")) noisy = False; else - if (ISFLAG("--version")) license(); else - if (ISFLAG("--license")) license(); else + if (ISFLAG("--version")) { license(); exit ( 0 ); } else + if (ISFLAG("--license")) { license(); exit ( 0 ); } else if (ISFLAG("--exponential")) workFactor = 1; else if (ISFLAG("--repetitive-best")) redundant(aa->name); else if (ISFLAG("--repetitive-fast")) redundant(aa->name); else @@ -2003,12 +2005,14 @@ IntNative main ( IntNative argc, Char *argv[] ) testf ( aa->name ); } } - if (testFailsExist && noisy) { - fprintf ( stderr, - "\n" - "You can use the `bzip2recover' program to attempt to recover\n" - "data from undamaged sections of corrupted files.\n\n" - ); + if (testFailsExist) { + if (noisy) { + fprintf ( stderr, + "\n" + "You can use the `bzip2recover' program to attempt to recover\n" + "data from undamaged sections of corrupted files.\n\n" + ); + } setExit(2); exit(exitValue); } diff --git a/bzip2recover.c b/bzip2recover.c index 5f6d621..27a9530 100644 --- a/bzip2recover.c +++ b/bzip2recover.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include /* This program records bit locations in the file to be recovered. @@ -269,6 +271,19 @@ static Bool endsInBz2 ( Char* name ) name[n-1] == '2'); } +/*---------------------------------------------*/ +/* Open an output file safely with O_EXCL and good permissions */ +FILE* fopen_output( Char* name, const char* mode ) +{ + FILE *fp; + int fh; + + fh = open(name, O_WRONLY|O_CREAT|O_EXCL, 0600); + if (fh == -1) return NULL; + fp = fdopen(fh, mode); + if (fp == NULL) close(fh); + return fp; +} /*---------------------------------------------------*/ /*--- ---*/ @@ -486,7 +501,7 @@ Int32 main ( Int32 argc, Char** argv ) fprintf ( stderr, " writing block %d to `%s' ...\n", wrBlock+1, outFileName ); - outFile = fopen ( outFileName, "wb" ); + outFile = fopen_output ( outFileName, "wb" ); if (outFile == NULL) { fprintf ( stderr, "%s: can't write `%s'\n", progName, outFileName ); diff --git a/bzmore b/bzmore index d314043..f423ed9 100644 --- a/bzmore +++ b/bzmore @@ -24,10 +24,10 @@ else # 'stty min 1' resets eof to ^a on both SunOS and SysV! cb='min 1 -icanon'; ncb='icanon eof ^d' fi -if test $? -eq 0 -a -n "$oldtty"; then - trap 'stty $oldtty 2>/dev/null; exit' 0 2 3 5 10 13 15 +if test $? -eq 0 && test -n "$oldtty"; then + trap 'stty $oldtty 2>/dev/null; exit' 0 INT QUIT TRAP USR1 PIPE TERM else - trap 'stty $ncb echo 2>/dev/null; exit' 0 2 3 5 10 13 15 + trap 'stty $ncb echo 2>/dev/null; exit' 0 INT QUIT TRAP USR1 PIPE TERM fi if test $# = 0; then @@ -46,7 +46,7 @@ else ANS=`dd bs=1 count=1 2>/dev/null` stty $ncb echo 2>/dev/null echo " " - if test "$ANS" = 'e' -o "$ANS" = 'q'; then + if test "$ANS" = 'e' || test "$ANS" = 'q'; then exit fi fi diff --git a/manual.xml b/manual.xml index f224136..35eb9ef 100644 --- a/manual.xml +++ b/manual.xml @@ -1162,9 +1162,9 @@ BZ_CONFIG_ERROR if the library has been mis-compiled BZ_PARAM_ERROR if strm is NULL - or blockSize < 1 or blockSize > 9 - or verbosity < 0 or verbosity > 4 - or workFactor < 0 or workFactor > 250 + or blockSize < 1 or blockSize > 9 + or verbosity < 0 or verbosity > 4 + or workFactor < 0 or workFactor > 250 BZ_MEM_ERROR if not enough memory is available BZ_OK @@ -1474,8 +1474,8 @@ could fail with BZ_CONFIG_ERROR if the library has been mis-compiled BZ_PARAM_ERROR - if ( small != 0 && small != 1 ) - or (verbosity <; 0 || verbosity > 4) + if ( small != 0 && small != 1 ) + or (verbosity < 0 || verbosity > 4) BZ_MEM_ERROR if insufficient memory is available @@ -1560,7 +1560,7 @@ and release memory. BZ_PARAM_ERROR if strm is NULL or strm->s is NULL - or strm->avail_out < 1 + or strm->avail_out < 1 BZ_DATA_ERROR if a data integrity error is detected in the compressed stream BZ_DATA_ERROR_MAGIC @@ -1733,8 +1733,8 @@ BZ_CONFIG_ERROR BZ_PARAM_ERROR if f is NULL or small is neither 0 nor 1 - or ( unused == NULL && nUnused != 0 ) - or ( unused != NULL && !(0 <= nUnused <= BZ_MAX_UNUSED) ) + or ( unused == NULL && nUnused != 0 ) + or ( unused != NULL && !(0 <= nUnused <= BZ_MAX_UNUSED) ) BZ_IO_ERROR if ferror(f) is nonzero BZ_MEM_ERROR @@ -1813,7 +1813,7 @@ immediately before BZ_PARAM_ERROR - if b is NULL or buf is NULL or len < 0 + if b is NULL or buf is NULL or len < 0 BZ_SEQUENCE_ERROR if b was opened with BZ2_bzWriteOpen BZ_IO_ERROR @@ -1971,7 +1971,7 @@ BZ_CONFIG_ERROR if the library has been mis-compiled BZ_PARAM_ERROR if f is NULL - or blockSize100k < 1 or blockSize100k > 9 + or blockSize100k < 1 or blockSize100k > 9 BZ_IO_ERROR if ferror(f) is nonzero BZ_MEM_ERROR @@ -2018,7 +2018,7 @@ compressed and written to the file. BZ_PARAM_ERROR - if b is NULL or buf is NULL or len < 0 + if b is NULL or buf is NULL or len < 0 BZ_SEQUENCE_ERROR if b was opened with BZ2_bzReadOpen BZ_IO_ERROR @@ -2169,7 +2169,7 @@ f = fopen ( "myfile.bz2", "w" ); if ( !f ) { /* handle error */ } -b = BZ2_bzWriteOpen( &bzerror, f, 9 ); +b = BZ2_bzWriteOpen( &bzerror, f, 9 ); if (bzerror != BZ_OK) { BZ2_bzWriteClose ( b ); /* handle error */ @@ -2177,14 +2177,14 @@ if (bzerror != BZ_OK) { while ( /* condition */ ) { /* get data to write into buf, and set nBuf appropriately */ - nWritten = BZ2_bzWrite ( &bzerror, b, buf, nBuf ); + nWritten = BZ2_bzWrite ( &bzerror, b, buf, nBuf ); if (bzerror == BZ_IO_ERROR) { - BZ2_bzWriteClose ( &bzerror, b ); + BZ2_bzWriteClose ( &bzerror, b ); /* handle error */ } } -BZ2_bzWriteClose( &bzerror, b ); +BZ2_bzWriteClose( &bzerror, b ); if (bzerror == BZ_IO_ERROR) { /* handle error */ } @@ -2204,24 +2204,24 @@ f = fopen ( "myfile.bz2", "r" ); if ( !f ) { /* handle error */ } -b = BZ2_bzReadOpen ( &bzerror, f, 0, NULL, 0 ); +b = BZ2_bzReadOpen ( &bzerror, f, 0, NULL, 0 ); if ( bzerror != BZ_OK ) { - BZ2_bzReadClose ( &bzerror, b ); + BZ2_bzReadClose ( &bzerror, b ); /* handle error */ } bzerror = BZ_OK; -while ( bzerror == BZ_OK && /* arbitrary other conditions */) { - nBuf = BZ2_bzRead ( &bzerror, b, buf, /* size of buf */ ); +while ( bzerror == BZ_OK && /* arbitrary other conditions */) { + nBuf = BZ2_bzRead ( &bzerror, b, buf, /* size of buf */ ); if ( bzerror == BZ_OK ) { /* do something with buf[0 .. nBuf-1] */ } } if ( bzerror != BZ_STREAM_END ) { - BZ2_bzReadClose ( &bzerror, b ); + BZ2_bzReadClose ( &bzerror, b ); /* handle error */ } else { - BZ2_bzReadClose ( &bzerror, b ); + BZ2_bzReadClose ( &bzerror, b ); } @@ -2287,9 +2287,9 @@ BZ_CONFIG_ERROR if the library has been mis-compiled BZ_PARAM_ERROR if dest is NULL or destLen is NULL - or blockSize100k < 1 or blockSize100k > 9 - or verbosity < 0 or verbosity > 4 - or workFactor < 0 or workFactor > 250 + or blockSize100k < 1 or blockSize100k > 9 + or verbosity < 0 or verbosity > 4 + or workFactor < 0 or workFactor > 250 BZ_MEM_ERROR if insufficient memory is available BZ_OUTBUFF_FULL @@ -2355,8 +2355,8 @@ BZ_CONFIG_ERROR if the library has been mis-compiled BZ_PARAM_ERROR if dest is NULL or destLen is NULL - or small != 0 && small != 1 - or verbosity < 0 or verbosity > 4 + or small != 0 && small != 1 + or verbosity < 0 or verbosity > 4 BZ_MEM_ERROR if insufficient memory is available BZ_OUTBUFF_FULL