00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 #define BZ_UNIX 1
00118
00119
00120
00121
00122
00123
00124 #define BZ_LCCWIN32 0
00125
00126 #if defined(_WIN32) && !defined(__CYGWIN32__)
00127 #undef BZ_LCCWIN32
00128 #define BZ_LCCWIN32 1
00129 #undef BZ_UNIX
00130 #define BZ_UNIX 0
00131 #endif
00132
00133
00134
00135
00136
00137
00138
00139 #include <stdio.h>
00140 #include <stdlib.h>
00141 #include <string.h>
00142 #include <time.h>
00143 #include <signal.h>
00144 #include <math.h>
00145 #include <errno.h>
00146 #include <ctype.h>
00147 #include "bzlib.h"
00148
00149 #define ERROR_IF_EOF(i) { if ((i) == EOF) ioError(); }
00150 #define ERROR_IF_NOT_ZERO(i) { if ((i) != 0) ioError(); }
00151 #define ERROR_IF_MINUS_ONE(i) { if ((i) == (-1)) ioError(); }
00152
00153
00154
00155
00156
00157
00158
00159 #if BZ_UNIX
00160 # include <sys/types.h>
00161 # include <utime.h>
00162 # include <unistd.h>
00163 # include <sys/stat.h>
00164 # include <sys/times.h>
00165
00166 # define PATH_SEP '/'
00167 # define MY_LSTAT lstat
00168 # define MY_S_IFREG S_ISREG
00169 # define MY_STAT stat
00170
00171 # define APPEND_FILESPEC(root, name) \
00172 root=snocString((root), (name))
00173
00174 # define APPEND_FLAG(root, name) \
00175 root=snocString((root), (name))
00176
00177 # define SET_BINARY_MODE(fd)
00178
00179 # ifdef __GNUC__
00180 # define NORETURN __attribute__ ((noreturn))
00181 # else
00182 # define NORETURN
00183 # endif
00184 # ifdef __DJGPP__
00185 # include <io.h>
00186 # include <fcntl.h>
00187 # undef MY_LSTAT
00188 # define MY_LSTAT stat
00189 # undef SET_BINARY_MODE
00190 # define SET_BINARY_MODE(fd) \
00191 do { \
00192 int retVal = setmode ( fileno ( fd ), \
00193 O_BINARY ); \
00194 ERROR_IF_MINUS_ONE ( retVal ); \
00195 } while ( 0 )
00196 # endif
00197 #endif
00198
00199
00200
00201 #if BZ_LCCWIN32
00202 # include <io.h>
00203 # include <fcntl.h>
00204 # include <sys\stat.h>
00205
00206 # define NORETURN
00207 # define PATH_SEP '\\'
00208 # define MY_LSTAT _stat
00209 # define MY_STAT _stat
00210 # define MY_S_IFREG(x) ((x) & _S_IFREG)
00211
00212 # define APPEND_FLAG(root, name) \
00213 root=snocString((root), (name))
00214
00215 # if 0
00216
00217 # define APPEND_FILESPEC(root, spec) \
00218 do { \
00219 if ((spec)[0] == '-') { \
00220 root = snocString((root), (spec)); \
00221 } else { \
00222 struct _finddata_t c_file; \
00223 long hFile; \
00224 hFile = _findfirst((spec), &c_file); \
00225 if ( hFile == -1L ) { \
00226 root = snocString ((root), (spec)); \
00227 } else { \
00228 int anInt = 0; \
00229 while ( anInt == 0 ) { \
00230 root = snocString((root), \
00231 &c_file.name[0]); \
00232 anInt = _findnext(hFile, &c_file); \
00233 } \
00234 } \
00235 } \
00236 } while ( 0 )
00237 # else
00238 # define APPEND_FILESPEC(root, name) \
00239 root = snocString ((root), (name))
00240 # endif
00241
00242 # define SET_BINARY_MODE(fd) \
00243 do { \
00244 int retVal = setmode ( fileno ( fd ), \
00245 O_BINARY ); \
00246 ERROR_IF_MINUS_ONE ( retVal ); \
00247 } while ( 0 )
00248
00249 #endif
00250
00251
00252
00253
00254
00255
00256
00257 typedef char Char;
00258 typedef unsigned char Bool;
00259 typedef unsigned char UChar;
00260 typedef int Int32;
00261 typedef unsigned int UInt32;
00262 typedef short Int16;
00263 typedef unsigned short UInt16;
00264
00265 #define True ((Bool)1)
00266 #define False ((Bool)0)
00267
00268
00269
00270
00271
00272 typedef int IntNative;
00273
00274
00275
00276
00277
00278
00279 Int32 verbosity;
00280 Bool keepInputFiles, smallMode;
00281 Bool forceOverwrite, testFailsExist, noisy;
00282 Int32 numFileNames, numFilesProcessed, blockSize100k;
00283
00284
00285
00286 #define SM_I2O 1
00287 #define SM_F2O 2
00288 #define SM_F2F 3
00289
00290
00291 #define OM_Z 1
00292 #define OM_UNZ 2
00293 #define OM_TEST 3
00294
00295 Int32 opMode;
00296 Int32 srcMode;
00297
00298 #define FILE_NAME_LEN 1034
00299
00300 Int32 longestFileName;
00301 Char inName [FILE_NAME_LEN];
00302 Char outName[FILE_NAME_LEN];
00303 Char tmpName[FILE_NAME_LEN];
00304 Char *progName;
00305 Char progNameReally[FILE_NAME_LEN];
00306 FILE *outputHandleJustInCase;
00307 Int32 workFactor;
00308
00309 void panic ( Char* ) NORETURN;
00310 void ioError ( void ) NORETURN;
00311 void outOfMemory ( void ) NORETURN;
00312 void blockOverrun ( void ) NORETURN;
00313 void badBlockHeader ( void ) NORETURN;
00314 void badBGLengths ( void ) NORETURN;
00315 void crcError ( void ) NORETURN;
00316 void bitStreamEOF ( void ) NORETURN;
00317 void cleanUpAndFail ( Int32 ) NORETURN;
00318 void compressedStreamEOF ( void ) NORETURN;
00319
00320 void copyFileName ( Char*, Char* );
00321 void* myMalloc ( Int32 );
00322
00323
00324
00325
00326
00327
00328
00329
00330 Bool myfeof ( FILE* f )
00331 {
00332 Int32 c = fgetc ( f );
00333 if (c == EOF) return True;
00334 ungetc ( c, f );
00335 return False;
00336 }
00337
00338
00339
00340 void compressStream ( FILE *stream, FILE *zStream )
00341 {
00342 BZFILE* bzf = NULL;
00343 UChar ibuf[5000];
00344 Int32 nIbuf;
00345 UInt32 nbytes_in, nbytes_out;
00346 Int32 bzerr, bzerr_dummy, ret;
00347
00348 SET_BINARY_MODE(stream);
00349 SET_BINARY_MODE(zStream);
00350
00351 if (ferror(stream)) goto errhandler_io;
00352 if (ferror(zStream)) goto errhandler_io;
00353
00354 bzf = bzWriteOpen ( &bzerr, zStream,
00355 blockSize100k, verbosity, workFactor );
00356 if (bzerr != BZ_OK) goto errhandler;
00357
00358 if (verbosity >= 2) fprintf ( stderr, "\n" );
00359
00360 while (True) {
00361
00362 if (myfeof(stream)) break;
00363 nIbuf = fread ( ibuf, sizeof(UChar), 5000, stream );
00364 if (ferror(stream)) goto errhandler_io;
00365 if (nIbuf > 0) bzWrite ( &bzerr, bzf, (void*)ibuf, nIbuf );
00366 if (bzerr != BZ_OK) goto errhandler;
00367
00368 }
00369
00370 bzWriteClose ( &bzerr, bzf, 0, &nbytes_in, &nbytes_out );
00371 if (bzerr != BZ_OK) goto errhandler;
00372
00373 if (ferror(zStream)) goto errhandler_io;
00374 ret = fflush ( zStream );
00375 if (ret == EOF) goto errhandler_io;
00376 if (zStream != stdout) {
00377 ret = fclose ( zStream );
00378 if (ret == EOF) goto errhandler_io;
00379 }
00380 if (ferror(stream)) goto errhandler_io;
00381 ret = fclose ( stream );
00382 if (ret == EOF) goto errhandler_io;
00383
00384 if (nbytes_in == 0) nbytes_in = 1;
00385
00386 if (verbosity >= 1)
00387 fprintf ( stderr, "%6.3f:1, %6.3f bits/byte, "
00388 "%5.2f%% saved, %d in, %d out.\n",
00389 (float)nbytes_in / (float)nbytes_out,
00390 (8.0 * (float)nbytes_out) / (float)nbytes_in,
00391 100.0 * (1.0 - (float)nbytes_out / (float)nbytes_in),
00392 nbytes_in,
00393 nbytes_out
00394 );
00395
00396 return;
00397
00398 errhandler:
00399 bzWriteClose ( &bzerr_dummy, bzf, 1, &nbytes_in, &nbytes_out );
00400 switch (bzerr) {
00401 case BZ_MEM_ERROR:
00402 outOfMemory ();
00403 case BZ_IO_ERROR:
00404 errhandler_io:
00405 ioError(); break;
00406 default:
00407 panic ( "compress:unexpected error" );
00408 }
00409
00410 panic ( "compress:end" );
00411
00412 }
00413
00414
00415
00416
00417 Bool uncompressStream ( FILE *zStream, FILE *stream )
00418 {
00419 BZFILE* bzf = NULL;
00420 Int32 bzerr, bzerr_dummy, ret, nread, streamNo, i;
00421 UChar obuf[5000];
00422 UChar unused[BZ_MAX_UNUSED];
00423 Int32 nUnused;
00424 UChar* unusedTmp;
00425
00426 nUnused = 0;
00427 streamNo = 0;
00428
00429 SET_BINARY_MODE(stream);
00430 SET_BINARY_MODE(zStream);
00431
00432 if (ferror(stream)) goto errhandler_io;
00433 if (ferror(zStream)) goto errhandler_io;
00434
00435 while (True) {
00436
00437 bzf = bzReadOpen (
00438 &bzerr, zStream, verbosity,
00439 (int)smallMode, unused, nUnused
00440 );
00441 if (bzf == NULL || bzerr != BZ_OK) goto errhandler;
00442 streamNo++;
00443
00444 while (bzerr == BZ_OK) {
00445 nread = bzRead ( &bzerr, bzf, obuf, 5000 );
00446 if (bzerr == BZ_DATA_ERROR_MAGIC) goto errhandler;
00447 if ((bzerr == BZ_OK || bzerr == BZ_STREAM_END) && nread > 0)
00448 fwrite ( obuf, sizeof(UChar), nread, stream );
00449 if (ferror(stream)) goto errhandler_io;
00450 }
00451 if (bzerr != BZ_STREAM_END) goto errhandler;
00452
00453 bzReadGetUnused ( &bzerr, bzf, (void**)(&unusedTmp), &nUnused );
00454 if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" );
00455
00456 for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i];
00457
00458 bzReadClose ( &bzerr, bzf );
00459 if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" );
00460
00461 if (nUnused == 0 && myfeof(zStream)) break;
00462
00463 }
00464
00465 if (ferror(zStream)) goto errhandler_io;
00466 ret = fclose ( zStream );
00467 if (ret == EOF) goto errhandler_io;
00468
00469 if (ferror(stream)) goto errhandler_io;
00470 ret = fflush ( stream );
00471 if (ret != 0) goto errhandler_io;
00472 if (stream != stdout) {
00473 ret = fclose ( stream );
00474 if (ret == EOF) goto errhandler_io;
00475 }
00476 if (verbosity >= 2) fprintf ( stderr, "\n " );
00477 return True;
00478
00479 errhandler:
00480 bzReadClose ( &bzerr_dummy, bzf );
00481 switch (bzerr) {
00482 case BZ_IO_ERROR:
00483 errhandler_io:
00484 ioError(); break;
00485 case BZ_DATA_ERROR:
00486 crcError();
00487 case BZ_MEM_ERROR:
00488 outOfMemory();
00489 case BZ_UNEXPECTED_EOF:
00490 compressedStreamEOF();
00491 case BZ_DATA_ERROR_MAGIC:
00492 if (streamNo == 1) {
00493 return False;
00494 } else {
00495 if (noisy)
00496 fprintf ( stderr,
00497 "\n%s: %s: trailing garbage after EOF ignored\n",
00498 progName, inName );
00499 return True;
00500 }
00501 default:
00502 panic ( "decompress:unexpected error" );
00503 }
00504
00505 panic ( "decompress:end" );
00506 return True;
00507 }
00508
00509
00510
00511 Bool testStream ( FILE *zStream )
00512 {
00513 BZFILE* bzf = NULL;
00514 Int32 bzerr, bzerr_dummy, ret, nread, streamNo, i;
00515 UChar obuf[5000];
00516 UChar unused[BZ_MAX_UNUSED];
00517 Int32 nUnused;
00518 UChar* unusedTmp;
00519
00520 nUnused = 0;
00521 streamNo = 0;
00522
00523 SET_BINARY_MODE(zStream);
00524 if (ferror(zStream)) goto errhandler_io;
00525
00526 while (True) {
00527
00528 bzf = bzReadOpen (
00529 &bzerr, zStream, verbosity,
00530 (int)smallMode, unused, nUnused
00531 );
00532 if (bzf == NULL || bzerr != BZ_OK) goto errhandler;
00533 streamNo++;
00534
00535 while (bzerr == BZ_OK) {
00536 nread = bzRead ( &bzerr, bzf, obuf, 5000 );
00537 if (bzerr == BZ_DATA_ERROR_MAGIC) goto errhandler;
00538 }
00539 if (bzerr != BZ_STREAM_END) goto errhandler;
00540
00541 bzReadGetUnused ( &bzerr, bzf, (void**)(&unusedTmp), &nUnused );
00542 if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" );
00543
00544 for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i];
00545
00546 bzReadClose ( &bzerr, bzf );
00547 if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" );
00548 if (nUnused == 0 && myfeof(zStream)) break;
00549
00550 }
00551
00552 if (ferror(zStream)) goto errhandler_io;
00553 ret = fclose ( zStream );
00554 if (ret == EOF) goto errhandler_io;
00555
00556 if (verbosity >= 2) fprintf ( stderr, "\n " );
00557 return True;
00558
00559 errhandler:
00560 bzReadClose ( &bzerr_dummy, bzf );
00561 if (verbosity == 0)
00562 fprintf ( stderr, "%s: %s: ", progName, inName );
00563 switch (bzerr) {
00564 case BZ_IO_ERROR:
00565 errhandler_io:
00566 ioError(); break;
00567 case BZ_DATA_ERROR:
00568 fprintf ( stderr,
00569 "data integrity (CRC) error in data\n" );
00570 return False;
00571 case BZ_MEM_ERROR:
00572 outOfMemory();
00573 case BZ_UNEXPECTED_EOF:
00574 fprintf ( stderr,
00575 "file ends unexpectedly\n" );
00576 return False;
00577 case BZ_DATA_ERROR_MAGIC:
00578 if (streamNo == 1) {
00579 fprintf ( stderr,
00580 "bad magic number (file not created by bzip2)\n" );
00581 return False;
00582 } else {
00583 if (noisy)
00584 fprintf ( stderr,
00585 "trailing garbage after EOF ignored\n" );
00586 return True;
00587 }
00588 default:
00589 panic ( "test:unexpected error" );
00590 }
00591
00592 panic ( "test:end" );
00593 return True;
00594 }
00595
00596
00597
00598
00599
00600
00601
00602 void cadvise ( void )
00603 {
00604 if (noisy)
00605 fprintf (
00606 stderr,
00607 "\nIt is possible that the compressed file(s) have become corrupted.\n"
00608 "You can use the -tvv option to test integrity of such files.\n\n"
00609 "You can use the `bzip2recover' program to *attempt* to recover\n"
00610 "data from undamaged sections of corrupted files.\n\n"
00611 );
00612 }
00613
00614
00615
00616 void showFileNames ( void )
00617 {
00618 if (noisy)
00619 fprintf (
00620 stderr,
00621 "\tInput file = %s, output file = %s\n",
00622 inName, outName
00623 );
00624 }
00625
00626
00627
00628 void cleanUpAndFail ( Int32 ec )
00629 {
00630 IntNative retVal;
00631
00632 if ( srcMode == SM_F2F && opMode != OM_TEST ) {
00633 if (noisy)
00634 fprintf ( stderr, "%s: Deleting output file %s, if it exists.\n",
00635 progName, outName );
00636 if (outputHandleJustInCase != NULL)
00637 fclose ( outputHandleJustInCase );
00638 retVal = remove ( outName );
00639 if (retVal != 0)
00640 fprintf ( stderr,
00641 "%s: WARNING: deletion of output file (apparently) failed.\n",
00642 progName );
00643 }
00644 if (noisy && numFileNames > 0 && numFilesProcessed < numFileNames) {
00645 fprintf ( stderr,
00646 "%s: WARNING: some files have not been processed:\n"
00647 "\t%d specified on command line, %d not processed yet.\n\n",
00648 progName, numFileNames,
00649 numFileNames - numFilesProcessed );
00650 }
00651 exit ( ec );
00652 }
00653
00654
00655
00656 void panic ( Char* s )
00657 {
00658 fprintf ( stderr,
00659 "\n%s: PANIC -- internal consistency error:\n"
00660 "\t%s\n"
00661 "\tThis is a BUG. Please report it to me at:\n"
00662 "\tjseward@acm.org\n",
00663 progName, s );
00664 showFileNames();
00665 cleanUpAndFail( 3 );
00666 }
00667
00668
00669
00670 void crcError ( void )
00671 {
00672 fprintf ( stderr,
00673 "\n%s: Data integrity error when decompressing.\n",
00674 progName );
00675 showFileNames();
00676 cadvise();
00677 cleanUpAndFail( 2 );
00678 }
00679
00680
00681
00682 void compressedStreamEOF ( void )
00683 {
00684 fprintf ( stderr,
00685 "\n%s: Compressed file ends unexpectedly;\n\t"
00686 "perhaps it is corrupted? *Possible* reason follows.\n",
00687 progName );
00688 perror ( progName );
00689 showFileNames();
00690 cadvise();
00691 cleanUpAndFail( 2 );
00692 }
00693
00694
00695
00696 void ioError ( void )
00697 {
00698 fprintf ( stderr,
00699 "\n%s: I/O or other error, bailing out. Possible reason follows.\n",
00700 progName );
00701 perror ( progName );
00702 showFileNames();
00703 cleanUpAndFail( 1 );
00704 }
00705
00706
00707
00708 #ifdef WIN32
00709 void __cdecl mySignalCatcher ( IntNative n )
00710 #else
00711 void mySignalCatcher ( IntNative n )
00712 #endif
00713 {
00714 fprintf ( stderr,
00715 "\n%s: Control-C or similar caught, quitting.\n",
00716 progName );
00717 cleanUpAndFail(1);
00718 }
00719
00720
00721
00722 #ifdef WIN32
00723 void __cdecl mySIGSEGVorSIGBUScatcher ( IntNative n )
00724 #else
00725 void mySIGSEGVorSIGBUScatcher ( IntNative n )
00726 #endif
00727 {
00728 if (opMode == OM_Z)
00729 fprintf ( stderr,
00730 "\n%s: Caught a SIGSEGV or SIGBUS whilst compressing,\n"
00731 "\twhich probably indicates a bug in bzip2. Please\n"
00732 "\treport it to me at: jseward@acm.org\n",
00733 progName );
00734 else
00735 fprintf ( stderr,
00736 "\n%s: Caught a SIGSEGV or SIGBUS whilst decompressing,\n"
00737 "\twhich probably indicates that the compressed data\n"
00738 "\tis corrupted.\n",
00739 progName );
00740
00741 showFileNames();
00742 if (opMode == OM_Z)
00743 cleanUpAndFail( 3 ); else
00744 { cadvise(); cleanUpAndFail( 2 ); }
00745 }
00746
00747
00748
00749 void outOfMemory ( void )
00750 {
00751 fprintf ( stderr,
00752 "\n%s: couldn't allocate enough memory\n",
00753 progName );
00754 showFileNames();
00755 cleanUpAndFail(1);
00756 }
00757
00758
00759
00760
00761
00762
00763
00764 void pad ( Char *s )
00765 {
00766 Int32 i;
00767 if ( (Int32)strlen(s) >= longestFileName ) return;
00768 for (i = 1; i <= longestFileName - (Int32)strlen(s); i++)
00769 fprintf ( stderr, " " );
00770 }
00771
00772
00773
00774 void copyFileName ( Char* to, Char* from )
00775 {
00776 if ( strlen(from) > FILE_NAME_LEN-10 ) {
00777 fprintf (
00778 stderr,
00779 "bzip2: file name\n`%s'\n"
00780 "is suspiciously (more than %d chars) long.\n"
00781 "Try using a reasonable file name instead. Sorry! :-)\n",
00782 from, FILE_NAME_LEN-10
00783 );
00784 exit(1);
00785 }
00786
00787 strncpy(to,from,FILE_NAME_LEN-10);
00788 to[FILE_NAME_LEN-10]='\0';
00789 }
00790
00791
00792
00793 Bool fileExists ( Char* name )
00794 {
00795 FILE *tmp = fopen ( name, "rb" );
00796 Bool exists = (tmp != NULL);
00797 if (tmp != NULL) fclose ( tmp );
00798 return exists;
00799 }
00800
00801
00802
00803
00804
00805
00806 Bool notAStandardFile ( Char* name )
00807 {
00808 IntNative i;
00809 struct MY_STAT statBuf;
00810
00811 i = MY_LSTAT ( name, &statBuf );
00812 if (i != 0) return True;
00813 if (MY_S_IFREG(statBuf.st_mode)) return False;
00814 return True;
00815 }
00816
00817
00818
00819
00820
00821
00822 Int32 countHardLinks ( Char* name )
00823 {
00824 IntNative i;
00825 struct MY_STAT statBuf;
00826
00827 i = MY_LSTAT ( name, &statBuf );
00828 if (i != 0) return 0;
00829 return (statBuf.st_nlink - 1);
00830 }
00831
00832
00833
00834 void copyDatePermissionsAndOwner ( Char *srcName, Char *dstName )
00835 {
00836 #if BZ_UNIX
00837 IntNative retVal;
00838 struct MY_STAT statBuf;
00839 struct utimbuf uTimBuf;
00840
00841 retVal = MY_LSTAT ( srcName, &statBuf );
00842 ERROR_IF_NOT_ZERO ( retVal );
00843 uTimBuf.actime = statBuf.st_atime;
00844 uTimBuf.modtime = statBuf.st_mtime;
00845
00846 retVal = chmod ( dstName, statBuf.st_mode );
00847 ERROR_IF_NOT_ZERO ( retVal );
00848
00849 retVal = utime ( dstName, &uTimBuf );
00850 ERROR_IF_NOT_ZERO ( retVal );
00851
00852 retVal = chown ( dstName, statBuf.st_uid, statBuf.st_gid );
00853
00854
00855
00856 #endif
00857 }
00858
00859
00860
00861 void setInterimPermissions ( Char *dstName )
00862 {
00863 #if BZ_UNIX
00864 IntNative retVal;
00865 retVal = chmod ( dstName, S_IRUSR | S_IWUSR );
00866 ERROR_IF_NOT_ZERO ( retVal );
00867 #endif
00868 }
00869
00870
00871
00872 Bool containsDubiousChars ( Char* name )
00873 {
00874 Bool cdc = False;
00875 for (; *name != '\0'; name++)
00876 if (*name == '?' || *name == '*') cdc = True;
00877 return cdc;
00878 }
00879
00880
00881
00882 #define BZ_N_SUFFIX_PAIRS 4
00883
00884 Char* zSuffix[BZ_N_SUFFIX_PAIRS]
00885 = { ".bz2", ".bz", ".tbz2", ".tbz" };
00886 Char* unzSuffix[BZ_N_SUFFIX_PAIRS]
00887 = { "", "", ".tar", ".tar" };
00888
00889 Bool hasSuffix ( Char* s, Char* suffix )
00890 {
00891 Int32 ns = strlen(s);
00892 Int32 nx = strlen(suffix);
00893 if (ns < nx) return False;
00894 if (strcmp(s + ns - nx, suffix) == 0) return True;
00895 return False;
00896 }
00897
00898 Bool mapSuffix ( Char* name,
00899 Char* oldSuffix, Char* newSuffix )
00900 {
00901 if (!hasSuffix(name,oldSuffix)) return False;
00902 name[strlen(name)-strlen(oldSuffix)] = 0;
00903 strcat ( name, newSuffix );
00904 return True;
00905 }
00906
00907
00908
00909 void compress ( Char *name )
00910 {
00911 FILE *inStr;
00912 FILE *outStr;
00913 Int32 n, i;
00914 if (name == NULL && srcMode != SM_I2O)
00915 panic ( "compress: bad modes\n" );
00916
00917 switch (srcMode) {
00918 case SM_I2O:
00919 copyFileName ( inName, "(stdin)" );
00920 copyFileName ( outName, "(stdout)" );
00921 break;
00922 case SM_F2F:
00923 copyFileName ( inName, name );
00924 copyFileName ( outName, name );
00925 strcat ( outName, ".bz2" );
00926 break;
00927 case SM_F2O:
00928 copyFileName ( inName, name );
00929 copyFileName ( outName, "(stdout)" );
00930 break;
00931 }
00932
00933 if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
00934 if (noisy)
00935 fprintf ( stderr, "%s: There are no files matching `%s'.\n",
00936 progName, inName );
00937 return;
00938 }
00939 if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
00940 fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
00941 progName, inName, strerror(errno) );
00942 return;
00943 }
00944 for (i = 0; i < BZ_N_SUFFIX_PAIRS; i++) {
00945 if (hasSuffix(inName, zSuffix[i])) {
00946 if (noisy)
00947 fprintf ( stderr,
00948 "%s: Input file %s already has %s suffix.\n",
00949 progName, inName, zSuffix[i] );
00950 return;
00951 }
00952 }
00953 if ( srcMode == SM_F2F && !forceOverwrite && notAStandardFile ( inName )) {
00954 if (noisy)
00955 fprintf ( stderr, "%s: Input file %s is not a normal file.\n",
00956 progName, inName );
00957 return;
00958 }
00959 if ( srcMode == SM_F2F && !forceOverwrite && fileExists ( outName ) ) {
00960 fprintf ( stderr, "%s: Output file %s already exists.\n",
00961 progName, outName );
00962 return;
00963 }
00964 if ( srcMode == SM_F2F && !forceOverwrite &&
00965 (n=countHardLinks ( inName )) > 0) {
00966 fprintf ( stderr, "%s: Input file %s has %d other link%s.\n",
00967 progName, inName, n, n > 1 ? "s" : "" );
00968 return;
00969 }
00970
00971 switch ( srcMode ) {
00972
00973 case SM_I2O:
00974 inStr = stdin;
00975 outStr = stdout;
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986 break;
00987
00988 case SM_F2O:
00989 inStr = fopen ( inName, "rb" );
00990 outStr = stdout;
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002 if ( inStr == NULL ) {
01003 fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
01004 progName, inName, strerror(errno) );
01005 return;
01006 };
01007 break;
01008
01009 case SM_F2F:
01010 inStr = fopen ( inName, "rb" );
01011 outStr = fopen ( outName, "wb" );
01012 if ( outStr == NULL) {
01013 fprintf ( stderr, "%s: Can't create output file %s: %s.\n",
01014 progName, outName, strerror(errno) );
01015 if ( inStr != NULL ) fclose ( inStr );
01016 return;
01017 }
01018 if ( inStr == NULL ) {
01019 fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
01020 progName, inName, strerror(errno) );
01021 if ( outStr != NULL ) fclose ( outStr );
01022 return;
01023 };
01024 setInterimPermissions ( outName );
01025 break;
01026
01027 default:
01028 panic ( "compress: bad srcMode" );
01029 break;
01030 }
01031
01032 if (verbosity >= 1) {
01033 fprintf ( stderr, " %s: ", inName );
01034 pad ( inName );
01035 fflush ( stderr );
01036 }
01037
01038
01039 outputHandleJustInCase = outStr;
01040 compressStream ( inStr, outStr );
01041 outputHandleJustInCase = NULL;
01042
01043
01044 if ( srcMode == SM_F2F ) {
01045 copyDatePermissionsAndOwner ( inName, outName );
01046 if ( !keepInputFiles ) {
01047 IntNative retVal = remove ( inName );
01048 ERROR_IF_NOT_ZERO ( retVal );
01049 }
01050 }
01051 }
01052
01053
01054
01055 void uncompress ( Char *name )
01056 {
01057 FILE *inStr;
01058 FILE *outStr;
01059 Int32 n, i;
01060 Bool magicNumberOK;
01061 Bool cantGuess;
01062
01063 if (name == NULL && srcMode != SM_I2O)
01064 panic ( "uncompress: bad modes\n" );
01065
01066 cantGuess = False;
01067 switch (srcMode) {
01068 case SM_I2O:
01069 copyFileName ( inName, "(stdin)" );
01070 copyFileName ( outName, "(stdout)" );
01071 break;
01072 case SM_F2F:
01073 copyFileName ( inName, name );
01074 copyFileName ( outName, name );
01075 for (i = 0; i < BZ_N_SUFFIX_PAIRS; i++)
01076 if (mapSuffix(outName,zSuffix[i],unzSuffix[i]))
01077 goto zzz;
01078 cantGuess = True;
01079 strcat ( outName, ".out" );
01080 break;
01081 case SM_F2O:
01082 copyFileName ( inName, name );
01083 copyFileName ( outName, "(stdout)" );
01084 break;
01085 }
01086
01087 zzz:
01088 if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
01089 if (noisy)
01090 fprintf ( stderr, "%s: There are no files matching `%s'.\n",
01091 progName, inName );
01092 return;
01093 }
01094 if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
01095 fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
01096 progName, inName, strerror(errno) );
01097 return;
01098 }
01099 if ( srcMode == SM_F2F && !forceOverwrite && notAStandardFile ( inName )) {
01100 if (noisy)
01101 fprintf ( stderr, "%s: Input file %s is not a normal file.\n",
01102 progName, inName );
01103 return;
01104 }
01105 if ( cantGuess ) {
01106 if (noisy)
01107 fprintf ( stderr,
01108 "%s: Can't guess original name for %s -- using %s\n",
01109 progName, inName, outName );
01110
01111 }
01112 if ( srcMode == SM_F2F && !forceOverwrite && fileExists ( outName ) ) {
01113 fprintf ( stderr, "%s: Output file %s already exists.\n",
01114 progName, outName );
01115 return;
01116 }
01117 if ( srcMode == SM_F2F && !forceOverwrite &&
01118 (n=countHardLinks ( inName ) ) > 0) {
01119 fprintf ( stderr, "%s: Input file %s has %d other link%s.\n",
01120 progName, inName, n, n > 1 ? "s" : "" );
01121 return;
01122 }
01123
01124 switch ( srcMode ) {
01125
01126 case SM_I2O:
01127 inStr = stdin;
01128 outStr = stdout;
01129 if ( isatty ( fileno ( stdin ) ) ) {
01130 fprintf ( stderr,
01131 "%s: I won't read compressed data from a terminal.\n",
01132 progName );
01133 fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
01134 progName, progName );
01135 return;
01136 };
01137 break;
01138
01139 case SM_F2O:
01140 inStr = fopen ( inName, "rb" );
01141 outStr = stdout;
01142 if ( inStr == NULL ) {
01143 fprintf ( stderr, "%s: Can't open input file %s:%s.\n",
01144 progName, inName, strerror(errno) );
01145 if ( inStr != NULL ) fclose ( inStr );
01146 return;
01147 };
01148 break;
01149
01150 case SM_F2F:
01151 inStr = fopen ( inName, "rb" );
01152 outStr = fopen ( outName, "wb" );
01153 if ( outStr == NULL) {
01154 fprintf ( stderr, "%s: Can't create output file %s: %s.\n",
01155 progName, outName, strerror(errno) );
01156 if ( inStr != NULL ) fclose ( inStr );
01157 return;
01158 }
01159 if ( inStr == NULL ) {
01160 fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
01161 progName, inName, strerror(errno) );
01162 if ( outStr != NULL ) fclose ( outStr );
01163 return;
01164 };
01165 setInterimPermissions ( outName );
01166 break;
01167
01168 default:
01169 panic ( "uncompress: bad srcMode" );
01170 break;
01171 }
01172
01173 if (verbosity >= 1) {
01174 fprintf ( stderr, " %s: ", inName );
01175 pad ( inName );
01176 fflush ( stderr );
01177 }
01178
01179
01180 outputHandleJustInCase = outStr;
01181 magicNumberOK = uncompressStream ( inStr, outStr );
01182 outputHandleJustInCase = NULL;
01183
01184
01185 if ( magicNumberOK ) {
01186 if ( srcMode == SM_F2F ) {
01187 copyDatePermissionsAndOwner ( inName, outName );
01188 if ( !keepInputFiles ) {
01189 IntNative retVal = remove ( inName );
01190 ERROR_IF_NOT_ZERO ( retVal );
01191 }
01192 }
01193 } else {
01194 if ( srcMode == SM_F2F ) {
01195 IntNative retVal = remove ( outName );
01196 ERROR_IF_NOT_ZERO ( retVal );
01197 }
01198 }
01199
01200 if ( magicNumberOK ) {
01201 if (verbosity >= 1)
01202 fprintf ( stderr, "done\n" );
01203 } else {
01204 if (verbosity >= 1)
01205 fprintf ( stderr, "not a bzip2 file.\n" ); else
01206 fprintf ( stderr,
01207 "%s: %s is not a bzip2 file.\n",
01208 progName, inName );
01209 }
01210
01211 }
01212
01213
01214
01215 void testf ( Char *name )
01216 {
01217 FILE *inStr;
01218 Bool allOK;
01219
01220 if (name == NULL && srcMode != SM_I2O)
01221 panic ( "testf: bad modes\n" );
01222
01223 copyFileName ( outName, "(none)" );
01224 switch (srcMode) {
01225 case SM_I2O: copyFileName ( inName, "(stdin)" ); break;
01226 case SM_F2F: copyFileName ( inName, name ); break;
01227 case SM_F2O: copyFileName ( inName, name ); break;
01228 }
01229
01230 if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
01231 if (noisy)
01232 fprintf ( stderr, "%s: There are no files matching `%s'.\n",
01233 progName, inName );
01234 return;
01235 }
01236 if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
01237 fprintf ( stderr, "%s: Can't open input %s: %s.\n",
01238 progName, inName, strerror(errno) );
01239 return;
01240 }
01241
01242 switch ( srcMode ) {
01243
01244 case SM_I2O:
01245 if ( isatty ( fileno ( stdin ) ) ) {
01246 fprintf ( stderr,
01247 "%s: I won't read compressed data from a terminal.\n",
01248 progName );
01249 fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
01250 progName, progName );
01251 return;
01252 };
01253 inStr = stdin;
01254 break;
01255
01256 case SM_F2O: case SM_F2F:
01257 inStr = fopen ( inName, "rb" );
01258 if ( inStr == NULL ) {
01259 fprintf ( stderr, "%s: Can't open input file %s:%s.\n",
01260 progName, inName, strerror(errno) );
01261 return;
01262 };
01263 break;
01264
01265 default:
01266 panic ( "testf: bad srcMode" );
01267 break;
01268 }
01269
01270 if (verbosity >= 1) {
01271 fprintf ( stderr, " %s: ", inName );
01272 pad ( inName );
01273 fflush ( stderr );
01274 }
01275
01276
01277 allOK = testStream ( inStr );
01278
01279 if (allOK && verbosity >= 1) fprintf ( stderr, "ok\n" );
01280 if (!allOK) testFailsExist = True;
01281 }
01282
01283
01284
01285 void license ( void )
01286 {
01287 fprintf ( stderr,
01288
01289 "bzip2, a block-sorting file compressor. "
01290 "Version 0.9.5c, 9-Aug-99.\n"
01291 " \n"
01292 " Copyright (C) 1996, 1997, 1998, 1999 by Julian Seward.\n"
01293 " \n"
01294 " This program is free software; you can redistribute it and/or modify\n"
01295 " it under the terms set out in the LICENSE file, which is included\n"
01296 " in the bzip2-0.9.5 source distribution.\n"
01297 " \n"
01298 " This program is distributed in the hope that it will be useful,\n"
01299 " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
01300 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
01301 " LICENSE file for more details.\n"
01302 " \n"
01303 );
01304 }
01305
01306
01307
01308 void usage ( Char *fullProgName )
01309 {
01310 fprintf (
01311 stderr,
01312 "bzip2, a block-sorting file compressor. "
01313 "Version 0.9.5c, 9-Aug-99.\n"
01314 "\n usage: %s [flags and input files in any order]\n"
01315 "\n"
01316 " -h --help print this message\n"
01317 " -d --decompress force decompression\n"
01318 " -z --compress force compression\n"
01319 " -k --keep keep (don't delete) input files\n"
01320 " -f --force overwrite existing output filess\n"
01321 " -t --test test compressed file integrity\n"
01322 " -c --stdout output to standard out\n"
01323 " -q --quiet suppress noncritical error messages\n"
01324 " -v --verbose be verbose (a 2nd -v gives more)\n"
01325 " -L --license display software version & license\n"
01326 " -V --version display software version & license\n"
01327 " -s --small use less memory (at most 2500k)\n"
01328 " -1 .. -9 set block size to 100k .. 900k\n"
01329 "\n"
01330 " If invoked as `bzip2', default action is to compress.\n"
01331 " as `bunzip2', default action is to decompress.\n"
01332 " as `bzcat', default action is to decompress to stdout.\n"
01333 "\n"
01334 " If no file names are given, bzip2 compresses or decompresses\n"
01335 " from standard input to standard output. You can combine\n"
01336 " short flags, so `-v -4' means the same as -v4 or -4v, &c.\n"
01337 #if BZ_UNIX
01338 "\n"
01339 #endif
01340 ,
01341
01342 fullProgName
01343 );
01344 }
01345
01346
01347
01348 void redundant ( Char* flag )
01349 {
01350 fprintf (
01351 stderr,
01352 "%s: %s is redundant in versions 0.9.5 and above\n",
01353 progName, flag );
01354 }
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372 typedef
01373 struct zzzz {
01374 Char *name;
01375 struct zzzz *link;
01376 }
01377 Cell;
01378
01379
01380
01381 void *myMalloc ( Int32 n )
01382 {
01383 void* p;
01384
01385 p = malloc ( (size_t)n );
01386 if (p == NULL) outOfMemory ();
01387 return p;
01388 }
01389
01390
01391
01392 Cell *mkCell ( void )
01393 {
01394 Cell *c;
01395
01396 c = (Cell*) myMalloc ( sizeof ( Cell ) );
01397 c->name = NULL;
01398 c->link = NULL;
01399 return c;
01400 }
01401
01402
01403
01404 Cell *snocString ( Cell *root, Char *name )
01405 {
01406 if (root == NULL) {
01407 Cell *tmp = mkCell();
01408 tmp->name = (Char*) myMalloc ( 5 + strlen(name) );
01409 strcpy ( tmp->name, name );
01410 return tmp;
01411 } else {
01412 Cell *tmp = root;
01413 while (tmp->link != NULL) tmp = tmp->link;
01414 tmp->link = snocString ( tmp->link, name );
01415 return root;
01416 }
01417 }
01418
01419
01420
01421 void addFlagsFromEnvVar ( Cell** argList, Char* varName )
01422 {
01423 Int32 i, j, k;
01424 Char *envbase, *p;
01425
01426 envbase = getenv(varName);
01427 if (envbase != NULL) {
01428 p = envbase;
01429 i = 0;
01430 while (True) {
01431 if (p[i] == 0) break;
01432 p += i;
01433 i = 0;
01434 while (isspace((Int32)(p[0]))) p++;
01435 while (p[i] != 0 && !isspace((Int32)(p[i]))) i++;
01436 if (i > 0) {
01437 k = i; if (k > FILE_NAME_LEN-10) k = FILE_NAME_LEN-10;
01438 for (j = 0; j < k; j++) tmpName[j] = p[j];
01439 tmpName[k] = 0;
01440 APPEND_FLAG(*argList, tmpName);
01441 }
01442 }
01443 }
01444 }
01445
01446
01447
01448 #define ISFLAG(s) (strcmp(aa->name, (s))==0)
01449
01450 #ifdef WIN32
01451 IntNative __cdecl main ( IntNative argc, Char *argv[] )
01452 #else
01453 IntNative main ( IntNative argc, Char *argv[] )
01454 #endif
01455 {
01456 Int32 i, j;
01457 Char *tmp;
01458 Cell *argList;
01459 Cell *aa;
01460 Bool decode;
01461 clock_t c1,c2;
01462
01463
01464 if (sizeof(Int32) != 4 || sizeof(UInt32) != 4 ||
01465 sizeof(Int16) != 2 || sizeof(UInt16) != 2 ||
01466 sizeof(Char) != 1 || sizeof(UChar) != 1) {
01467 fprintf ( stderr,
01468 "bzip2: I'm not configured correctly for this platform!\n"
01469 "\tI require Int32, Int16 and Char to have sizes\n"
01470 "\tof 4, 2 and 1 bytes to run properly, and they don't.\n"
01471 "\tProbably you can fix this by defining them correctly,\n"
01472 "\tand recompiling. Bye!\n" );
01473 exit(3);
01474 }
01475
01476
01477
01478 outputHandleJustInCase = NULL;
01479 smallMode = False;
01480 keepInputFiles = False;
01481 forceOverwrite = False;
01482 noisy = True;
01483 verbosity = 0;
01484 blockSize100k = 9;
01485 testFailsExist = False;
01486 numFileNames = 0;
01487 numFilesProcessed = 0;
01488 workFactor = 30;
01489 i = j = 0;
01490
01491
01492 signal (SIGSEGV, mySIGSEGVorSIGBUScatcher);
01493 #if BZ_UNIX
01494 #ifndef __DJGPP__
01495 signal (SIGBUS, mySIGSEGVorSIGBUScatcher);
01496 #endif
01497 #endif
01498
01499 copyFileName ( inName, "(none)" );
01500 copyFileName ( outName, "(none)" );
01501
01502 copyFileName ( progNameReally, argv[0] );
01503 progName = &progNameReally[0];
01504 for (tmp = &progNameReally[0]; *tmp != '\0'; tmp++)
01505 if (*tmp == PATH_SEP) progName = tmp + 1;
01506
01507
01508
01509
01510
01511 argList = NULL;
01512 addFlagsFromEnvVar ( &argList, "BZIP2" );
01513 addFlagsFromEnvVar ( &argList, "BZIP" );
01514 for (i = 1; i <= argc-1; i++)
01515 APPEND_FILESPEC(argList, argv[i]);
01516
01517
01518
01519 longestFileName = 7;
01520 numFileNames = 0;
01521 decode = True;
01522 for (aa = argList; aa != NULL; aa = aa->link) {
01523 if (ISFLAG("--")) { decode = False; continue; }
01524 if (aa->name[0] == '-' && decode) continue;
01525 numFileNames++;
01526 if (longestFileName < (Int32)strlen(aa->name) )
01527 longestFileName = (Int32)strlen(aa->name);
01528 }
01529
01530
01531
01532 if (numFileNames == 0)
01533 srcMode = SM_I2O; else srcMode = SM_F2F;
01534
01535
01536
01537
01538 opMode = OM_Z;
01539
01540 if ( (strstr ( progName, "unzip" ) != 0) ||
01541 (strstr ( progName, "UNZIP" ) != 0) )
01542 opMode = OM_UNZ;
01543
01544 if ( (strstr ( progName, "z2cat" ) != 0) ||
01545 (strstr ( progName, "Z2CAT" ) != 0) ||
01546 (strstr ( progName, "zcat" ) != 0) ||
01547 (strstr ( progName, "ZCAT" ) != 0) ) {
01548 opMode = OM_UNZ;
01549 srcMode = (numFileNames == 0) ? SM_I2O : SM_F2O;
01550 }
01551
01552
01553
01554 for (aa = argList; aa != NULL; aa = aa->link) {
01555 if (ISFLAG("--")) break;
01556 if (aa->name[0] == '-' && aa->name[1] != '-') {
01557 for (j = 1; aa->name[j] != '\0'; j++) {
01558 switch (aa->name[j]) {
01559 case 'c': srcMode = SM_F2O; break;
01560 case 'd': opMode = OM_UNZ; break;
01561 case 'z': opMode = OM_Z; break;
01562 case 'f': forceOverwrite = True; break;
01563 case 't': opMode = OM_TEST; break;
01564 case 'k': keepInputFiles = True; break;
01565 case 's': smallMode = True; break;
01566 case 'q': noisy = False; break;
01567 case '1': blockSize100k = 1; break;
01568 case '2': blockSize100k = 2; break;
01569 case '3': blockSize100k = 3; break;
01570 case '4': blockSize100k = 4; break;
01571 case '5': blockSize100k = 5; break;
01572 case '6': blockSize100k = 6; break;
01573 case '7': blockSize100k = 7; break;
01574 case '8': blockSize100k = 8; break;
01575 case '9': blockSize100k = 9; break;
01576 case 'V':
01577 case 'L': license(); break;
01578 case 'v': verbosity++; break;
01579 case 'h': usage ( progName );
01580 exit ( 0 );
01581 break;
01582 default: fprintf ( stderr, "%s: Bad flag `%s'\n",
01583 progName, aa->name );
01584 usage ( progName );
01585 exit ( 1 );
01586 break;
01587 }
01588 }
01589 }
01590 }
01591
01592
01593 for (aa = argList; aa != NULL; aa = aa->link) {
01594 if (ISFLAG("--")) break;
01595 if (ISFLAG("--stdout")) srcMode = SM_F2O; else
01596 if (ISFLAG("--decompress")) opMode = OM_UNZ; else
01597 if (ISFLAG("--compress")) opMode = OM_Z; else
01598 if (ISFLAG("--force")) forceOverwrite = True; else
01599 if (ISFLAG("--test")) opMode = OM_TEST; else
01600 if (ISFLAG("--keep")) keepInputFiles = True; else
01601 if (ISFLAG("--small")) smallMode = True; else
01602 if (ISFLAG("--quiet")) noisy = False; else
01603 if (ISFLAG("--version")) license(); else
01604 if (ISFLAG("--license")) license(); else
01605 if (ISFLAG("--exponential")) workFactor = 1; else
01606 if (ISFLAG("--repetitive-best")) redundant(aa->name); else
01607 if (ISFLAG("--repetitive-fast")) redundant(aa->name); else
01608 if (ISFLAG("--verbose")) verbosity++; else
01609 if (ISFLAG("--help")) { usage ( progName ); exit ( 0 ); }
01610 else
01611 if (strncmp ( aa->name, "--", 2) == 0) {
01612 fprintf ( stderr, "%s: Bad flag `%s'\n", progName, aa->name );
01613 usage ( progName );
01614 exit ( 1 );
01615 }
01616 }
01617
01618 if (verbosity > 4) verbosity = 4;
01619 if (opMode == OM_Z && smallMode && blockSize100k > 2)
01620 blockSize100k = 2;
01621
01622 if (opMode == OM_TEST && srcMode == SM_F2O) {
01623 fprintf ( stderr, "%s: -c and -t cannot be used together.\n",
01624 progName );
01625 exit ( 1 );
01626 }
01627
01628 if (srcMode == SM_F2O && numFileNames == 0)
01629 srcMode = SM_I2O;
01630
01631 if (opMode != OM_Z) blockSize100k = 0;
01632
01633 if (srcMode == SM_F2F) {
01634 signal (SIGINT, mySignalCatcher);
01635 signal (SIGTERM, mySignalCatcher);
01636 # if BZ_UNIX
01637 signal (SIGHUP, mySignalCatcher);
01638 # endif
01639 }
01640
01641 c1=clock();
01642
01643 if (opMode == OM_Z) {
01644 if (srcMode == SM_I2O) {
01645 compress ( NULL );
01646 } else {
01647 decode = True;
01648 for (aa = argList; aa != NULL; aa = aa->link) {
01649 if (ISFLAG("--")) { decode = False; continue; }
01650 if (aa->name[0] == '-' && decode) continue;
01651 numFilesProcessed++;
01652 compress ( aa->name );
01653 }
01654 }
01655 }
01656 else
01657
01658 if (opMode == OM_UNZ) {
01659 if (srcMode == SM_I2O) {
01660 uncompress ( NULL );
01661 } else {
01662 decode = True;
01663 for (aa = argList; aa != NULL; aa = aa->link) {
01664 if (ISFLAG("--")) { decode = False; continue; }
01665 if (aa->name[0] == '-' && decode) continue;
01666 numFilesProcessed++;
01667 uncompress ( aa->name );
01668 }
01669 }
01670 }
01671
01672 else {
01673 testFailsExist = False;
01674 if (srcMode == SM_I2O) {
01675 testf ( NULL );
01676 } else {
01677 decode = True;
01678 for (aa = argList; aa != NULL; aa = aa->link) {
01679 if (ISFLAG("--")) { decode = False; continue; }
01680 if (aa->name[0] == '-' && decode) continue;
01681 numFilesProcessed++;
01682 testf ( aa->name );
01683 }
01684 }
01685 if (testFailsExist && noisy) {
01686 fprintf ( stderr,
01687 "\n"
01688 "You can use the `bzip2recover' program to attempt to recover\n"
01689 "data from undamaged sections of corrupted files.\n\n"
01690 );
01691 exit(2);
01692 }
01693 }
01694
01695
01696
01697
01698 aa = argList;
01699 while (aa != NULL) {
01700 Cell* aa2 = aa->link;
01701 if (aa->name) free(aa->name);
01702 free(aa);
01703 aa = aa2;
01704 }
01705
01706 c2=clock();
01707 printf("Time: %f\n",((float)c2-(float)c1)/(float)CLOCKS_PER_SEC);
01708
01709 return 0;
01710 }
01711
01712
01713
01714
01715