2
/*-----------------------------------------------------------*/
3
/*--- A block-sorting, lossless compressor bzip2.c ---*/
4
/*-----------------------------------------------------------*/
6
/* ------------------------------------------------------------------
7
This file is part of bzip2/libbzip2, a program and library for
8
lossless, block-sorting data compression.
10
bzip2/libbzip2 version 1.0.6 of 6 September 2010
11
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
13
Please read the WARNING, DISCLAIMER and PATENTS sections in the
16
This program is released under the terms of the license contained
18
------------------------------------------------------------------ */
21
/* Place a 1 beside your platform, and 0 elsewhere.
23
Also works on 64-bit Unix boxes.
29
Win32, as seen by Jacob Navia's excellent
30
port of (Chris Fraser & David Hanson)'s excellent
31
lcc compiler. Or with MS Visual C.
32
This is selected automatically if compiled by a compiler which
33
defines _WIN32, not including the Cygwin GCC.
37
#if defined(_WIN32) && !defined(__CYGWIN__)
45
/*---------------------------------------------*/
47
Some stuff for all platforms.
59
#define ERROR_IF_EOF(i) { if ((i) == EOF) ioError(); }
60
#define ERROR_IF_NOT_ZERO(i) { if ((i) != 0) ioError(); }
61
#define ERROR_IF_MINUS_ONE(i) { if ((i) == (-1)) ioError(); }
64
/*---------------------------------------------*/
66
Platform-specific stuff.
71
# include <sys/types.h>
74
# include <sys/stat.h>
75
# include <sys/times.h>
78
# define MY_LSTAT lstat
80
# define MY_S_ISREG S_ISREG
81
# define MY_S_ISDIR S_ISDIR
83
# define APPEND_FILESPEC(root, name) \
84
root=snocString((root), (name))
86
# define APPEND_FLAG(root, name) \
87
root=snocString((root), (name))
89
# define SET_BINARY_MODE(fd) /**/
92
# define NORETURN __attribute__ ((noreturn))
94
# define NORETURN /**/
102
# define MY_LSTAT stat
103
# define MY_STAT stat
104
# undef SET_BINARY_MODE
105
# define SET_BINARY_MODE(fd) \
107
int retVal = setmode ( fileno ( fd ), \
109
ERROR_IF_MINUS_ONE ( retVal ); \
116
# undef SET_BINARY_MODE
117
# define SET_BINARY_MODE(fd) \
119
int retVal = setmode ( fileno ( fd ), \
121
ERROR_IF_MINUS_ONE ( retVal ); \
131
# include <sys\stat.h>
133
# define NORETURN /**/
134
# define PATH_SEP '\\'
135
# define MY_LSTAT _stat
136
# define MY_STAT _stat
137
# define MY_S_ISREG(x) ((x) & _S_IFREG)
138
# define MY_S_ISDIR(x) ((x) & _S_IFDIR)
140
# define APPEND_FLAG(root, name) \
141
root=snocString((root), (name))
143
# define APPEND_FILESPEC(root, name) \
144
root = snocString ((root), (name))
146
# define SET_BINARY_MODE(fd) \
148
int retVal = setmode ( fileno ( fd ), \
150
ERROR_IF_MINUS_ONE ( retVal ); \
153
#endif /* BZ_LCCWIN32 */
156
/*---------------------------------------------*/
158
Some more stuff for all platforms :-)
162
typedef unsigned char Bool;
163
typedef unsigned char UChar;
165
typedef unsigned int UInt32;
167
typedef unsigned short UInt16;
169
#define True ((Bool)1)
170
#define False ((Bool)0)
173
IntNative is your platform's `native' int size.
174
Only here to avoid probs with 64-bit platforms.
176
typedef int IntNative;
179
/*---------------------------------------------------*/
180
/*--- Misc (file handling) data decls ---*/
181
/*---------------------------------------------------*/
184
Bool keepInputFiles, smallMode, deleteOutputOnInterrupt;
185
Bool forceOverwrite, testFailsExist, unzFailsExist, noisy;
186
Int32 numFileNames, numFilesProcessed, blockSize100k;
189
/*-- source modes; F==file, I==stdin, O==stdout --*/
194
/*-- operation modes --*/
202
#define FILE_NAME_LEN 1034
204
Int32 longestFileName;
205
Char inName [FILE_NAME_LEN];
206
Char outName[FILE_NAME_LEN];
207
Char tmpName[FILE_NAME_LEN];
209
Char progNameReally[FILE_NAME_LEN];
210
FILE *outputHandleJustInCase;
213
static void panic ( const Char* ) NORETURN;
214
static void ioError ( void ) NORETURN;
215
static void outOfMemory ( void ) NORETURN;
216
static void configError ( void ) NORETURN;
217
static void crcError ( void ) NORETURN;
218
static void cleanUpAndFail ( Int32 ) NORETURN;
219
static void compressedStreamEOF ( void ) NORETURN;
221
static void copyFileName ( Char*, Char* );
222
static void* myMalloc ( Int32 );
223
static void applySavedFileAttrToOutputFile ( IntNative fd );
227
/*---------------------------------------------------*/
228
/*--- An implementation of 64-bit ints. Sigh. ---*/
229
/*--- Roll on widespread deployment of ANSI C9X ! ---*/
230
/*---------------------------------------------------*/
233
struct { UChar b[8]; }
238
void uInt64_from_UInt32s ( UInt64* n, UInt32 lo32, UInt32 hi32 )
240
n->b[7] = (UChar)((hi32 >> 24) & 0xFF);
241
n->b[6] = (UChar)((hi32 >> 16) & 0xFF);
242
n->b[5] = (UChar)((hi32 >> 8) & 0xFF);
243
n->b[4] = (UChar) (hi32 & 0xFF);
244
n->b[3] = (UChar)((lo32 >> 24) & 0xFF);
245
n->b[2] = (UChar)((lo32 >> 16) & 0xFF);
246
n->b[1] = (UChar)((lo32 >> 8) & 0xFF);
247
n->b[0] = (UChar) (lo32 & 0xFF);
252
double uInt64_to_double ( UInt64* n )
257
for (i = 0; i < 8; i++) {
258
sum += base * (double)(n->b[i]);
266
Bool uInt64_isZero ( UInt64* n )
269
for (i = 0; i < 8; i++)
270
if (n->b[i] != 0) return 0;
275
/* Divide *n by 10, and return the remainder. */
277
Int32 uInt64_qrm10 ( UInt64* n )
282
for (i = 7; i >= 0; i--) {
283
tmp = rem * 256 + n->b[i];
291
/* ... and the Whole Entire Point of all this UInt64 stuff is
292
so that we can supply the following function.
295
void uInt64_toAscii ( char* outbuf, UInt64* n )
302
q = uInt64_qrm10 ( &n_copy );
305
} while (!uInt64_isZero(&n_copy));
307
for (i = 0; i < nBuf; i++)
308
outbuf[i] = buf[nBuf-i-1];
312
/*---------------------------------------------------*/
313
/*--- Processing of complete files and streams ---*/
314
/*---------------------------------------------------*/
316
/*---------------------------------------------*/
318
Bool myfeof ( FILE* f )
320
Int32 c = fgetc ( f );
321
if (c == EOF) return True;
327
/*---------------------------------------------*/
329
void compressStream ( FILE *stream, FILE *zStream )
334
UInt32 nbytes_in_lo32, nbytes_in_hi32;
335
UInt32 nbytes_out_lo32, nbytes_out_hi32;
336
Int32 bzerr, bzerr_dummy, ret;
338
SET_BINARY_MODE(stream);
339
SET_BINARY_MODE(zStream);
341
if (ferror(stream)) goto errhandler_io;
342
if (ferror(zStream)) goto errhandler_io;
344
bzf = BZ2_bzWriteOpen ( &bzerr, zStream,
345
blockSize100k, verbosity, workFactor );
346
if (bzerr != BZ_OK) goto errhandler;
348
if (verbosity >= 2) fprintf ( stderr, "\n" );
352
if (myfeof(stream)) break;
353
nIbuf = fread ( ibuf, sizeof(UChar), 5000, stream );
354
if (ferror(stream)) goto errhandler_io;
355
if (nIbuf > 0) BZ2_bzWrite ( &bzerr, bzf, (void*)ibuf, nIbuf );
356
if (bzerr != BZ_OK) goto errhandler;
360
BZ2_bzWriteClose64 ( &bzerr, bzf, 0,
361
&nbytes_in_lo32, &nbytes_in_hi32,
362
&nbytes_out_lo32, &nbytes_out_hi32 );
363
if (bzerr != BZ_OK) goto errhandler;
365
if (ferror(zStream)) goto errhandler_io;
366
ret = fflush ( zStream );
367
if (ret == EOF) goto errhandler_io;
368
if (zStream != stdout) {
369
Int32 fd = fileno ( zStream );
370
if (fd < 0) goto errhandler_io;
371
applySavedFileAttrToOutputFile ( fd );
372
ret = fclose ( zStream );
373
outputHandleJustInCase = NULL;
374
if (ret == EOF) goto errhandler_io;
376
outputHandleJustInCase = NULL;
377
if (ferror(stream)) goto errhandler_io;
378
ret = fclose ( stream );
379
if (ret == EOF) goto errhandler_io;
381
if (verbosity >= 1) {
382
if (nbytes_in_lo32 == 0 && nbytes_in_hi32 == 0) {
383
fprintf ( stderr, " no data compressed.\n");
385
Char buf_nin[32], buf_nout[32];
386
UInt64 nbytes_in, nbytes_out;
387
double nbytes_in_d, nbytes_out_d;
388
uInt64_from_UInt32s ( &nbytes_in,
389
nbytes_in_lo32, nbytes_in_hi32 );
390
uInt64_from_UInt32s ( &nbytes_out,
391
nbytes_out_lo32, nbytes_out_hi32 );
392
nbytes_in_d = uInt64_to_double ( &nbytes_in );
393
nbytes_out_d = uInt64_to_double ( &nbytes_out );
394
uInt64_toAscii ( buf_nin, &nbytes_in );
395
uInt64_toAscii ( buf_nout, &nbytes_out );
396
fprintf ( stderr, "%6.3f:1, %6.3f bits/byte, "
397
"%5.2f%% saved, %s in, %s out.\n",
398
nbytes_in_d / nbytes_out_d,
399
(8.0 * nbytes_out_d) / nbytes_in_d,
400
100.0 * (1.0 - nbytes_out_d / nbytes_in_d),
410
BZ2_bzWriteClose64 ( &bzerr_dummy, bzf, 1,
411
&nbytes_in_lo32, &nbytes_in_hi32,
412
&nbytes_out_lo32, &nbytes_out_hi32 );
414
case BZ_CONFIG_ERROR:
415
configError(); break;
417
outOfMemory (); break;
422
panic ( "compress:unexpected error" );
425
panic ( "compress:end" );
431
/*---------------------------------------------*/
433
Bool uncompressStream ( FILE *zStream, FILE *stream )
436
Int32 bzerr, bzerr_dummy, ret, nread, streamNo, i;
438
UChar unused[BZ_MAX_UNUSED];
446
SET_BINARY_MODE(stream);
447
SET_BINARY_MODE(zStream);
449
if (ferror(stream)) goto errhandler_io;
450
if (ferror(zStream)) goto errhandler_io;
454
bzf = BZ2_bzReadOpen (
455
&bzerr, zStream, verbosity,
456
(int)smallMode, unused, nUnused
458
if (bzf == NULL || bzerr != BZ_OK) goto errhandler;
461
while (bzerr == BZ_OK) {
462
nread = BZ2_bzRead ( &bzerr, bzf, obuf, 5000 );
463
if (bzerr == BZ_DATA_ERROR_MAGIC) goto trycat;
464
if ((bzerr == BZ_OK || bzerr == BZ_STREAM_END) && nread > 0)
465
fwrite ( obuf, sizeof(UChar), nread, stream );
466
if (ferror(stream)) goto errhandler_io;
468
if (bzerr != BZ_STREAM_END) goto errhandler;
470
BZ2_bzReadGetUnused ( &bzerr, bzf, &unusedTmpV, &nUnused );
471
if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" );
473
unusedTmp = (UChar*)unusedTmpV;
474
for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i];
476
BZ2_bzReadClose ( &bzerr, bzf );
477
if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" );
479
if (nUnused == 0 && myfeof(zStream)) break;
483
if (ferror(zStream)) goto errhandler_io;
484
if (stream != stdout) {
485
Int32 fd = fileno ( stream );
486
if (fd < 0) goto errhandler_io;
487
applySavedFileAttrToOutputFile ( fd );
489
ret = fclose ( zStream );
490
if (ret == EOF) goto errhandler_io;
492
if (ferror(stream)) goto errhandler_io;
493
ret = fflush ( stream );
494
if (ret != 0) goto errhandler_io;
495
if (stream != stdout) {
496
ret = fclose ( stream );
497
outputHandleJustInCase = NULL;
498
if (ret == EOF) goto errhandler_io;
500
outputHandleJustInCase = NULL;
501
if (verbosity >= 2) fprintf ( stderr, "\n " );
505
if (forceOverwrite) {
508
if (myfeof(zStream)) break;
509
nread = fread ( obuf, sizeof(UChar), 5000, zStream );
510
if (ferror(zStream)) goto errhandler_io;
511
if (nread > 0) fwrite ( obuf, sizeof(UChar), nread, stream );
512
if (ferror(stream)) goto errhandler_io;
518
BZ2_bzReadClose ( &bzerr_dummy, bzf );
520
case BZ_CONFIG_ERROR:
521
configError(); break;
529
case BZ_UNEXPECTED_EOF:
530
compressedStreamEOF();
531
case BZ_DATA_ERROR_MAGIC:
532
if (zStream != stdin) fclose(zStream);
533
if (stream != stdout) fclose(stream);
539
"\n%s: %s: trailing garbage after EOF ignored\n",
544
panic ( "decompress:unexpected error" );
547
panic ( "decompress:end" );
548
return True; /*notreached*/
552
/*---------------------------------------------*/
554
Bool testStream ( FILE *zStream )
557
Int32 bzerr, bzerr_dummy, ret, nread, streamNo, i;
559
UChar unused[BZ_MAX_UNUSED];
567
SET_BINARY_MODE(zStream);
568
if (ferror(zStream)) goto errhandler_io;
572
bzf = BZ2_bzReadOpen (
573
&bzerr, zStream, verbosity,
574
(int)smallMode, unused, nUnused
576
if (bzf == NULL || bzerr != BZ_OK) goto errhandler;
579
while (bzerr == BZ_OK) {
580
nread = BZ2_bzRead ( &bzerr, bzf, obuf, 5000 );
581
if (bzerr == BZ_DATA_ERROR_MAGIC) goto errhandler;
583
if (bzerr != BZ_STREAM_END) goto errhandler;
585
BZ2_bzReadGetUnused ( &bzerr, bzf, &unusedTmpV, &nUnused );
586
if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" );
588
unusedTmp = (UChar*)unusedTmpV;
589
for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i];
591
BZ2_bzReadClose ( &bzerr, bzf );
592
if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" );
593
if (nUnused == 0 && myfeof(zStream)) break;
597
if (ferror(zStream)) goto errhandler_io;
598
ret = fclose ( zStream );
599
if (ret == EOF) goto errhandler_io;
601
if (verbosity >= 2) fprintf ( stderr, "\n " );
605
BZ2_bzReadClose ( &bzerr_dummy, bzf );
607
fprintf ( stderr, "%s: %s: ", progName, inName );
609
case BZ_CONFIG_ERROR:
610
configError(); break;
616
"data integrity (CRC) error in data\n" );
620
case BZ_UNEXPECTED_EOF:
622
"file ends unexpectedly\n" );
624
case BZ_DATA_ERROR_MAGIC:
625
if (zStream != stdin) fclose(zStream);
628
"bad magic number (file not created by bzip2)\n" );
633
"trailing garbage after EOF ignored\n" );
637
panic ( "test:unexpected error" );
640
panic ( "test:end" );
641
return True; /*notreached*/
645
/*---------------------------------------------------*/
646
/*--- Error [non-] handling grunge ---*/
647
/*---------------------------------------------------*/
649
/*---------------------------------------------*/
651
void setExit ( Int32 v )
653
if (v > exitValue) exitValue = v;
657
/*---------------------------------------------*/
659
void cadvise ( void )
664
"\nIt is possible that the compressed file(s) have become corrupted.\n"
665
"You can use the -tvv option to test integrity of such files.\n\n"
666
"You can use the `bzip2recover' program to attempt to recover\n"
667
"data from undamaged sections of corrupted files.\n\n"
672
/*---------------------------------------------*/
674
void showFileNames ( void )
679
"\tInput file = %s, output file = %s\n",
685
/*---------------------------------------------*/
687
void cleanUpAndFail ( Int32 ec )
690
struct MY_STAT statBuf;
692
if ( srcMode == SM_F2F
694
&& deleteOutputOnInterrupt ) {
696
/* Check whether input file still exists. Delete output file
697
only if input exists to avoid loss of data. Joerg Prante, 5
698
January 2002. (JRS 06-Jan-2002: other changes in 1.0.2 mean
699
this is less likely to happen. But to be ultra-paranoid, we
700
do the check anyway.) */
701
retVal = MY_STAT ( inName, &statBuf );
705
"%s: Deleting output file %s, if it exists.\n",
707
if (outputHandleJustInCase != NULL)
708
fclose ( outputHandleJustInCase );
709
retVal = remove ( outName );
712
"%s: WARNING: deletion of output file "
713
"(apparently) failed.\n",
717
"%s: WARNING: deletion of output file suppressed\n",
720
"%s: since input file no longer exists. Output file\n",
723
"%s: `%s' may be incomplete.\n",
726
"%s: I suggest doing an integrity test (bzip2 -tv)"
732
if (noisy && numFileNames > 0 && numFilesProcessed < numFileNames) {
734
"%s: WARNING: some files have not been processed:\n"
735
"%s: %d specified on command line, %d not processed yet.\n\n",
737
numFileNames, numFileNames - numFilesProcessed );
744
/*---------------------------------------------*/
746
void panic ( const Char* s )
749
"\n%s: PANIC -- internal consistency error:\n"
751
"\tThis is a BUG. Please report it to me at:\n"
752
"\tjseward@bzip.org\n",
759
/*---------------------------------------------*/
761
void crcError ( void )
764
"\n%s: Data integrity error when decompressing.\n",
772
/*---------------------------------------------*/
774
void compressedStreamEOF ( void )
778
"\n%s: Compressed file ends unexpectedly;\n\t"
779
"perhaps it is corrupted? *Possible* reason follows.\n",
789
/*---------------------------------------------*/
791
void ioError ( void )
794
"\n%s: I/O or other error, bailing out. "
795
"Possible reason follows.\n",
803
/*---------------------------------------------*/
805
void mySignalCatcher ( IntNative n )
808
"\n%s: Control-C or similar caught, quitting.\n",
814
/*---------------------------------------------*/
816
void mySIGSEGVorSIGBUScatcher ( IntNative n )
821
"\n%s: Caught a SIGSEGV or SIGBUS whilst compressing.\n"
823
" Possible causes are (most likely first):\n"
824
" (1) This computer has unreliable memory or cache hardware\n"
825
" (a surprisingly common problem; try a different machine.)\n"
826
" (2) A bug in the compiler used to create this executable\n"
827
" (unlikely, if you didn't compile bzip2 yourself.)\n"
828
" (3) A real bug in bzip2 -- I hope this should never be the case.\n"
829
" The user's manual, Section 4.3, has more info on (1) and (2).\n"
831
" If you suspect this is a bug in bzip2, or are unsure about (1)\n"
832
" or (2), feel free to report it to me at: jseward@bzip.org.\n"
833
" Section 4.3 of the user's manual describes the info a useful\n"
834
" bug report should have. If the manual is available on your\n"
835
" system, please try and read it before mailing me. If you don't\n"
836
" have the manual or can't be bothered to read it, mail me anyway.\n"
842
"\n%s: Caught a SIGSEGV or SIGBUS whilst decompressing.\n"
844
" Possible causes are (most likely first):\n"
845
" (1) The compressed data is corrupted, and bzip2's usual checks\n"
846
" failed to detect this. Try bzip2 -tvv my_file.bz2.\n"
847
" (2) This computer has unreliable memory or cache hardware\n"
848
" (a surprisingly common problem; try a different machine.)\n"
849
" (3) A bug in the compiler used to create this executable\n"
850
" (unlikely, if you didn't compile bzip2 yourself.)\n"
851
" (4) A real bug in bzip2 -- I hope this should never be the case.\n"
852
" The user's manual, Section 4.3, has more info on (2) and (3).\n"
854
" If you suspect this is a bug in bzip2, or are unsure about (2)\n"
855
" or (3), feel free to report it to me at: jseward@bzip.org.\n"
856
" Section 4.3 of the user's manual describes the info a useful\n"
857
" bug report should have. If the manual is available on your\n"
858
" system, please try and read it before mailing me. If you don't\n"
859
" have the manual or can't be bothered to read it, mail me anyway.\n"
865
cleanUpAndFail( 3 ); else
866
{ cadvise(); cleanUpAndFail( 2 ); }
870
/*---------------------------------------------*/
872
void outOfMemory ( void )
875
"\n%s: couldn't allocate enough memory\n",
882
/*---------------------------------------------*/
884
void configError ( void )
887
"bzip2: I'm not configured correctly for this platform!\n"
888
"\tI require Int32, Int16 and Char to have sizes\n"
889
"\tof 4, 2 and 1 bytes to run properly, and they don't.\n"
890
"\tProbably you can fix this by defining them correctly,\n"
891
"\tand recompiling. Bye!\n" );
897
/*---------------------------------------------------*/
898
/*--- The main driver machinery ---*/
899
/*---------------------------------------------------*/
901
/* All rather crufty. The main problem is that input files
902
are stat()d multiple times before use. This should be
906
/*---------------------------------------------*/
911
if ( (Int32)strlen(s) >= longestFileName ) return;
912
for (i = 1; i <= longestFileName - (Int32)strlen(s); i++)
913
fprintf ( stderr, " " );
917
/*---------------------------------------------*/
919
void copyFileName ( Char* to, Char* from )
921
if ( strlen(from) > FILE_NAME_LEN-10 ) {
924
"bzip2: file name\n`%s'\n"
925
"is suspiciously (more than %d chars) long.\n"
926
"Try using a reasonable file name instead. Sorry! :-)\n",
927
from, FILE_NAME_LEN-10
933
strncpy(to,from,FILE_NAME_LEN-10);
934
to[FILE_NAME_LEN-10]='\0';
938
/*---------------------------------------------*/
940
Bool fileExists ( Char* name )
942
FILE *tmp = fopen ( name, "rb" );
943
Bool exists = (tmp != NULL);
944
if (tmp != NULL) fclose ( tmp );
949
/*---------------------------------------------*/
950
/* Open an output file safely with O_EXCL and good permissions.
951
This avoids a race condition in versions < 1.0.2, in which
952
the file was first opened and then had its interim permissions
953
set safely. We instead use open() to create the file with
954
the interim permissions required. (--- --- rw-).
956
For non-Unix platforms, if we are not worrying about
957
security issues, simple this simply behaves like fopen.
960
FILE* fopen_output_safely ( Char* name, const char* mode )
965
fh = open(name, O_WRONLY|O_CREAT|O_EXCL, S_IWUSR|S_IRUSR);
966
if (fh == -1) return NULL;
967
fp = fdopen(fh, mode);
968
if (fp == NULL) close(fh);
971
return fopen(name, mode);
976
/*---------------------------------------------*/
978
if in doubt, return True
981
Bool notAStandardFile ( Char* name )
984
struct MY_STAT statBuf;
986
i = MY_LSTAT ( name, &statBuf );
987
if (i != 0) return True;
988
if (MY_S_ISREG(statBuf.st_mode)) return False;
993
/*---------------------------------------------*/
995
rac 11/21/98 see if file has hard links to it
998
Int32 countHardLinks ( Char* name )
1001
struct MY_STAT statBuf;
1003
i = MY_LSTAT ( name, &statBuf );
1004
if (i != 0) return 0;
1005
return (statBuf.st_nlink - 1);
1009
/*---------------------------------------------*/
1010
/* Copy modification date, access date, permissions and owner from the
1011
source to destination file. We have to copy this meta-info off
1012
into fileMetaInfo before starting to compress / decompress it,
1013
because doing it afterwards means we get the wrong access time.
1015
To complicate matters, in compress() and decompress() below, the
1016
sequence of tests preceding the call to saveInputFileMetaInfo()
1017
involves calling fileExists(), which in turn establishes its result
1018
by attempting to fopen() the file, and if successful, immediately
1019
fclose()ing it again. So we have to assume that the fopen() call
1020
does not cause the access time field to be updated.
1022
Reading of the man page for stat() (man 2 stat) on RedHat 7.2 seems
1023
to imply that merely doing open() will not affect the access time.
1024
Therefore we merely need to hope that the C library only does
1025
open() as a result of fopen(), and not any kind of read()-ahead
1028
It sounds pretty fragile to me. Whether this carries across
1029
robustly to arbitrary Unix-like platforms (or even works robustly
1030
on this one, RedHat 7.2) is unknown to me. Nevertheless ...
1034
struct MY_STAT fileMetaInfo;
1038
void saveInputFileMetaInfo ( Char *srcName )
1042
/* Note use of stat here, not lstat. */
1043
retVal = MY_STAT( srcName, &fileMetaInfo );
1044
ERROR_IF_NOT_ZERO ( retVal );
1050
void applySavedTimeInfoToOutputFile ( Char *dstName )
1054
struct utimbuf uTimBuf;
1056
uTimBuf.actime = fileMetaInfo.st_atime;
1057
uTimBuf.modtime = fileMetaInfo.st_mtime;
1059
retVal = utime ( dstName, &uTimBuf );
1060
ERROR_IF_NOT_ZERO ( retVal );
1065
void applySavedFileAttrToOutputFile ( IntNative fd )
1070
retVal = fchmod ( fd, fileMetaInfo.st_mode );
1071
ERROR_IF_NOT_ZERO ( retVal );
1073
(void) fchown ( fd, fileMetaInfo.st_uid, fileMetaInfo.st_gid );
1074
/* chown() will in many cases return with EPERM, which can
1081
/*---------------------------------------------*/
1083
Bool containsDubiousChars ( Char* name )
1086
/* On unix, files can contain any characters and the file expansion
1087
* is performed by the shell.
1090
# else /* ! BZ_UNIX */
1091
/* On non-unix (Win* platforms), wildcard characters are not allowed in
1094
for (; *name != '\0'; name++)
1095
if (*name == '?' || *name == '*') return True;
1097
# endif /* BZ_UNIX */
1101
/*---------------------------------------------*/
1102
#define BZ_N_SUFFIX_PAIRS 4
1104
const Char* zSuffix[BZ_N_SUFFIX_PAIRS]
1105
= { ".bz2", ".bz", ".tbz2", ".tbz" };
1106
const Char* unzSuffix[BZ_N_SUFFIX_PAIRS]
1107
= { "", "", ".tar", ".tar" };
1110
Bool hasSuffix ( Char* s, const Char* suffix )
1112
Int32 ns = strlen(s);
1113
Int32 nx = strlen(suffix);
1114
if (ns < nx) return False;
1115
if (strcmp(s + ns - nx, suffix) == 0) return True;
1120
Bool mapSuffix ( Char* name,
1121
const Char* oldSuffix,
1122
const Char* newSuffix )
1124
if (!hasSuffix(name,oldSuffix)) return False;
1125
name[strlen(name)-strlen(oldSuffix)] = 0;
1126
strcat ( name, newSuffix );
1131
/*---------------------------------------------*/
1133
void compress ( Char *name )
1138
struct MY_STAT statBuf;
1140
deleteOutputOnInterrupt = False;
1142
if (name == NULL && srcMode != SM_I2O)
1143
panic ( "compress: bad modes\n" );
1147
copyFileName ( inName, (Char*)"(stdin)" );
1148
copyFileName ( outName, (Char*)"(stdout)" );
1151
copyFileName ( inName, name );
1152
copyFileName ( outName, name );
1153
strcat ( outName, ".bz2" );
1156
copyFileName ( inName, name );
1157
copyFileName ( outName, (Char*)"(stdout)" );
1161
if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
1163
fprintf ( stderr, "%s: There are no files matching `%s'.\n",
1168
if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
1169
fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
1170
progName, inName, strerror(errno) );
1174
for (i = 0; i < BZ_N_SUFFIX_PAIRS; i++) {
1175
if (hasSuffix(inName, zSuffix[i])) {
1178
"%s: Input file %s already has %s suffix.\n",
1179
progName, inName, zSuffix[i] );
1184
if ( srcMode == SM_F2F || srcMode == SM_F2O ) {
1185
MY_STAT(inName, &statBuf);
1186
if ( MY_S_ISDIR(statBuf.st_mode) ) {
1188
"%s: Input file %s is a directory.\n",
1194
if ( srcMode == SM_F2F && !forceOverwrite && notAStandardFile ( inName )) {
1196
fprintf ( stderr, "%s: Input file %s is not a normal file.\n",
1201
if ( srcMode == SM_F2F && fileExists ( outName ) ) {
1202
if (forceOverwrite) {
1205
fprintf ( stderr, "%s: Output file %s already exists.\n",
1206
progName, outName );
1211
if ( srcMode == SM_F2F && !forceOverwrite &&
1212
(n=countHardLinks ( inName )) > 0) {
1213
fprintf ( stderr, "%s: Input file %s has %d other link%s.\n",
1214
progName, inName, n, n > 1 ? "s" : "" );
1219
if ( srcMode == SM_F2F ) {
1220
/* Save the file's meta-info before we open it. Doing it later
1221
means we mess up the access times. */
1222
saveInputFileMetaInfo ( inName );
1225
switch ( srcMode ) {
1230
if ( isatty ( fileno ( stdout ) ) ) {
1232
"%s: I won't write compressed data to a terminal.\n",
1234
fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
1235
progName, progName );
1242
inStr = fopen ( inName, "rb" );
1244
if ( isatty ( fileno ( stdout ) ) ) {
1246
"%s: I won't write compressed data to a terminal.\n",
1248
fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
1249
progName, progName );
1250
if ( inStr != NULL ) fclose ( inStr );
1254
if ( inStr == NULL ) {
1255
fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
1256
progName, inName, strerror(errno) );
1263
inStr = fopen ( inName, "rb" );
1264
outStr = fopen_output_safely ( outName, "wb" );
1265
if ( outStr == NULL) {
1266
fprintf ( stderr, "%s: Can't create output file %s: %s.\n",
1267
progName, outName, strerror(errno) );
1268
if ( inStr != NULL ) fclose ( inStr );
1272
if ( inStr == NULL ) {
1273
fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
1274
progName, inName, strerror(errno) );
1275
if ( outStr != NULL ) fclose ( outStr );
1282
panic ( "compress: bad srcMode" );
1286
if (verbosity >= 1) {
1287
fprintf ( stderr, " %s: ", inName );
1292
/*--- Now the input and output handles are sane. Do the Biz. ---*/
1293
outputHandleJustInCase = outStr;
1294
deleteOutputOnInterrupt = True;
1295
compressStream ( inStr, outStr );
1296
outputHandleJustInCase = NULL;
1298
/*--- If there was an I/O error, we won't get here. ---*/
1299
if ( srcMode == SM_F2F ) {
1300
applySavedTimeInfoToOutputFile ( outName );
1301
deleteOutputOnInterrupt = False;
1302
if ( !keepInputFiles ) {
1303
IntNative retVal = remove ( inName );
1304
ERROR_IF_NOT_ZERO ( retVal );
1308
deleteOutputOnInterrupt = False;
1312
/*---------------------------------------------*/
1314
void uncompress ( Char *name )
1321
struct MY_STAT statBuf;
1323
deleteOutputOnInterrupt = False;
1325
if (name == NULL && srcMode != SM_I2O)
1326
panic ( "uncompress: bad modes\n" );
1331
copyFileName ( inName, (Char*)"(stdin)" );
1332
copyFileName ( outName, (Char*)"(stdout)" );
1335
copyFileName ( inName, name );
1336
copyFileName ( outName, name );
1337
for (i = 0; i < BZ_N_SUFFIX_PAIRS; i++)
1338
if (mapSuffix(outName,zSuffix[i],unzSuffix[i]))
1341
strcat ( outName, ".out" );
1344
copyFileName ( inName, name );
1345
copyFileName ( outName, (Char*)"(stdout)" );
1350
if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
1352
fprintf ( stderr, "%s: There are no files matching `%s'.\n",
1357
if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
1358
fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
1359
progName, inName, strerror(errno) );
1363
if ( srcMode == SM_F2F || srcMode == SM_F2O ) {
1364
MY_STAT(inName, &statBuf);
1365
if ( MY_S_ISDIR(statBuf.st_mode) ) {
1367
"%s: Input file %s is a directory.\n",
1373
if ( srcMode == SM_F2F && !forceOverwrite && notAStandardFile ( inName )) {
1375
fprintf ( stderr, "%s: Input file %s is not a normal file.\n",
1380
if ( /* srcMode == SM_F2F implied && */ cantGuess ) {
1383
"%s: Can't guess original name for %s -- using %s\n",
1384
progName, inName, outName );
1385
/* just a warning, no return */
1387
if ( srcMode == SM_F2F && fileExists ( outName ) ) {
1388
if (forceOverwrite) {
1391
fprintf ( stderr, "%s: Output file %s already exists.\n",
1392
progName, outName );
1397
if ( srcMode == SM_F2F && !forceOverwrite &&
1398
(n=countHardLinks ( inName ) ) > 0) {
1399
fprintf ( stderr, "%s: Input file %s has %d other link%s.\n",
1400
progName, inName, n, n > 1 ? "s" : "" );
1405
if ( srcMode == SM_F2F ) {
1406
/* Save the file's meta-info before we open it. Doing it later
1407
means we mess up the access times. */
1408
saveInputFileMetaInfo ( inName );
1411
switch ( srcMode ) {
1416
if ( isatty ( fileno ( stdin ) ) ) {
1418
"%s: I won't read compressed data from a terminal.\n",
1420
fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
1421
progName, progName );
1428
inStr = fopen ( inName, "rb" );
1430
if ( inStr == NULL ) {
1431
fprintf ( stderr, "%s: Can't open input file %s:%s.\n",
1432
progName, inName, strerror(errno) );
1433
if ( inStr != NULL ) fclose ( inStr );
1440
inStr = fopen ( inName, "rb" );
1441
outStr = fopen_output_safely ( outName, "wb" );
1442
if ( outStr == NULL) {
1443
fprintf ( stderr, "%s: Can't create output file %s: %s.\n",
1444
progName, outName, strerror(errno) );
1445
if ( inStr != NULL ) fclose ( inStr );
1449
if ( inStr == NULL ) {
1450
fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
1451
progName, inName, strerror(errno) );
1452
if ( outStr != NULL ) fclose ( outStr );
1459
panic ( "uncompress: bad srcMode" );
1463
if (verbosity >= 1) {
1464
fprintf ( stderr, " %s: ", inName );
1469
/*--- Now the input and output handles are sane. Do the Biz. ---*/
1470
outputHandleJustInCase = outStr;
1471
deleteOutputOnInterrupt = True;
1472
magicNumberOK = uncompressStream ( inStr, outStr );
1473
outputHandleJustInCase = NULL;
1475
/*--- If there was an I/O error, we won't get here. ---*/
1476
if ( magicNumberOK ) {
1477
if ( srcMode == SM_F2F ) {
1478
applySavedTimeInfoToOutputFile ( outName );
1479
deleteOutputOnInterrupt = False;
1480
if ( !keepInputFiles ) {
1481
IntNative retVal = remove ( inName );
1482
ERROR_IF_NOT_ZERO ( retVal );
1486
unzFailsExist = True;
1487
deleteOutputOnInterrupt = False;
1488
if ( srcMode == SM_F2F ) {
1489
IntNative retVal = remove ( outName );
1490
ERROR_IF_NOT_ZERO ( retVal );
1493
deleteOutputOnInterrupt = False;
1495
if ( magicNumberOK ) {
1497
fprintf ( stderr, "done\n" );
1501
fprintf ( stderr, "not a bzip2 file.\n" ); else
1503
"%s: %s is not a bzip2 file.\n",
1510
/*---------------------------------------------*/
1512
void testf ( Char *name )
1516
struct MY_STAT statBuf;
1518
deleteOutputOnInterrupt = False;
1520
if (name == NULL && srcMode != SM_I2O)
1521
panic ( "testf: bad modes\n" );
1523
copyFileName ( outName, (Char*)"(none)" );
1525
case SM_I2O: copyFileName ( inName, (Char*)"(stdin)" ); break;
1526
case SM_F2F: copyFileName ( inName, name ); break;
1527
case SM_F2O: copyFileName ( inName, name ); break;
1530
if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
1532
fprintf ( stderr, "%s: There are no files matching `%s'.\n",
1537
if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
1538
fprintf ( stderr, "%s: Can't open input %s: %s.\n",
1539
progName, inName, strerror(errno) );
1543
if ( srcMode != SM_I2O ) {
1544
MY_STAT(inName, &statBuf);
1545
if ( MY_S_ISDIR(statBuf.st_mode) ) {
1547
"%s: Input file %s is a directory.\n",
1554
switch ( srcMode ) {
1557
if ( isatty ( fileno ( stdin ) ) ) {
1559
"%s: I won't read compressed data from a terminal.\n",
1561
fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
1562
progName, progName );
1569
case SM_F2O: case SM_F2F:
1570
inStr = fopen ( inName, "rb" );
1571
if ( inStr == NULL ) {
1572
fprintf ( stderr, "%s: Can't open input file %s:%s.\n",
1573
progName, inName, strerror(errno) );
1580
panic ( "testf: bad srcMode" );
1584
if (verbosity >= 1) {
1585
fprintf ( stderr, " %s: ", inName );
1590
/*--- Now the input handle is sane. Do the Biz. ---*/
1591
outputHandleJustInCase = NULL;
1592
allOK = testStream ( inStr );
1594
if (allOK && verbosity >= 1) fprintf ( stderr, "ok\n" );
1595
if (!allOK) testFailsExist = True;
1599
/*---------------------------------------------*/
1601
void license ( void )
1605
"bzip2, a block-sorting file compressor. "
1608
" Copyright (C) 1996-2010 by Julian Seward.\n"
1610
" This program is free software; you can redistribute it and/or modify\n"
1611
" it under the terms set out in the LICENSE file, which is included\n"
1612
" in the bzip2-1.0.6 source distribution.\n"
1614
" This program is distributed in the hope that it will be useful,\n"
1615
" but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
1616
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
1617
" LICENSE file for more details.\n"
1624
/*---------------------------------------------*/
1626
void usage ( Char *fullProgName )
1630
"bzip2, a block-sorting file compressor. "
1632
"\n usage: %s [flags and input files in any order]\n"
1634
" -h --help print this message\n"
1635
" -d --decompress force decompression\n"
1636
" -z --compress force compression\n"
1637
" -k --keep keep (don't delete) input files\n"
1638
" -f --force overwrite existing output files\n"
1639
" -t --test test compressed file integrity\n"
1640
" -c --stdout output to standard out\n"
1641
" -q --quiet suppress noncritical error messages\n"
1642
" -v --verbose be verbose (a 2nd -v gives more)\n"
1643
" -L --license display software version & license\n"
1644
" -V --version display software version & license\n"
1645
" -s --small use less memory (at most 2500k)\n"
1646
" -1 .. -9 set block size to 100k .. 900k\n"
1647
" --fast alias for -1\n"
1648
" --best alias for -9\n"
1650
" If invoked as `bzip2', default action is to compress.\n"
1651
" as `bunzip2', default action is to decompress.\n"
1652
" as `bzcat', default action is to decompress to stdout.\n"
1654
" If no file names are given, bzip2 compresses or decompresses\n"
1655
" from standard input to standard output. You can combine\n"
1656
" short flags, so `-v -4' means the same as -v4 or -4v, &c.\n"
1668
/*---------------------------------------------*/
1670
void redundant ( Char* flag )
1674
"%s: %s is redundant in versions 0.9.5 and above\n",
1679
/*---------------------------------------------*/
1681
All the garbage from here to main() is purely to
1682
implement a linked list of command-line arguments,
1683
into which main() copies argv[1 .. argc-1].
1685
The purpose of this exercise is to facilitate
1686
the expansion of wildcard characters * and ? in
1687
filenames for OSs which don't know how to do it
1688
themselves, like MSDOS, Windows 95 and NT.
1690
The actual Dirty Work is done by the platform-
1691
specific macro APPEND_FILESPEC.
1702
/*---------------------------------------------*/
1704
void *myMalloc ( Int32 n )
1708
p = malloc ( (size_t)n );
1709
if (p == NULL) outOfMemory ();
1714
/*---------------------------------------------*/
1716
Cell *mkCell ( void )
1720
c = (Cell*) myMalloc ( sizeof ( Cell ) );
1727
/*---------------------------------------------*/
1729
Cell *snocString ( Cell *root, Char *name )
1732
Cell *tmp = mkCell();
1733
tmp->name = (Char*) myMalloc ( 5 + strlen(name) );
1734
strcpy ( tmp->name, name );
1738
while (tmp->link != NULL) tmp = tmp->link;
1739
tmp->link = snocString ( tmp->link, name );
1745
/*---------------------------------------------*/
1747
void addFlagsFromEnvVar ( Cell** argList, Char* varName )
1752
envbase = getenv(varName);
1753
if (envbase != NULL) {
1757
if (p[i] == 0) break;
1760
while (isspace((Int32)(p[0]))) p++;
1761
while (p[i] != 0 && !isspace((Int32)(p[i]))) i++;
1763
k = i; if (k > FILE_NAME_LEN-10) k = FILE_NAME_LEN-10;
1764
for (j = 0; j < k; j++) tmpName[j] = p[j];
1766
APPEND_FLAG(*argList, tmpName);
1773
/*---------------------------------------------*/
1774
#define ISFLAG(s) (strcmp(aa->name, (s))==0)
1776
IntNative main ( IntNative argc, Char *argv[] )
1784
/*-- Be really really really paranoid :-) --*/
1785
if (sizeof(Int32) != 4 || sizeof(UInt32) != 4 ||
1786
sizeof(Int16) != 2 || sizeof(UInt16) != 2 ||
1787
sizeof(Char) != 1 || sizeof(UChar) != 1)
1790
/*-- Initialise --*/
1791
outputHandleJustInCase = NULL;
1793
keepInputFiles = False;
1794
forceOverwrite = False;
1798
testFailsExist = False;
1799
unzFailsExist = False;
1801
numFilesProcessed = 0;
1803
deleteOutputOnInterrupt = False;
1805
i = j = 0; /* avoid bogus warning from egcs-1.1.X */
1807
/*-- Set up signal handlers for mem access errors --*/
1808
signal (SIGSEGV, mySIGSEGVorSIGBUScatcher);
1811
signal (SIGBUS, mySIGSEGVorSIGBUScatcher);
1815
copyFileName ( inName, (Char*)"(none)" );
1816
copyFileName ( outName, (Char*)"(none)" );
1818
copyFileName ( progNameReally, argv[0] );
1819
progName = &progNameReally[0];
1820
for (tmp = &progNameReally[0]; *tmp != '\0'; tmp++)
1821
if (*tmp == PATH_SEP) progName = tmp + 1;
1824
/*-- Copy flags from env var BZIP2, and
1825
expand filename wildcards in arg list.
1828
addFlagsFromEnvVar ( &argList, (Char*)"BZIP2" );
1829
addFlagsFromEnvVar ( &argList, (Char*)"BZIP" );
1830
for (i = 1; i <= argc-1; i++)
1831
APPEND_FILESPEC(argList, argv[i]);
1834
/*-- Find the length of the longest filename --*/
1835
longestFileName = 7;
1838
for (aa = argList; aa != NULL; aa = aa->link) {
1839
if (ISFLAG("--")) { decode = False; continue; }
1840
if (aa->name[0] == '-' && decode) continue;
1842
if (longestFileName < (Int32)strlen(aa->name) )
1843
longestFileName = (Int32)strlen(aa->name);
1847
/*-- Determine source modes; flag handling may change this too. --*/
1848
if (numFileNames == 0)
1849
srcMode = SM_I2O; else srcMode = SM_F2F;
1852
/*-- Determine what to do (compress/uncompress/test/cat). --*/
1853
/*-- Note that subsequent flag handling may change this. --*/
1856
if ( (strstr ( progName, "unzip" ) != 0) ||
1857
(strstr ( progName, "UNZIP" ) != 0) )
1860
if ( (strstr ( progName, "z2cat" ) != 0) ||
1861
(strstr ( progName, "Z2CAT" ) != 0) ||
1862
(strstr ( progName, "zcat" ) != 0) ||
1863
(strstr ( progName, "ZCAT" ) != 0) ) {
1865
srcMode = (numFileNames == 0) ? SM_I2O : SM_F2O;
1869
/*-- Look at the flags. --*/
1870
for (aa = argList; aa != NULL; aa = aa->link) {
1871
if (ISFLAG("--")) break;
1872
if (aa->name[0] == '-' && aa->name[1] != '-') {
1873
for (j = 1; aa->name[j] != '\0'; j++) {
1874
switch (aa->name[j]) {
1875
case 'c': srcMode = SM_F2O; break;
1876
case 'd': opMode = OM_UNZ; break;
1877
case 'z': opMode = OM_Z; break;
1878
case 'f': forceOverwrite = True; break;
1879
case 't': opMode = OM_TEST; break;
1880
case 'k': keepInputFiles = True; break;
1881
case 's': smallMode = True; break;
1882
case 'q': noisy = False; break;
1883
case '1': blockSize100k = 1; break;
1884
case '2': blockSize100k = 2; break;
1885
case '3': blockSize100k = 3; break;
1886
case '4': blockSize100k = 4; break;
1887
case '5': blockSize100k = 5; break;
1888
case '6': blockSize100k = 6; break;
1889
case '7': blockSize100k = 7; break;
1890
case '8': blockSize100k = 8; break;
1891
case '9': blockSize100k = 9; break;
1893
case 'L': license(); break;
1894
case 'v': verbosity++; break;
1895
case 'h': usage ( progName );
1898
default: fprintf ( stderr, "%s: Bad flag `%s'\n",
1899
progName, aa->name );
1908
/*-- And again ... --*/
1909
for (aa = argList; aa != NULL; aa = aa->link) {
1910
if (ISFLAG("--")) break;
1911
if (ISFLAG("--stdout")) srcMode = SM_F2O; else
1912
if (ISFLAG("--decompress")) opMode = OM_UNZ; else
1913
if (ISFLAG("--compress")) opMode = OM_Z; else
1914
if (ISFLAG("--force")) forceOverwrite = True; else
1915
if (ISFLAG("--test")) opMode = OM_TEST; else
1916
if (ISFLAG("--keep")) keepInputFiles = True; else
1917
if (ISFLAG("--small")) smallMode = True; else
1918
if (ISFLAG("--quiet")) noisy = False; else
1919
if (ISFLAG("--version")) license(); else
1920
if (ISFLAG("--license")) license(); else
1921
if (ISFLAG("--exponential")) workFactor = 1; else
1922
if (ISFLAG("--repetitive-best")) redundant(aa->name); else
1923
if (ISFLAG("--repetitive-fast")) redundant(aa->name); else
1924
if (ISFLAG("--fast")) blockSize100k = 1; else
1925
if (ISFLAG("--best")) blockSize100k = 9; else
1926
if (ISFLAG("--verbose")) verbosity++; else
1927
if (ISFLAG("--help")) { usage ( progName ); exit ( 0 ); }
1929
if (strncmp ( aa->name, "--", 2) == 0) {
1930
fprintf ( stderr, "%s: Bad flag `%s'\n", progName, aa->name );
1936
if (verbosity > 4) verbosity = 4;
1937
if (opMode == OM_Z && smallMode && blockSize100k > 2)
1940
if (opMode == OM_TEST && srcMode == SM_F2O) {
1941
fprintf ( stderr, "%s: -c and -t cannot be used together.\n",
1946
if (srcMode == SM_F2O && numFileNames == 0)
1949
if (opMode != OM_Z) blockSize100k = 0;
1951
if (srcMode == SM_F2F) {
1952
signal (SIGINT, mySignalCatcher);
1953
signal (SIGTERM, mySignalCatcher);
1955
signal (SIGHUP, mySignalCatcher);
1959
if (opMode == OM_Z) {
1960
if (srcMode == SM_I2O) {
1964
for (aa = argList; aa != NULL; aa = aa->link) {
1965
if (ISFLAG("--")) { decode = False; continue; }
1966
if (aa->name[0] == '-' && decode) continue;
1967
numFilesProcessed++;
1968
compress ( aa->name );
1974
if (opMode == OM_UNZ) {
1975
unzFailsExist = False;
1976
if (srcMode == SM_I2O) {
1977
uncompress ( NULL );
1980
for (aa = argList; aa != NULL; aa = aa->link) {
1981
if (ISFLAG("--")) { decode = False; continue; }
1982
if (aa->name[0] == '-' && decode) continue;
1983
numFilesProcessed++;
1984
uncompress ( aa->name );
1987
if (unzFailsExist) {
1994
testFailsExist = False;
1995
if (srcMode == SM_I2O) {
1999
for (aa = argList; aa != NULL; aa = aa->link) {
2000
if (ISFLAG("--")) { decode = False; continue; }
2001
if (aa->name[0] == '-' && decode) continue;
2002
numFilesProcessed++;
2006
if (testFailsExist && noisy) {
2009
"You can use the `bzip2recover' program to attempt to recover\n"
2010
"data from undamaged sections of corrupted files.\n\n"
2017
/* Free the argument list memory to mollify leak detectors
2018
(eg) Purify, Checker. Serves no other useful purpose.
2021
while (aa != NULL) {
2022
Cell* aa2 = aa->link;
2023
if (aa->name != NULL) free(aa->name);
2032
/*-----------------------------------------------------------*/
2033
/*--- end bzip2.c ---*/
2034
/*-----------------------------------------------------------*/