diff options
author | Julian Seward <jseward@acm.org> | 1999-09-04 22:13:13 +0200 |
---|---|---|
committer | Julian Seward <jseward@acm.org> | 1999-09-04 22:13:13 +0200 |
commit | f93cd82a9a7094ad90fd19bbc6ccf6f4627f8060 (patch) | |
tree | c95407df5665f5a7395683f07552f2b13f2e501f /bzip2.c | |
parent | 977101ad5f833f5c0a574bfeea408e5301a6b052 (diff) | |
download | bzip2-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.c | 545 |
1 files changed, 357 insertions, 188 deletions
@@ -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 | ||
255 | Int32 verbosity; | 278 | Int32 verbosity; |
256 | Bool keepInputFiles, smallMode; | 279 | Bool keepInputFiles, smallMode; |
257 | Bool forceOverwrite, testFailsExist; | 280 | Bool forceOverwrite, testFailsExist, noisy; |
258 | Int32 numFileNames, numFilesProcessed, blockSize100k; | 281 | Int32 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 | ||
276 | Int32 longestFileName; | 299 | Int32 longestFileName; |
277 | Char inName[FILE_NAME_LEN]; | 300 | Char inName [FILE_NAME_LEN]; |
278 | Char outName[FILE_NAME_LEN]; | 301 | Char outName[FILE_NAME_LEN]; |
302 | Char tmpName[FILE_NAME_LEN]; | ||
279 | Char *progName; | 303 | Char *progName; |
280 | Char progNameReally[FILE_NAME_LEN]; | 304 | Char progNameReally[FILE_NAME_LEN]; |
281 | FILE *outputHandleJustInCase; | 305 | FILE *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 | /*---------------------------------------------*/ |
577 | void cadvise ( void ) | 601 | void 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 | /*---------------------------------------------*/ |
590 | void showFileNames ( void ) | 615 | void 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 | /*---------------------------------------------*/ |
642 | void crcError () | 669 | void 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 | /*---------------------------------------------*/ |
668 | void ioError ( ) | 695 | void 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 ( ) | |||
680 | void mySignalCatcher ( IntNative n ) | 707 | void 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 | --*/ | ||
813 | Int32 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 | /*---------------------------------------------*/ | ||
782 | void copyDatePermissionsAndOwner ( Char *srcName, Char *dstName ) | 825 | void 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 | /*---------------------------------------------*/ | ||
824 | Bool 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 | /*---------------------------------------------*/ |
837 | Bool containsDubiousChars ( Char* name ) | 863 | Bool containsDubiousChars ( Char* name ) |
838 | { | 864 | { |
@@ -844,49 +870,94 @@ Bool containsDubiousChars ( Char* name ) | |||
844 | 870 | ||
845 | 871 | ||
846 | /*---------------------------------------------*/ | 872 | /*---------------------------------------------*/ |
847 | void compress ( Char *name ) | 873 | #define BZ_N_SUFFIX_PAIRS 4 |
874 | |||
875 | Char* zSuffix[BZ_N_SUFFIX_PAIRS] | ||
876 | = { ".bz2", ".bz", ".tbz2", ".tbz" }; | ||
877 | Char* unzSuffix[BZ_N_SUFFIX_PAIRS] | ||
878 | = { "", "", ".tar", ".tar" }; | ||
879 | |||
880 | Bool 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 | ||
889 | Bool 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 | /*---------------------------------------------*/ | ||
900 | void 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 | /*---------------------------------------------*/ |
968 | void uncompress ( Char *name ) | 1042 | void 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 | /*---------------------------------------------*/ |
1335 | void 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 | ||
1262 | typedef | 1359 | typedef |
@@ -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) | 1408 | void 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 | |||
1314 | IntNative main ( IntNative argc, Char *argv[] ) | 1437 | IntNative 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 | ||