aboutsummaryrefslogtreecommitdiff
path: root/bzip2.c
diff options
context:
space:
mode:
authorJulian Seward <jseward@acm.org>1999-09-04 22:13:13 +0200
committerJulian Seward <jseward@acm.org>1999-09-04 22:13:13 +0200
commitf93cd82a9a7094ad90fd19bbc6ccf6f4627f8060 (patch)
treec95407df5665f5a7395683f07552f2b13f2e501f /bzip2.c
parent977101ad5f833f5c0a574bfeea408e5301a6b052 (diff)
downloadbzip2-f93cd82a9a7094ad90fd19bbc6ccf6f4627f8060.tar.gz
bzip2-f93cd82a9a7094ad90fd19bbc6ccf6f4627f8060.tar.bz2
bzip2-f93cd82a9a7094ad90fd19bbc6ccf6f4627f8060.zip
bzip2-0.9.5dbzip2-0.9.5d
Diffstat (limited to 'bzip2.c')
-rw-r--r--bzip2.c545
1 files changed, 357 insertions, 188 deletions
diff --git a/bzip2.c b/bzip2.c
index 6a3ab95..abb9530 100644
--- a/bzip2.c
+++ b/bzip2.c
@@ -7,7 +7,7 @@
7 This file is a part of bzip2 and/or libbzip2, a program and 7 This file is a part of bzip2 and/or libbzip2, a program and
8 library for lossless, block-sorting data compression. 8 library for lossless, block-sorting data compression.
9 9
10 Copyright (C) 1996-1998 Julian R Seward. All rights reserved. 10 Copyright (C) 1996-1999 Julian R Seward. All rights reserved.
11 11
12 Redistribution and use in source and binary forms, with or without 12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions 13 modification, are permitted provided that the following conditions
@@ -40,9 +40,9 @@
40 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 40 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 41 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 42
43 Julian Seward, Guildford, Surrey, UK. 43 Julian Seward, Cambridge, UK.
44 jseward@acm.org 44 jseward@acm.org
45 bzip2/libbzip2 version 0.9.0c of 18 October 1998 45 bzip2/libbzip2 version 0.9.5 of 24 May 1999
46 46
47 This program is based on (at least) the work of: 47 This program is based on (at least) the work of:
48 Mike Burrows 48 Mike Burrows
@@ -123,8 +123,10 @@
123--*/ 123--*/
124#define BZ_LCCWIN32 0 124#define BZ_LCCWIN32 0
125 125
126#ifdef _WIN32 126#if defined(_WIN32) && !defined(__CYGWIN32__)
127#undef BZ_LCCWIN32
127#define BZ_LCCWIN32 1 128#define BZ_LCCWIN32 1
129#undef BZ_UNIX
128#define BZ_UNIX 0 130#define BZ_UNIX 0
129#endif 131#endif
130 132
@@ -139,6 +141,8 @@
139#include <string.h> 141#include <string.h>
140#include <signal.h> 142#include <signal.h>
141#include <math.h> 143#include <math.h>
144#include <errno.h>
145#include <ctype.h>
142#include "bzlib.h" 146#include "bzlib.h"
143 147
144#define ERROR_IF_EOF(i) { if ((i) == EOF) ioError(); } 148#define ERROR_IF_EOF(i) { if ((i) == EOF) ioError(); }
@@ -166,6 +170,9 @@
166# define APPEND_FILESPEC(root, name) \ 170# define APPEND_FILESPEC(root, name) \
167 root=snocString((root), (name)) 171 root=snocString((root), (name))
168 172
173# define APPEND_FLAG(root, name) \
174 root=snocString((root), (name))
175
169# define SET_BINARY_MODE(fd) /**/ 176# define SET_BINARY_MODE(fd) /**/
170 177
171# ifdef __GNUC__ 178# ifdef __GNUC__
@@ -173,6 +180,19 @@
173# else 180# else
174# define NORETURN /**/ 181# define NORETURN /**/
175# endif 182# endif
183# ifdef __DJGPP__
184# include <io.h>
185# include <fcntl.h>
186# undef MY_LSTAT
187# define MY_LSTAT stat
188# undef SET_BINARY_MODE
189# define SET_BINARY_MODE(fd) \
190 do { \
191 int retVal = setmode ( fileno ( fd ), \
192 O_BINARY ); \
193 ERROR_IF_MINUS_ONE ( retVal ); \
194 } while ( 0 )
195# endif
176#endif 196#endif
177 197
178 198
@@ -188,6 +208,9 @@
188# define MY_STAT _stat 208# define MY_STAT _stat
189# define MY_S_IFREG(x) ((x) & _S_IFREG) 209# define MY_S_IFREG(x) ((x) & _S_IFREG)
190 210
211# define APPEND_FLAG(root, name) \
212 root=snocString((root), (name))
213
191# if 0 214# if 0
192 /*-- lcc-win32 seems to expand wildcards itself --*/ 215 /*-- lcc-win32 seems to expand wildcards itself --*/
193# define APPEND_FILESPEC(root, spec) \ 216# define APPEND_FILESPEC(root, spec) \
@@ -254,7 +277,7 @@ typedef int IntNative;
254 277
255Int32 verbosity; 278Int32 verbosity;
256Bool keepInputFiles, smallMode; 279Bool keepInputFiles, smallMode;
257Bool forceOverwrite, testFailsExist; 280Bool forceOverwrite, testFailsExist, noisy;
258Int32 numFileNames, numFilesProcessed, blockSize100k; 281Int32 numFileNames, numFilesProcessed, blockSize100k;
259 282
260 283
@@ -274,8 +297,9 @@ Int32 srcMode;
274#define FILE_NAME_LEN 1034 297#define FILE_NAME_LEN 1034
275 298
276Int32 longestFileName; 299Int32 longestFileName;
277Char inName[FILE_NAME_LEN]; 300Char inName [FILE_NAME_LEN];
278Char outName[FILE_NAME_LEN]; 301Char outName[FILE_NAME_LEN];
302Char tmpName[FILE_NAME_LEN];
279Char *progName; 303Char *progName;
280Char progNameReally[FILE_NAME_LEN]; 304Char progNameReally[FILE_NAME_LEN];
281FILE *outputHandleJustInCase; 305FILE *outputHandleJustInCase;
@@ -467,6 +491,7 @@ Bool uncompressStream ( FILE *zStream, FILE *stream )
467 if (streamNo == 1) { 491 if (streamNo == 1) {
468 return False; 492 return False;
469 } else { 493 } else {
494 if (noisy)
470 fprintf ( stderr, 495 fprintf ( stderr,
471 "\n%s: %s: trailing garbage after EOF ignored\n", 496 "\n%s: %s: trailing garbage after EOF ignored\n",
472 progName, inName ); 497 progName, inName );
@@ -532,32 +557,31 @@ Bool testStream ( FILE *zStream )
532 557
533 errhandler: 558 errhandler:
534 bzReadClose ( &bzerr_dummy, bzf ); 559 bzReadClose ( &bzerr_dummy, bzf );
560 if (verbosity == 0)
561 fprintf ( stderr, "%s: %s: ", progName, inName );
535 switch (bzerr) { 562 switch (bzerr) {
536 case BZ_IO_ERROR: 563 case BZ_IO_ERROR:
537 errhandler_io: 564 errhandler_io:
538 ioError(); break; 565 ioError(); break;
539 case BZ_DATA_ERROR: 566 case BZ_DATA_ERROR:
540 fprintf ( stderr, 567 fprintf ( stderr,
541 "\n%s: data integrity (CRC) error in data\n", 568 "data integrity (CRC) error in data\n" );
542 inName );
543 return False; 569 return False;
544 case BZ_MEM_ERROR: 570 case BZ_MEM_ERROR:
545 outOfMemory(); 571 outOfMemory();
546 case BZ_UNEXPECTED_EOF: 572 case BZ_UNEXPECTED_EOF:
547 fprintf ( stderr, 573 fprintf ( stderr,
548 "\n%s: file ends unexpectedly\n", 574 "file ends unexpectedly\n" );
549 inName );
550 return False; 575 return False;
551 case BZ_DATA_ERROR_MAGIC: 576 case BZ_DATA_ERROR_MAGIC:
552 if (streamNo == 1) { 577 if (streamNo == 1) {
553 fprintf ( stderr, 578 fprintf ( stderr,
554 "\n%s: bad magic number (ie, not created by bzip2)\n", 579 "bad magic number (file not created by bzip2)\n" );
555 inName );
556 return False; 580 return False;
557 } else { 581 } else {
582 if (noisy)
558 fprintf ( stderr, 583 fprintf ( stderr,
559 "\n%s: %s: trailing garbage after EOF ignored\n", 584 "trailing garbage after EOF ignored\n" );
560 progName, inName );
561 return True; 585 return True;
562 } 586 }
563 default: 587 default:
@@ -576,6 +600,7 @@ Bool testStream ( FILE *zStream )
576/*---------------------------------------------*/ 600/*---------------------------------------------*/
577void cadvise ( void ) 601void cadvise ( void )
578{ 602{
603 if (noisy)
579 fprintf ( 604 fprintf (
580 stderr, 605 stderr,
581 "\nIt is possible that the compressed file(s) have become corrupted.\n" 606 "\nIt is possible that the compressed file(s) have become corrupted.\n"
@@ -589,6 +614,7 @@ void cadvise ( void )
589/*---------------------------------------------*/ 614/*---------------------------------------------*/
590void showFileNames ( void ) 615void showFileNames ( void )
591{ 616{
617 if (noisy)
592 fprintf ( 618 fprintf (
593 stderr, 619 stderr,
594 "\tInput file = %s, output file = %s\n", 620 "\tInput file = %s, output file = %s\n",
@@ -603,6 +629,7 @@ void cleanUpAndFail ( Int32 ec )
603 IntNative retVal; 629 IntNative retVal;
604 630
605 if ( srcMode == SM_F2F && opMode != OM_TEST ) { 631 if ( srcMode == SM_F2F && opMode != OM_TEST ) {
632 if (noisy)
606 fprintf ( stderr, "%s: Deleting output file %s, if it exists.\n", 633 fprintf ( stderr, "%s: Deleting output file %s, if it exists.\n",
607 progName, outName ); 634 progName, outName );
608 if (outputHandleJustInCase != NULL) 635 if (outputHandleJustInCase != NULL)
@@ -613,7 +640,7 @@ void cleanUpAndFail ( Int32 ec )
613 "%s: WARNING: deletion of output file (apparently) failed.\n", 640 "%s: WARNING: deletion of output file (apparently) failed.\n",
614 progName ); 641 progName );
615 } 642 }
616 if (numFileNames > 0 && numFilesProcessed < numFileNames) { 643 if (noisy && numFileNames > 0 && numFilesProcessed < numFileNames) {
617 fprintf ( stderr, 644 fprintf ( stderr,
618 "%s: WARNING: some files have not been processed:\n" 645 "%s: WARNING: some files have not been processed:\n"
619 "\t%d specified on command line, %d not processed yet.\n\n", 646 "\t%d specified on command line, %d not processed yet.\n\n",
@@ -639,7 +666,7 @@ void panic ( Char* s )
639 666
640 667
641/*---------------------------------------------*/ 668/*---------------------------------------------*/
642void crcError () 669void crcError ( void )
643{ 670{
644 fprintf ( stderr, 671 fprintf ( stderr,
645 "\n%s: Data integrity error when decompressing.\n", 672 "\n%s: Data integrity error when decompressing.\n",
@@ -665,7 +692,7 @@ void compressedStreamEOF ( void )
665 692
666 693
667/*---------------------------------------------*/ 694/*---------------------------------------------*/
668void ioError ( ) 695void ioError ( void )
669{ 696{
670 fprintf ( stderr, 697 fprintf ( stderr,
671 "\n%s: I/O or other error, bailing out. Possible reason follows.\n", 698 "\n%s: I/O or other error, bailing out. Possible reason follows.\n",
@@ -680,7 +707,7 @@ void ioError ( )
680void mySignalCatcher ( IntNative n ) 707void mySignalCatcher ( IntNative n )
681{ 708{
682 fprintf ( stderr, 709 fprintf ( stderr,
683 "\n%s: Control-C (or similar) caught, quitting.\n", 710 "\n%s: Control-C or similar caught, quitting.\n",
684 progName ); 711 progName );
685 cleanUpAndFail(1); 712 cleanUpAndFail(1);
686} 713}
@@ -740,9 +767,10 @@ void copyFileName ( Char* to, Char* from )
740 if ( strlen(from) > FILE_NAME_LEN-10 ) { 767 if ( strlen(from) > FILE_NAME_LEN-10 ) {
741 fprintf ( 768 fprintf (
742 stderr, 769 stderr,
743 "bzip2: file name\n`%s'\nis suspiciously (> 1024 chars) long.\n" 770 "bzip2: file name\n`%s'\n"
744 "Try using a reasonable file name instead. Sorry! :)\n", 771 "is suspiciously (more than %d chars) long.\n"
745 from 772 "Try using a reasonable file name instead. Sorry! :-)\n",
773 from, FILE_NAME_LEN-10
746 ); 774 );
747 exit(1); 775 exit(1);
748 } 776 }
@@ -779,6 +807,21 @@ Bool notAStandardFile ( Char* name )
779 807
780 808
781/*---------------------------------------------*/ 809/*---------------------------------------------*/
810/*--
811 rac 11/21/98 see if file has hard links to it
812--*/
813Int32 countHardLinks ( Char* name )
814{
815 IntNative i;
816 struct MY_STAT statBuf;
817
818 i = MY_LSTAT ( name, &statBuf );
819 if (i != 0) return 0;
820 return (statBuf.st_nlink - 1);
821}
822
823
824/*---------------------------------------------*/
782void copyDatePermissionsAndOwner ( Char *srcName, Char *dstName ) 825void copyDatePermissionsAndOwner ( Char *srcName, Char *dstName )
783{ 826{
784#if BZ_UNIX 827#if BZ_UNIX
@@ -793,17 +836,14 @@ void copyDatePermissionsAndOwner ( Char *srcName, Char *dstName )
793 836
794 retVal = chmod ( dstName, statBuf.st_mode ); 837 retVal = chmod ( dstName, statBuf.st_mode );
795 ERROR_IF_NOT_ZERO ( retVal ); 838 ERROR_IF_NOT_ZERO ( retVal );
796 /* Not sure if this is really portable or not. Causes 839
797 problems on my x86-Linux Redhat 5.0 box. Decided
798 to omit it from 0.9.0. JRS, 27 June 98. If you
799 understand Unix file semantics and portability issues
800 well enough to fix this properly, drop me a line
801 at jseward@acm.org.
802 retVal = chown ( dstName, statBuf.st_uid, statBuf.st_gid );
803 ERROR_IF_NOT_ZERO ( retVal );
804 */
805 retVal = utime ( dstName, &uTimBuf ); 840 retVal = utime ( dstName, &uTimBuf );
806 ERROR_IF_NOT_ZERO ( retVal ); 841 ERROR_IF_NOT_ZERO ( retVal );
842
843 retVal = chown ( dstName, statBuf.st_uid, statBuf.st_gid );
844 /* chown() will in many cases return with EPERM, which can
845 be safely ignored.
846 */
807#endif 847#endif
808} 848}
809 849
@@ -819,20 +859,6 @@ void setInterimPermissions ( Char *dstName )
819} 859}
820 860
821 861
822
823/*---------------------------------------------*/
824Bool endsInBz2 ( Char* name )
825{
826 Int32 n = strlen ( name );
827 if (n <= 4) return False;
828 return
829 (name[n-4] == '.' &&
830 name[n-3] == 'b' &&
831 name[n-2] == 'z' &&
832 name[n-1] == '2');
833}
834
835
836/*---------------------------------------------*/ 862/*---------------------------------------------*/
837Bool containsDubiousChars ( Char* name ) 863Bool containsDubiousChars ( Char* name )
838{ 864{
@@ -844,49 +870,94 @@ Bool containsDubiousChars ( Char* name )
844 870
845 871
846/*---------------------------------------------*/ 872/*---------------------------------------------*/
847void compress ( Char *name ) 873#define BZ_N_SUFFIX_PAIRS 4
874
875Char* zSuffix[BZ_N_SUFFIX_PAIRS]
876 = { ".bz2", ".bz", ".tbz2", ".tbz" };
877Char* unzSuffix[BZ_N_SUFFIX_PAIRS]
878 = { "", "", ".tar", ".tar" };
879
880Bool hasSuffix ( Char* s, Char* suffix )
848{ 881{
849 FILE *inStr; 882 Int32 ns = strlen(s);
850 FILE *outStr; 883 Int32 nx = strlen(suffix);
884 if (ns < nx) return False;
885 if (strcmp(s + ns - nx, suffix) == 0) return True;
886 return False;
887}
851 888
889Bool mapSuffix ( Char* name,
890 Char* oldSuffix, Char* newSuffix )
891{
892 if (!hasSuffix(name,oldSuffix)) return False;
893 name[strlen(name)-strlen(oldSuffix)] = 0;
894 strcat ( name, newSuffix );
895 return True;
896}
897
898
899/*---------------------------------------------*/
900void compress ( Char *name )
901{
902 FILE *inStr;
903 FILE *outStr;
904 Int32 n, i;
852 if (name == NULL && srcMode != SM_I2O) 905 if (name == NULL && srcMode != SM_I2O)
853 panic ( "compress: bad modes\n" ); 906 panic ( "compress: bad modes\n" );
854 907
855 switch (srcMode) { 908 switch (srcMode) {
856 case SM_I2O: copyFileName ( inName, "(stdin)" ); 909 case SM_I2O:
857 copyFileName ( outName, "(stdout)" ); break; 910 copyFileName ( inName, "(stdin)" );
858 case SM_F2F: copyFileName ( inName, name ); 911 copyFileName ( outName, "(stdout)" );
859 copyFileName ( outName, name ); 912 break;
860 strcat ( outName, ".bz2" ); break; 913 case SM_F2F:
861 case SM_F2O: copyFileName ( inName, name ); 914 copyFileName ( inName, name );
862 copyFileName ( outName, "(stdout)" ); break; 915 copyFileName ( outName, name );
916 strcat ( outName, ".bz2" );
917 break;
918 case SM_F2O:
919 copyFileName ( inName, name );
920 copyFileName ( outName, "(stdout)" );
921 break;
863 } 922 }
864 923
865 if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) { 924 if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
925 if (noisy)
866 fprintf ( stderr, "%s: There are no files matching `%s'.\n", 926 fprintf ( stderr, "%s: There are no files matching `%s'.\n",
867 progName, inName ); 927 progName, inName );
868 return; 928 return;
869 } 929 }
870 if ( srcMode != SM_I2O && !fileExists ( inName ) ) { 930 if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
871 fprintf ( stderr, "%s: Input file %s doesn't exist, skipping.\n", 931 fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
872 progName, inName ); 932 progName, inName, strerror(errno) );
873 return; 933 return;
874 } 934 }
875 if ( srcMode != SM_I2O && endsInBz2 ( inName )) { 935 for (i = 0; i < BZ_N_SUFFIX_PAIRS; i++) {
876 fprintf ( stderr, "%s: Input file name %s ends in `.bz2', skipping.\n", 936 if (hasSuffix(inName, zSuffix[i])) {
877 progName, inName ); 937 if (noisy)
878 return; 938 fprintf ( stderr,
939 "%s: Input file %s already has %s suffix.\n",
940 progName, inName, zSuffix[i] );
941 return;
942 }
879 } 943 }
880 if ( srcMode != SM_I2O && notAStandardFile ( inName )) { 944 if ( srcMode == SM_F2F && !forceOverwrite && notAStandardFile ( inName )) {
881 fprintf ( stderr, "%s: Input file %s is not a normal file, skipping.\n", 945 if (noisy)
946 fprintf ( stderr, "%s: Input file %s is not a normal file.\n",
882 progName, inName ); 947 progName, inName );
883 return; 948 return;
884 } 949 }
885 if ( srcMode == SM_F2F && !forceOverwrite && fileExists ( outName ) ) { 950 if ( srcMode == SM_F2F && !forceOverwrite && fileExists ( outName ) ) {
886 fprintf ( stderr, "%s: Output file %s already exists, skipping.\n", 951 fprintf ( stderr, "%s: Output file %s already exists.\n",
887 progName, outName ); 952 progName, outName );
888 return; 953 return;
889 } 954 }
955 if ( srcMode == SM_F2F && !forceOverwrite &&
956 (n=countHardLinks ( inName )) > 0) {
957 fprintf ( stderr, "%s: Input file %s has %d other link%s.\n",
958 progName, inName, n, n > 1 ? "s" : "" );
959 return;
960 }
890 961
891 switch ( srcMode ) { 962 switch ( srcMode ) {
892 963
@@ -912,11 +983,12 @@ void compress ( Char *name )
912 progName ); 983 progName );
913 fprintf ( stderr, "%s: For help, type: `%s --help'.\n", 984 fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
914 progName, progName ); 985 progName, progName );
986 if ( inStr != NULL ) fclose ( inStr );
915 return; 987 return;
916 }; 988 };
917 if ( inStr == NULL ) { 989 if ( inStr == NULL ) {
918 fprintf ( stderr, "%s: Can't open input file %s, skipping.\n", 990 fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
919 progName, inName ); 991 progName, inName, strerror(errno) );
920 return; 992 return;
921 }; 993 };
922 break; 994 break;
@@ -925,13 +997,15 @@ void compress ( Char *name )
925 inStr = fopen ( inName, "rb" ); 997 inStr = fopen ( inName, "rb" );
926 outStr = fopen ( outName, "wb" ); 998 outStr = fopen ( outName, "wb" );
927 if ( outStr == NULL) { 999 if ( outStr == NULL) {
928 fprintf ( stderr, "%s: Can't create output file %s, skipping.\n", 1000 fprintf ( stderr, "%s: Can't create output file %s: %s.\n",
929 progName, outName ); 1001 progName, outName, strerror(errno) );
1002 if ( inStr != NULL ) fclose ( inStr );
930 return; 1003 return;
931 } 1004 }
932 if ( inStr == NULL ) { 1005 if ( inStr == NULL ) {
933 fprintf ( stderr, "%s: Can't open input file %s, skipping.\n", 1006 fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
934 progName, inName ); 1007 progName, inName, strerror(errno) );
1008 if ( outStr != NULL ) fclose ( outStr );
935 return; 1009 return;
936 }; 1010 };
937 setInterimPermissions ( outName ); 1011 setInterimPermissions ( outName );
@@ -967,51 +1041,72 @@ void compress ( Char *name )
967/*---------------------------------------------*/ 1041/*---------------------------------------------*/
968void uncompress ( Char *name ) 1042void uncompress ( Char *name )
969{ 1043{
970 FILE *inStr; 1044 FILE *inStr;
971 FILE *outStr; 1045 FILE *outStr;
972 Bool magicNumberOK; 1046 Int32 n, i;
1047 Bool magicNumberOK;
1048 Bool cantGuess;
973 1049
974 if (name == NULL && srcMode != SM_I2O) 1050 if (name == NULL && srcMode != SM_I2O)
975 panic ( "uncompress: bad modes\n" ); 1051 panic ( "uncompress: bad modes\n" );
976 1052
1053 cantGuess = False;
977 switch (srcMode) { 1054 switch (srcMode) {
978 case SM_I2O: copyFileName ( inName, "(stdin)" ); 1055 case SM_I2O:
979 copyFileName ( outName, "(stdout)" ); break; 1056 copyFileName ( inName, "(stdin)" );
980 case SM_F2F: copyFileName ( inName, name ); 1057 copyFileName ( outName, "(stdout)" );
981 copyFileName ( outName, name ); 1058 break;
982 if (endsInBz2 ( outName )) 1059 case SM_F2F:
983 outName [ strlen ( outName ) - 4 ] = '\0'; 1060 copyFileName ( inName, name );
984 break; 1061 copyFileName ( outName, name );
985 case SM_F2O: copyFileName ( inName, name ); 1062 for (i = 0; i < BZ_N_SUFFIX_PAIRS; i++)
986 copyFileName ( outName, "(stdout)" ); break; 1063 if (mapSuffix(outName,zSuffix[i],unzSuffix[i]))
1064 goto zzz;
1065 cantGuess = True;
1066 strcat ( outName, ".out" );
1067 break;
1068 case SM_F2O:
1069 copyFileName ( inName, name );
1070 copyFileName ( outName, "(stdout)" );
1071 break;
987 } 1072 }
988 1073
1074 zzz:
989 if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) { 1075 if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
1076 if (noisy)
990 fprintf ( stderr, "%s: There are no files matching `%s'.\n", 1077 fprintf ( stderr, "%s: There are no files matching `%s'.\n",
991 progName, inName ); 1078 progName, inName );
992 return; 1079 return;
993 } 1080 }
994 if ( srcMode != SM_I2O && !fileExists ( inName ) ) { 1081 if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
995 fprintf ( stderr, "%s: Input file %s doesn't exist, skipping.\n", 1082 fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
996 progName, inName ); 1083 progName, inName, strerror(errno) );
997 return; 1084 return;
998 } 1085 }
999 if ( srcMode != SM_I2O && !endsInBz2 ( inName )) { 1086 if ( srcMode == SM_F2F && !forceOverwrite && notAStandardFile ( inName )) {
1000 fprintf ( stderr, 1087 if (noisy)
1001 "%s: Input file name %s doesn't end in `.bz2', skipping.\n", 1088 fprintf ( stderr, "%s: Input file %s is not a normal file.\n",
1002 progName, inName );
1003 return;
1004 }
1005 if ( srcMode != SM_I2O && notAStandardFile ( inName )) {
1006 fprintf ( stderr, "%s: Input file %s is not a normal file, skipping.\n",
1007 progName, inName ); 1089 progName, inName );
1008 return; 1090 return;
1009 } 1091 }
1092 if ( /* srcMode == SM_F2F implied && */ cantGuess ) {
1093 if (noisy)
1094 fprintf ( stderr,
1095 "%s: Can't guess original name for %s -- using %s\n",
1096 progName, inName, outName );
1097 /* just a warning, no return */
1098 }
1010 if ( srcMode == SM_F2F && !forceOverwrite && fileExists ( outName ) ) { 1099 if ( srcMode == SM_F2F && !forceOverwrite && fileExists ( outName ) ) {
1011 fprintf ( stderr, "%s: Output file %s already exists, skipping.\n", 1100 fprintf ( stderr, "%s: Output file %s already exists.\n",
1012 progName, outName ); 1101 progName, outName );
1013 return; 1102 return;
1014 } 1103 }
1104 if ( srcMode == SM_F2F && !forceOverwrite &&
1105 (n=countHardLinks ( inName ) ) > 0) {
1106 fprintf ( stderr, "%s: Input file %s has %d other link%s.\n",
1107 progName, inName, n, n > 1 ? "s" : "" );
1108 return;
1109 }
1015 1110
1016 switch ( srcMode ) { 1111 switch ( srcMode ) {
1017 1112
@@ -1032,8 +1127,9 @@ void uncompress ( Char *name )
1032 inStr = fopen ( inName, "rb" ); 1127 inStr = fopen ( inName, "rb" );
1033 outStr = stdout; 1128 outStr = stdout;
1034 if ( inStr == NULL ) { 1129 if ( inStr == NULL ) {
1035 fprintf ( stderr, "%s: Can't open input file %s, skipping.\n", 1130 fprintf ( stderr, "%s: Can't open input file %s:%s.\n",
1036 progName, inName ); 1131 progName, inName, strerror(errno) );
1132 if ( inStr != NULL ) fclose ( inStr );
1037 return; 1133 return;
1038 }; 1134 };
1039 break; 1135 break;
@@ -1042,13 +1138,15 @@ void uncompress ( Char *name )
1042 inStr = fopen ( inName, "rb" ); 1138 inStr = fopen ( inName, "rb" );
1043 outStr = fopen ( outName, "wb" ); 1139 outStr = fopen ( outName, "wb" );
1044 if ( outStr == NULL) { 1140 if ( outStr == NULL) {
1045 fprintf ( stderr, "%s: Can't create output file %s, skipping.\n", 1141 fprintf ( stderr, "%s: Can't create output file %s: %s.\n",
1046 progName, outName ); 1142 progName, outName, strerror(errno) );
1143 if ( inStr != NULL ) fclose ( inStr );
1047 return; 1144 return;
1048 } 1145 }
1049 if ( inStr == NULL ) { 1146 if ( inStr == NULL ) {
1050 fprintf ( stderr, "%s: Can't open input file %s, skipping.\n", 1147 fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
1051 progName, inName ); 1148 progName, inName, strerror(errno) );
1149 if ( outStr != NULL ) fclose ( outStr );
1052 return; 1150 return;
1053 }; 1151 };
1054 setInterimPermissions ( outName ); 1152 setInterimPermissions ( outName );
@@ -1091,9 +1189,9 @@ void uncompress ( Char *name )
1091 fprintf ( stderr, "done\n" ); 1189 fprintf ( stderr, "done\n" );
1092 } else { 1190 } else {
1093 if (verbosity >= 1) 1191 if (verbosity >= 1)
1094 fprintf ( stderr, "not a bzip2 file, skipping.\n" ); else 1192 fprintf ( stderr, "not a bzip2 file.\n" ); else
1095 fprintf ( stderr, 1193 fprintf ( stderr,
1096 "%s: %s is not a bzip2 file, skipping.\n", 1194 "%s: %s is not a bzip2 file.\n",
1097 progName, inName ); 1195 progName, inName );
1098 } 1196 }
1099 1197
@@ -1117,24 +1215,14 @@ void testf ( Char *name )
1117 } 1215 }
1118 1216
1119 if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) { 1217 if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
1218 if (noisy)
1120 fprintf ( stderr, "%s: There are no files matching `%s'.\n", 1219 fprintf ( stderr, "%s: There are no files matching `%s'.\n",
1121 progName, inName ); 1220 progName, inName );
1122 return; 1221 return;
1123 } 1222 }
1124 if ( srcMode != SM_I2O && !fileExists ( inName ) ) { 1223 if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
1125 fprintf ( stderr, "%s: Input file %s doesn't exist, skipping.\n", 1224 fprintf ( stderr, "%s: Can't open input %s: %s.\n",
1126 progName, inName ); 1225 progName, inName, strerror(errno) );
1127 return;
1128 }
1129 if ( srcMode != SM_I2O && !endsInBz2 ( inName )) {
1130 fprintf ( stderr,
1131 "%s: Input file name %s doesn't end in `.bz2', skipping.\n",
1132 progName, inName );
1133 return;
1134 }
1135 if ( srcMode != SM_I2O && notAStandardFile ( inName )) {
1136 fprintf ( stderr, "%s: Input file %s is not a normal file, skipping.\n",
1137 progName, inName );
1138 return; 1226 return;
1139 } 1227 }
1140 1228
@@ -1155,8 +1243,8 @@ void testf ( Char *name )
1155 case SM_F2O: case SM_F2F: 1243 case SM_F2O: case SM_F2F:
1156 inStr = fopen ( inName, "rb" ); 1244 inStr = fopen ( inName, "rb" );
1157 if ( inStr == NULL ) { 1245 if ( inStr == NULL ) {
1158 fprintf ( stderr, "%s: Can't open input file %s, skipping.\n", 1246 fprintf ( stderr, "%s: Can't open input file %s:%s.\n",
1159 progName, inName ); 1247 progName, inName, strerror(errno) );
1160 return; 1248 return;
1161 }; 1249 };
1162 break; 1250 break;
@@ -1186,13 +1274,13 @@ void license ( void )
1186 fprintf ( stderr, 1274 fprintf ( stderr,
1187 1275
1188 "bzip2, a block-sorting file compressor. " 1276 "bzip2, a block-sorting file compressor. "
1189 "Version 0.9.0c, 18-Oct-98.\n" 1277 "Version 0.9.5d, 4-Sept-99.\n"
1190 " \n" 1278 " \n"
1191 " Copyright (C) 1996, 1997, 1998 by Julian Seward.\n" 1279 " Copyright (C) 1996, 1997, 1998, 1999 by Julian Seward.\n"
1192 " \n" 1280 " \n"
1193 " This program is free software; you can redistribute it and/or modify\n" 1281 " This program is free software; you can redistribute it and/or modify\n"
1194 " it under the terms set out in the LICENSE file, which is included\n" 1282 " it under the terms set out in the LICENSE file, which is included\n"
1195 " in the bzip2-0.9.0c source distribution.\n" 1283 " in the bzip2-0.9.5 source distribution.\n"
1196 " \n" 1284 " \n"
1197 " This program is distributed in the hope that it will be useful,\n" 1285 " This program is distributed in the hope that it will be useful,\n"
1198 " but WITHOUT ANY WARRANTY; without even the implied warranty of\n" 1286 " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
@@ -1209,27 +1297,26 @@ void usage ( Char *fullProgName )
1209 fprintf ( 1297 fprintf (
1210 stderr, 1298 stderr,
1211 "bzip2, a block-sorting file compressor. " 1299 "bzip2, a block-sorting file compressor. "
1212 "Version 0.9.0c, 18-Oct-98.\n" 1300 "Version 0.9.5d, 4-Sept-99.\n"
1213 "\n usage: %s [flags and input files in any order]\n" 1301 "\n usage: %s [flags and input files in any order]\n"
1214 "\n" 1302 "\n"
1215 " -h --help print this message\n" 1303 " -h --help print this message\n"
1216 " -d --decompress force decompression\n" 1304 " -d --decompress force decompression\n"
1217 " -z --compress force compression\n" 1305 " -z --compress force compression\n"
1218 " -k --keep keep (don't delete) input files\n" 1306 " -k --keep keep (don't delete) input files\n"
1219 " -f --force overwrite existing output filess\n" 1307 " -f --force overwrite existing output files\n"
1220 " -t --test test compressed file integrity\n" 1308 " -t --test test compressed file integrity\n"
1221 " -c --stdout output to standard out\n" 1309 " -c --stdout output to standard out\n"
1310 " -q --quiet suppress noncritical error messages\n"
1222 " -v --verbose be verbose (a 2nd -v gives more)\n" 1311 " -v --verbose be verbose (a 2nd -v gives more)\n"
1223 " -L --license display software version & license\n" 1312 " -L --license display software version & license\n"
1224 " -V --version display software version & license\n" 1313 " -V --version display software version & license\n"
1225 " -s --small use less memory (at most 2500k)\n" 1314 " -s --small use less memory (at most 2500k)\n"
1226 " -1 .. -9 set block size to 100k .. 900k\n" 1315 " -1 .. -9 set block size to 100k .. 900k\n"
1227 " --repetitive-fast compress repetitive blocks faster\n"
1228 " --repetitive-best compress repetitive blocks better\n"
1229 "\n" 1316 "\n"
1230 " If invoked as `bzip2', default action is to compress.\n" 1317 " If invoked as `bzip2', default action is to compress.\n"
1231 " as `bunzip2', default action is to decompress.\n" 1318 " as `bunzip2', default action is to decompress.\n"
1232 " as `bz2cat', default action is to decompress to stdout.\n" 1319 " as `bzcat', default action is to decompress to stdout.\n"
1233 "\n" 1320 "\n"
1234 " If no file names are given, bzip2 compresses or decompresses\n" 1321 " If no file names are given, bzip2 compresses or decompresses\n"
1235 " from standard input to standard output. You can combine\n" 1322 " from standard input to standard output. You can combine\n"
@@ -1245,18 +1332,28 @@ void usage ( Char *fullProgName )
1245 1332
1246 1333
1247/*---------------------------------------------*/ 1334/*---------------------------------------------*/
1335void redundant ( Char* flag )
1336{
1337 fprintf (
1338 stderr,
1339 "%s: %s is redundant in versions 0.9.5 and above\n",
1340 progName, flag );
1341}
1342
1343
1344/*---------------------------------------------*/
1248/*-- 1345/*--
1249 All the garbage from here to main() is purely to 1346 All the garbage from here to main() is purely to
1250 implement a linked list of command-line arguments, 1347 implement a linked list of command-line arguments,
1251 into which main() copies argv[1 .. argc-1]. 1348 into which main() copies argv[1 .. argc-1].
1252 1349
1253 The purpose of this ridiculous exercise is to 1350 The purpose of this exercise is to facilitate
1254 facilitate the expansion of wildcard characters 1351 the expansion of wildcard characters * and ? in
1255 * and ? in filenames for halfwitted OSs like 1352 filenames for OSs which don't know how to do it
1256 MSDOS, Windows 95 and NT. 1353 themselves, like MSDOS, Windows 95 and NT.
1257 1354
1258 The actual Dirty Work is done by the platform-specific 1355 The actual Dirty Work is done by the platform-
1259 macro APPEND_FILESPEC. 1356 specific macro APPEND_FILESPEC.
1260--*/ 1357--*/
1261 1358
1262typedef 1359typedef
@@ -1308,15 +1405,42 @@ Cell *snocString ( Cell *root, Char *name )
1308 1405
1309 1406
1310/*---------------------------------------------*/ 1407/*---------------------------------------------*/
1311#define ISFLAG(s) (strcmp(aa->name, (s))==0) 1408void addFlagsFromEnvVar ( Cell** argList, Char* varName )
1409{
1410 Int32 i, j, k;
1411 Char *envbase, *p;
1412
1413 envbase = getenv(varName);
1414 if (envbase != NULL) {
1415 p = envbase;
1416 i = 0;
1417 while (True) {
1418 if (p[i] == 0) break;
1419 p += i;
1420 i = 0;
1421 while (isspace((Int32)(p[0]))) p++;
1422 while (p[i] != 0 && !isspace((Int32)(p[i]))) i++;
1423 if (i > 0) {
1424 k = i; if (k > FILE_NAME_LEN-10) k = FILE_NAME_LEN-10;
1425 for (j = 0; j < k; j++) tmpName[j] = p[j];
1426 tmpName[k] = 0;
1427 APPEND_FLAG(*argList, tmpName);
1428 }
1429 }
1430 }
1431}
1312 1432
1313 1433
1434/*---------------------------------------------*/
1435#define ISFLAG(s) (strcmp(aa->name, (s))==0)
1436
1314IntNative main ( IntNative argc, Char *argv[] ) 1437IntNative main ( IntNative argc, Char *argv[] )
1315{ 1438{
1316 Int32 i, j; 1439 Int32 i, j;
1317 Char *tmp; 1440 Char *tmp;
1318 Cell *argList; 1441 Cell *argList;
1319 Cell *aa; 1442 Cell *aa;
1443 Bool decode;
1320 1444
1321 /*-- Be really really really paranoid :-) --*/ 1445 /*-- Be really really really paranoid :-) --*/
1322 if (sizeof(Int32) != 4 || sizeof(UInt32) != 4 || 1446 if (sizeof(Int32) != 4 || sizeof(UInt32) != 4 ||
@@ -1332,27 +1456,27 @@ IntNative main ( IntNative argc, Char *argv[] )
1332 } 1456 }
1333 1457
1334 1458
1335 /*-- Set up signal handlers --*/
1336 signal (SIGINT, mySignalCatcher);
1337 signal (SIGTERM, mySignalCatcher);
1338 signal (SIGSEGV, mySIGSEGVorSIGBUScatcher);
1339#if BZ_UNIX
1340 signal (SIGHUP, mySignalCatcher);
1341 signal (SIGBUS, mySIGSEGVorSIGBUScatcher);
1342#endif
1343
1344
1345 /*-- Initialise --*/ 1459 /*-- Initialise --*/
1346 outputHandleJustInCase = NULL; 1460 outputHandleJustInCase = NULL;
1347 smallMode = False; 1461 smallMode = False;
1348 keepInputFiles = False; 1462 keepInputFiles = False;
1349 forceOverwrite = False; 1463 forceOverwrite = False;
1464 noisy = True;
1350 verbosity = 0; 1465 verbosity = 0;
1351 blockSize100k = 9; 1466 blockSize100k = 9;
1352 testFailsExist = False; 1467 testFailsExist = False;
1353 numFileNames = 0; 1468 numFileNames = 0;
1354 numFilesProcessed = 0; 1469 numFilesProcessed = 0;
1355 workFactor = 30; 1470 workFactor = 30;
1471 i = j = 0; /* avoid bogus warning from egcs-1.1.X */
1472
1473 /*-- Set up signal handlers for mem access errors --*/
1474 signal (SIGSEGV, mySIGSEGVorSIGBUScatcher);
1475#if BZ_UNIX
1476#ifndef __DJGPP__
1477 signal (SIGBUS, mySIGSEGVorSIGBUScatcher);
1478#endif
1479#endif
1356 1480
1357 copyFileName ( inName, "(none)" ); 1481 copyFileName ( inName, "(none)" );
1358 copyFileName ( outName, "(none)" ); 1482 copyFileName ( outName, "(none)" );
@@ -1363,8 +1487,12 @@ IntNative main ( IntNative argc, Char *argv[] )
1363 if (*tmp == PATH_SEP) progName = tmp + 1; 1487 if (*tmp == PATH_SEP) progName = tmp + 1;
1364 1488
1365 1489
1366 /*-- Expand filename wildcards in arg list --*/ 1490 /*-- Copy flags from env var BZIP2, and
1491 expand filename wildcards in arg list.
1492 --*/
1367 argList = NULL; 1493 argList = NULL;
1494 addFlagsFromEnvVar ( &argList, "BZIP2" );
1495 addFlagsFromEnvVar ( &argList, "BZIP" );
1368 for (i = 1; i <= argc-1; i++) 1496 for (i = 1; i <= argc-1; i++)
1369 APPEND_FILESPEC(argList, argv[i]); 1497 APPEND_FILESPEC(argList, argv[i]);
1370 1498
@@ -1372,12 +1500,14 @@ IntNative main ( IntNative argc, Char *argv[] )
1372 /*-- Find the length of the longest filename --*/ 1500 /*-- Find the length of the longest filename --*/
1373 longestFileName = 7; 1501 longestFileName = 7;
1374 numFileNames = 0; 1502 numFileNames = 0;
1375 for (aa = argList; aa != NULL; aa = aa->link) 1503 decode = True;
1376 if (aa->name[0] != '-') { 1504 for (aa = argList; aa != NULL; aa = aa->link) {
1377 numFileNames++; 1505 if (ISFLAG("--")) { decode = False; continue; }
1378 if (longestFileName < (Int32)strlen(aa->name) ) 1506 if (aa->name[0] == '-' && decode) continue;
1379 longestFileName = (Int32)strlen(aa->name); 1507 numFileNames++;
1380 } 1508 if (longestFileName < (Int32)strlen(aa->name) )
1509 longestFileName = (Int32)strlen(aa->name);
1510 }
1381 1511
1382 1512
1383 /*-- Determine source modes; flag handling may change this too. --*/ 1513 /*-- Determine source modes; flag handling may change this too. --*/
@@ -1403,9 +1533,10 @@ IntNative main ( IntNative argc, Char *argv[] )
1403 1533
1404 1534
1405 /*-- Look at the flags. --*/ 1535 /*-- Look at the flags. --*/
1406 for (aa = argList; aa != NULL; aa = aa->link) 1536 for (aa = argList; aa != NULL; aa = aa->link) {
1407 if (aa->name[0] == '-' && aa->name[1] != '-') 1537 if (ISFLAG("--")) break;
1408 for (j = 1; aa->name[j] != '\0'; j++) 1538 if (aa->name[0] == '-' && aa->name[1] != '-') {
1539 for (j = 1; aa->name[j] != '\0'; j++) {
1409 switch (aa->name[j]) { 1540 switch (aa->name[j]) {
1410 case 'c': srcMode = SM_F2O; break; 1541 case 'c': srcMode = SM_F2O; break;
1411 case 'd': opMode = OM_UNZ; break; 1542 case 'd': opMode = OM_UNZ; break;
@@ -1414,6 +1545,7 @@ IntNative main ( IntNative argc, Char *argv[] )
1414 case 't': opMode = OM_TEST; break; 1545 case 't': opMode = OM_TEST; break;
1415 case 'k': keepInputFiles = True; break; 1546 case 'k': keepInputFiles = True; break;
1416 case 's': smallMode = True; break; 1547 case 's': smallMode = True; break;
1548 case 'q': noisy = False; break;
1417 case '1': blockSize100k = 1; break; 1549 case '1': blockSize100k = 1; break;
1418 case '2': blockSize100k = 2; break; 1550 case '2': blockSize100k = 2; break;
1419 case '3': blockSize100k = 3; break; 1551 case '3': blockSize100k = 3; break;
@@ -1427,17 +1559,21 @@ IntNative main ( IntNative argc, Char *argv[] )
1427 case 'L': license(); break; 1559 case 'L': license(); break;
1428 case 'v': verbosity++; break; 1560 case 'v': verbosity++; break;
1429 case 'h': usage ( progName ); 1561 case 'h': usage ( progName );
1430 exit ( 1 ); 1562 exit ( 0 );
1431 break; 1563 break;
1432 default: fprintf ( stderr, "%s: Bad flag `%s'\n", 1564 default: fprintf ( stderr, "%s: Bad flag `%s'\n",
1433 progName, aa->name ); 1565 progName, aa->name );
1434 usage ( progName ); 1566 usage ( progName );
1435 exit ( 1 ); 1567 exit ( 1 );
1436 break; 1568 break;
1569 }
1437 } 1570 }
1438 1571 }
1572 }
1573
1439 /*-- And again ... --*/ 1574 /*-- And again ... --*/
1440 for (aa = argList; aa != NULL; aa = aa->link) { 1575 for (aa = argList; aa != NULL; aa = aa->link) {
1576 if (ISFLAG("--")) break;
1441 if (ISFLAG("--stdout")) srcMode = SM_F2O; else 1577 if (ISFLAG("--stdout")) srcMode = SM_F2O; else
1442 if (ISFLAG("--decompress")) opMode = OM_UNZ; else 1578 if (ISFLAG("--decompress")) opMode = OM_UNZ; else
1443 if (ISFLAG("--compress")) opMode = OM_Z; else 1579 if (ISFLAG("--compress")) opMode = OM_Z; else
@@ -1445,12 +1581,14 @@ IntNative main ( IntNative argc, Char *argv[] )
1445 if (ISFLAG("--test")) opMode = OM_TEST; else 1581 if (ISFLAG("--test")) opMode = OM_TEST; else
1446 if (ISFLAG("--keep")) keepInputFiles = True; else 1582 if (ISFLAG("--keep")) keepInputFiles = True; else
1447 if (ISFLAG("--small")) smallMode = True; else 1583 if (ISFLAG("--small")) smallMode = True; else
1584 if (ISFLAG("--quiet")) noisy = False; else
1448 if (ISFLAG("--version")) license(); else 1585 if (ISFLAG("--version")) license(); else
1449 if (ISFLAG("--license")) license(); else 1586 if (ISFLAG("--license")) license(); else
1450 if (ISFLAG("--repetitive-fast")) workFactor = 5; else 1587 if (ISFLAG("--exponential")) workFactor = 1; else
1451 if (ISFLAG("--repetitive-best")) workFactor = 150; else 1588 if (ISFLAG("--repetitive-best")) redundant(aa->name); else
1589 if (ISFLAG("--repetitive-fast")) redundant(aa->name); else
1452 if (ISFLAG("--verbose")) verbosity++; else 1590 if (ISFLAG("--verbose")) verbosity++; else
1453 if (ISFLAG("--help")) { usage ( progName ); exit ( 1 ); } 1591 if (ISFLAG("--help")) { usage ( progName ); exit ( 0 ); }
1454 else 1592 else
1455 if (strncmp ( aa->name, "--", 2) == 0) { 1593 if (strncmp ( aa->name, "--", 2) == 0) {
1456 fprintf ( stderr, "%s: Bad flag `%s'\n", progName, aa->name ); 1594 fprintf ( stderr, "%s: Bad flag `%s'\n", progName, aa->name );
@@ -1460,13 +1598,8 @@ IntNative main ( IntNative argc, Char *argv[] )
1460 } 1598 }
1461 1599
1462 if (verbosity > 4) verbosity = 4; 1600 if (verbosity > 4) verbosity = 4;
1463 if (opMode == OM_Z && smallMode) blockSize100k = 2; 1601 if (opMode == OM_Z && smallMode && blockSize100k > 2)
1464 1602 blockSize100k = 2;
1465 if (srcMode == SM_F2O && numFileNames == 0) {
1466 fprintf ( stderr, "%s: -c expects at least one filename.\n",
1467 progName );
1468 exit ( 1 );
1469 }
1470 1603
1471 if (opMode == OM_TEST && srcMode == SM_F2O) { 1604 if (opMode == OM_TEST && srcMode == SM_F2O) {
1472 fprintf ( stderr, "%s: -c and -t cannot be used together.\n", 1605 fprintf ( stderr, "%s: -c and -t cannot be used together.\n",
@@ -1474,46 +1607,82 @@ IntNative main ( IntNative argc, Char *argv[] )
1474 exit ( 1 ); 1607 exit ( 1 );
1475 } 1608 }
1476 1609
1610 if (srcMode == SM_F2O && numFileNames == 0)
1611 srcMode = SM_I2O;
1612
1477 if (opMode != OM_Z) blockSize100k = 0; 1613 if (opMode != OM_Z) blockSize100k = 0;
1478 1614
1615 if (srcMode == SM_F2F) {
1616 signal (SIGINT, mySignalCatcher);
1617 signal (SIGTERM, mySignalCatcher);
1618# if BZ_UNIX
1619 signal (SIGHUP, mySignalCatcher);
1620# endif
1621 }
1622
1479 if (opMode == OM_Z) { 1623 if (opMode == OM_Z) {
1480 if (srcMode == SM_I2O) 1624 if (srcMode == SM_I2O) {
1481 compress ( NULL ); 1625 compress ( NULL );
1482 else 1626 } else {
1483 for (aa = argList; aa != NULL; aa = aa->link) 1627 decode = True;
1484 if (aa->name[0] != '-') { 1628 for (aa = argList; aa != NULL; aa = aa->link) {
1485 numFilesProcessed++; 1629 if (ISFLAG("--")) { decode = False; continue; }
1486 compress ( aa->name ); 1630 if (aa->name[0] == '-' && decode) continue;
1487 } 1631 numFilesProcessed++;
1488 } else 1632 compress ( aa->name );
1633 }
1634 }
1635 }
1636 else
1637
1489 if (opMode == OM_UNZ) { 1638 if (opMode == OM_UNZ) {
1490 if (srcMode == SM_I2O) 1639 if (srcMode == SM_I2O) {
1491 uncompress ( NULL ); 1640 uncompress ( NULL );
1492 else 1641 } else {
1493 for (aa = argList; aa != NULL; aa = aa->link) 1642 decode = True;
1494 if (aa->name[0] != '-') { 1643 for (aa = argList; aa != NULL; aa = aa->link) {
1495 numFilesProcessed++; 1644 if (ISFLAG("--")) { decode = False; continue; }
1496 uncompress ( aa->name ); 1645 if (aa->name[0] == '-' && decode) continue;
1497 } 1646 numFilesProcessed++;
1498 } else { 1647 uncompress ( aa->name );
1648 }
1649 }
1650 }
1651
1652 else {
1499 testFailsExist = False; 1653 testFailsExist = False;
1500 if (srcMode == SM_I2O) 1654 if (srcMode == SM_I2O) {
1501 testf ( NULL ); 1655 testf ( NULL );
1502 else 1656 } else {
1503 for (aa = argList; aa != NULL; aa = aa->link) 1657 decode = True;
1504 if (aa->name[0] != '-') { 1658 for (aa = argList; aa != NULL; aa = aa->link) {
1505 numFilesProcessed++; 1659 if (ISFLAG("--")) { decode = False; continue; }
1506 testf ( aa->name ); 1660 if (aa->name[0] == '-' && decode) continue;
1507 } 1661 numFilesProcessed++;
1508 if (testFailsExist) { 1662 testf ( aa->name );
1663 }
1664 }
1665 if (testFailsExist && noisy) {
1509 fprintf ( stderr, 1666 fprintf ( stderr,
1510 "\n" 1667 "\n"
1511 "You can use the `bzip2recover' program to *attempt* to recover\n" 1668 "You can use the `bzip2recover' program to attempt to recover\n"
1512 "data from undamaged sections of corrupted files.\n\n" 1669 "data from undamaged sections of corrupted files.\n\n"
1513 ); 1670 );
1514 exit(2); 1671 exit(2);
1515 } 1672 }
1516 } 1673 }
1674
1675 /* Free the argument list memory to mollify leak detectors
1676 (eg) Purify, Checker. Serves no other useful purpose.
1677 */
1678 aa = argList;
1679 while (aa != NULL) {
1680 Cell* aa2 = aa->link;
1681 if (aa->name) free(aa->name);
1682 free(aa);
1683 aa = aa2;
1684 }
1685
1517 return 0; 1686 return 0;
1518} 1687}
1519 1688