Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/bzip/bzip2.c
1808 views
1
#pragma prototyped
2
3
/*-----------------------------------------------------------*/
4
/*--- A block-sorting, lossless compressor bzip2.c ---*/
5
/*-----------------------------------------------------------*/
6
7
/*--
8
This file is a part of bzip2 and/or libbzip2, a program and
9
library for lossless, block-sorting data compression.
10
11
Copyright (C) 1996-1998 Julian R Seward. All rights reserved.
12
13
Redistribution and use in source and binary forms, with or without
14
modification, are permitted provided that the following conditions
15
are met:
16
17
1. Redistributions of source code must retain the above copyright
18
notice, this list of conditions and the following disclaimer.
19
20
2. The origin of this software must not be misrepresented; you must
21
not claim that you wrote the original software. If you use this
22
software in a product, an acknowledgment in the product
23
documentation would be appreciated but is not required.
24
25
3. Altered source versions must be plainly marked as such, and must
26
not be misrepresented as being the original software.
27
28
4. The name of the author may not be used to endorse or promote
29
products derived from this software without specific prior written
30
permission.
31
32
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
33
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
36
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
38
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
39
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
40
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
41
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
42
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43
44
Julian Seward, Guildford, Surrey, UK.
45
[email protected]
46
bzip2/libbzip2 version 0.9.0c of 18 October 1998
47
48
This program is based on (at least) the work of:
49
Mike Burrows
50
David Wheeler
51
Peter Fenwick
52
Alistair Moffat
53
Radford Neal
54
Ian H. Witten
55
Robert Sedgewick
56
Jon L. Bentley
57
58
For more information on these sources, see the manual.
59
--*/
60
61
62
/*----------------------------------------------------*/
63
/*--- IMPORTANT ---*/
64
/*----------------------------------------------------*/
65
66
/*--
67
WARNING:
68
This program and library (attempts to) compress data by
69
performing several non-trivial transformations on it.
70
Unless you are 100% familiar with *all* the algorithms
71
contained herein, and with the consequences of modifying them,
72
you should NOT meddle with the compression or decompression
73
machinery. Incorrect changes can and very likely *will*
74
lead to disasterous loss of data.
75
76
DISCLAIMER:
77
I TAKE NO RESPONSIBILITY FOR ANY LOSS OF DATA ARISING FROM THE
78
USE OF THIS PROGRAM, HOWSOEVER CAUSED.
79
80
Every compression of a file implies an assumption that the
81
compressed file can be decompressed to reproduce the original.
82
Great efforts in design, coding and testing have been made to
83
ensure that this program works correctly. However, the
84
complexity of the algorithms, and, in particular, the presence
85
of various special cases in the code which occur with very low
86
but non-zero probability make it impossible to rule out the
87
possibility of bugs remaining in the program. DO NOT COMPRESS
88
ANY DATA WITH THIS PROGRAM AND/OR LIBRARY UNLESS YOU ARE PREPARED
89
TO ACCEPT THE POSSIBILITY, HOWEVER SMALL, THAT THE DATA WILL
90
NOT BE RECOVERABLE.
91
92
That is not to say this program is inherently unreliable.
93
Indeed, I very much hope the opposite is true. bzip2/libbzip2
94
has been carefully constructed and extensively tested.
95
96
PATENTS:
97
To the best of my knowledge, bzip2/libbzip2 does not use any
98
patented algorithms. However, I do not have the resources
99
available to carry out a full patent search. Therefore I cannot
100
give any guarantee of the above statement.
101
--*/
102
103
104
105
/*----------------------------------------------------*/
106
/*--- and now for something much more pleasant :-) ---*/
107
/*----------------------------------------------------*/
108
109
/*---------------------------------------------*/
110
/*--
111
Some stuff for all platforms.
112
--*/
113
114
#include <bzlib.h>
115
#include <stdio.h>
116
#include <stdlib.h>
117
#include <string.h>
118
#include <signal.h>
119
#include <math.h>
120
121
#define ERROR_IF_EOF(i) { if ((i) == EOF) ioError(); }
122
#define ERROR_IF_NOT_ZERO(i) { if ((i) != 0) ioError(); }
123
#define ERROR_IF_MINUS_ONE(i) { if ((i) == (-1)) ioError(); }
124
125
#define panic bzpanic
126
127
/*---------------------------------------------*/
128
/*--
129
Platform-specific stuff.
130
--*/
131
132
#if BZ_UNIX
133
# if _PACKAGE_ast
134
# include <ast.h>
135
# include <ls.h>
136
# include <tm.h>
137
# else
138
# include <sys/types.h>
139
# include <unistd.h>
140
# include <sys/stat.h>
141
# include <sys/times.h>
142
# endif
143
144
# define PATH_SEP '/'
145
# define MY_LSTAT lstat
146
# define MY_S_IFREG S_ISREG
147
# define MY_STAT stat
148
149
# define APPEND_FILESPEC(root, name) \
150
root=snocString((root), (name))
151
152
# define SET_BINARY_MODE(fd) /**/
153
#endif
154
155
156
157
#if BZ_LCCWIN32
158
# include <io.h>
159
# include <fcntl.h>
160
# include <sys\stat.h>
161
162
# define PATH_SEP '\\'
163
# define MY_LSTAT _stat
164
# define MY_STAT _stat
165
# define MY_S_IFREG(x) ((x) & _S_IFREG)
166
167
# if 0
168
/*-- lcc-win32 seems to expand wildcards itself --*/
169
# define APPEND_FILESPEC(root, spec) \
170
do { \
171
if ((spec)[0] == '-') { \
172
root = snocString((root), (spec)); \
173
} else { \
174
struct _finddata_t c_file; \
175
long hFile; \
176
hFile = _findfirst((spec), &c_file); \
177
if ( hFile == -1L ) { \
178
root = snocString ((root), (spec)); \
179
} else { \
180
int anInt = 0; \
181
while ( anInt == 0 ) { \
182
root = snocString((root), \
183
&c_file.name[0]); \
184
anInt = _findnext(hFile, &c_file); \
185
} \
186
} \
187
} \
188
} while ( 0 )
189
# else
190
# define APPEND_FILESPEC(root, name) \
191
root = snocString ((root), (name))
192
# endif
193
194
# define SET_BINARY_MODE(fd) \
195
do { \
196
int retVal = setmode ( fileno ( fd ), \
197
O_BINARY ); \
198
ERROR_IF_MINUS_ONE ( retVal ); \
199
} while ( 0 )
200
201
#endif
202
203
204
/*---------------------------------------------*/
205
/*--
206
Some more stuff for all platforms :-)
207
--*/
208
209
typedef char Char;
210
typedef unsigned char Bool;
211
typedef unsigned char UChar;
212
typedef int Int32;
213
typedef unsigned int UInt32;
214
typedef short Int16;
215
typedef unsigned short UInt16;
216
217
#define True ((Bool)1)
218
#define False ((Bool)0)
219
220
/*--
221
IntNative is your platform's `native' int size.
222
Only here to avoid probs with 64-bit platforms.
223
--*/
224
typedef int IntNative;
225
226
227
/*---------------------------------------------------*/
228
/*--- Misc (file handling) data decls ---*/
229
/*---------------------------------------------------*/
230
231
Int32 verbosity;
232
Bool keepInputFiles, smallMode;
233
Bool forceOverwrite, testFailsExist;
234
Int32 numFileNames, numFilesProcessed, blockSize100k;
235
236
237
/*-- source modes; F==file, I==stdin, O==stdout --*/
238
#define SM_I2O 1
239
#define SM_F2O 2
240
#define SM_F2F 3
241
242
/*-- operation modes --*/
243
#define OM_Z 1
244
#define OM_UNZ 2
245
#define OM_TEST 3
246
247
Int32 opMode;
248
Int32 srcMode;
249
250
#define FILE_NAME_LEN 1034
251
252
Int32 longestFileName;
253
Char inName[FILE_NAME_LEN];
254
Char outName[FILE_NAME_LEN];
255
Char *progName;
256
Char progNameReally[FILE_NAME_LEN];
257
FILE *outputHandleJustInCase;
258
Int32 workFactor;
259
260
void panic ( Char* );
261
void ioError ( void );
262
void outOfMemory ( void );
263
void blockOverrun ( void );
264
void badBlockHeader ( void );
265
void badBGLengths ( void );
266
void crcError ( void );
267
void bitStreamEOF ( void );
268
void cleanUpAndFail ( Int32 );
269
void compressedStreamEOF ( void );
270
271
void copyFileName ( Char*, Char* );
272
void* myMalloc ( Int32 );
273
274
275
276
/*---------------------------------------------------*/
277
/*--- Processing of complete files and streams ---*/
278
/*---------------------------------------------------*/
279
280
/*---------------------------------------------*/
281
Bool myfeof ( FILE* f )
282
{
283
Int32 c = fgetc ( f );
284
if (c == EOF) return True;
285
ungetc ( c, f );
286
return False;
287
}
288
289
290
/*---------------------------------------------*/
291
void compressStream ( FILE *stream, FILE *zStream )
292
{
293
BZFILE* bzf = NULL;
294
UChar ibuf[5000];
295
Int32 nIbuf;
296
UInt32 nbytes_in, nbytes_out;
297
Int32 bzerr, bzerr_dummy, ret;
298
299
SET_BINARY_MODE(stream);
300
SET_BINARY_MODE(zStream);
301
302
if (ferror(stream)) goto errhandler_io;
303
if (ferror(zStream)) goto errhandler_io;
304
305
bzf = bzWriteOpen ( &bzerr, zStream,
306
blockSize100k, verbosity, workFactor );
307
if (bzerr != BZ_OK) goto errhandler;
308
309
if (verbosity >= 2) fprintf ( stderr, "\n" );
310
311
while (True) {
312
313
if (myfeof(stream)) break;
314
nIbuf = fread ( ibuf, sizeof(UChar), 5000, stream );
315
if (ferror(stream)) goto errhandler_io;
316
if (nIbuf > 0) bzWrite ( &bzerr, bzf, (void*)ibuf, nIbuf );
317
if (bzerr != BZ_OK) goto errhandler;
318
319
}
320
321
bzWriteClose ( &bzerr, bzf, 0, &nbytes_in, &nbytes_out );
322
if (bzerr != BZ_OK) goto errhandler;
323
324
if (ferror(zStream)) goto errhandler_io;
325
ret = fflush ( zStream );
326
if (ret == EOF) goto errhandler_io;
327
if (zStream != stdout) {
328
ret = fclose ( zStream );
329
if (ret == EOF) goto errhandler_io;
330
}
331
if (ferror(stream)) goto errhandler_io;
332
ret = fclose ( stream );
333
if (ret == EOF) goto errhandler_io;
334
335
if (nbytes_in == 0) nbytes_in = 1;
336
337
if (verbosity >= 1)
338
fprintf ( stderr, "%6.3f:1, %6.3f bits/byte, "
339
"%5.2f%% saved, %d in, %d out.\n",
340
(float)nbytes_in / (float)nbytes_out,
341
(8.0 * (float)nbytes_out) / (float)nbytes_in,
342
100.0 * (1.0 - (float)nbytes_out / (float)nbytes_in),
343
nbytes_in,
344
nbytes_out
345
);
346
347
return;
348
349
errhandler:
350
bzWriteClose ( &bzerr_dummy, bzf, 1, &nbytes_in, &nbytes_out );
351
switch (bzerr) {
352
case BZ_MEM_ERROR:
353
outOfMemory ();
354
case BZ_IO_ERROR:
355
errhandler_io:
356
ioError(); break;
357
default:
358
panic ( "compress:unexpected error" );
359
}
360
361
panic ( "compress:end" );
362
/*notreached*/
363
}
364
365
366
367
/*---------------------------------------------*/
368
Bool uncompressStream ( FILE *zStream, FILE *stream )
369
{
370
BZFILE* bzf = NULL;
371
Int32 bzerr, bzerr_dummy, ret, nread, streamNo, i;
372
UChar obuf[5000];
373
UChar unused[BZ_MAX_UNUSED];
374
Int32 nUnused;
375
UChar* unusedTmp;
376
377
nUnused = 0;
378
streamNo = 0;
379
380
SET_BINARY_MODE(stream);
381
SET_BINARY_MODE(zStream);
382
383
if (ferror(stream)) goto errhandler_io;
384
if (ferror(zStream)) goto errhandler_io;
385
386
while (True) {
387
388
bzf = bzReadOpen (
389
&bzerr, zStream, verbosity,
390
(int)smallMode, unused, nUnused
391
);
392
if (bzf == NULL || bzerr != BZ_OK) goto errhandler;
393
streamNo++;
394
395
while (bzerr == BZ_OK) {
396
nread = bzRead ( &bzerr, bzf, obuf, 5000 );
397
if (bzerr == BZ_DATA_ERROR_MAGIC) goto errhandler;
398
if ((bzerr == BZ_OK || bzerr == BZ_STREAM_END) && nread > 0)
399
fwrite ( obuf, sizeof(UChar), nread, stream );
400
if (ferror(stream)) goto errhandler_io;
401
}
402
if (bzerr != BZ_STREAM_END) goto errhandler;
403
404
bzReadGetUnused ( &bzerr, bzf, &unusedTmp, &nUnused );
405
if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" );
406
407
for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i];
408
409
bzReadClose ( &bzerr, bzf );
410
if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" );
411
412
if (nUnused == 0 && myfeof(zStream)) break;
413
414
}
415
416
if (ferror(zStream)) goto errhandler_io;
417
ret = fclose ( zStream );
418
if (ret == EOF) goto errhandler_io;
419
420
if (ferror(stream)) goto errhandler_io;
421
ret = fflush ( stream );
422
if (ret != 0) goto errhandler_io;
423
if (stream != stdout) {
424
ret = fclose ( stream );
425
if (ret == EOF) goto errhandler_io;
426
}
427
if (verbosity >= 2) fprintf ( stderr, "\n " );
428
return True;
429
430
errhandler:
431
bzReadClose ( &bzerr_dummy, bzf );
432
switch (bzerr) {
433
case BZ_IO_ERROR:
434
errhandler_io:
435
ioError(); break;
436
case BZ_DATA_ERROR:
437
crcError();
438
case BZ_MEM_ERROR:
439
outOfMemory();
440
case BZ_UNEXPECTED_EOF:
441
compressedStreamEOF();
442
case BZ_DATA_ERROR_MAGIC:
443
if (streamNo == 1) {
444
return False;
445
} else {
446
fprintf ( stderr,
447
"\n%s: %s: trailing garbage after EOF ignored\n",
448
progName, inName );
449
return True;
450
}
451
default:
452
panic ( "decompress:unexpected error" );
453
}
454
455
panic ( "decompress:end" );
456
return True; /*notreached*/
457
}
458
459
460
/*---------------------------------------------*/
461
Bool testStream ( FILE *zStream )
462
{
463
BZFILE* bzf = NULL;
464
Int32 bzerr, bzerr_dummy, ret, streamNo, i;
465
UChar obuf[5000];
466
UChar unused[BZ_MAX_UNUSED];
467
Int32 nUnused;
468
UChar* unusedTmp;
469
470
nUnused = 0;
471
streamNo = 0;
472
473
SET_BINARY_MODE(zStream);
474
if (ferror(zStream)) goto errhandler_io;
475
476
while (True) {
477
478
bzf = bzReadOpen (
479
&bzerr, zStream, verbosity,
480
(int)smallMode, unused, nUnused
481
);
482
if (bzf == NULL || bzerr != BZ_OK) goto errhandler;
483
streamNo++;
484
485
while (bzerr == BZ_OK) {
486
bzRead ( &bzerr, bzf, obuf, 5000 );
487
if (bzerr == BZ_DATA_ERROR_MAGIC) goto errhandler;
488
}
489
if (bzerr != BZ_STREAM_END) goto errhandler;
490
491
bzReadGetUnused ( &bzerr, bzf, &unusedTmp, &nUnused );
492
if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" );
493
494
for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i];
495
496
bzReadClose ( &bzerr, bzf );
497
if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" );
498
if (nUnused == 0 && myfeof(zStream)) break;
499
500
}
501
502
if (ferror(zStream)) goto errhandler_io;
503
ret = fclose ( zStream );
504
if (ret == EOF) goto errhandler_io;
505
506
if (verbosity >= 2) fprintf ( stderr, "\n " );
507
return True;
508
509
errhandler:
510
bzReadClose ( &bzerr_dummy, bzf );
511
switch (bzerr) {
512
case BZ_IO_ERROR:
513
errhandler_io:
514
ioError(); break;
515
case BZ_DATA_ERROR:
516
fprintf ( stderr,
517
"\n%s: data integrity (CRC) error in data\n",
518
inName );
519
return False;
520
case BZ_MEM_ERROR:
521
outOfMemory();
522
case BZ_UNEXPECTED_EOF:
523
fprintf ( stderr,
524
"\n%s: file ends unexpectedly\n",
525
inName );
526
return False;
527
case BZ_DATA_ERROR_MAGIC:
528
if (streamNo == 1) {
529
fprintf ( stderr,
530
"\n%s: bad magic number (ie, not created by bzip2)\n",
531
inName );
532
return False;
533
} else {
534
fprintf ( stderr,
535
"\n%s: %s: trailing garbage after EOF ignored\n",
536
progName, inName );
537
return True;
538
}
539
default:
540
panic ( "test:unexpected error" );
541
}
542
543
panic ( "test:end" );
544
return True; /*notreached*/
545
}
546
547
548
/*---------------------------------------------------*/
549
/*--- Error [non-] handling grunge ---*/
550
/*---------------------------------------------------*/
551
552
/*---------------------------------------------*/
553
void cadvise ( void )
554
{
555
fprintf (
556
stderr,
557
"\nIt is possible that the compressed file(s) have become corrupted.\n"
558
"You can use the -tvv option to test integrity of such files.\n\n"
559
"You can use the `bzip2recover' program to *attempt* to recover\n"
560
"data from undamaged sections of corrupted files.\n\n"
561
);
562
}
563
564
565
/*---------------------------------------------*/
566
void showFileNames ( void )
567
{
568
fprintf (
569
stderr,
570
"\tInput file = %s, output file = %s\n",
571
inName, outName
572
);
573
}
574
575
576
/*---------------------------------------------*/
577
void cleanUpAndFail ( Int32 ec )
578
{
579
IntNative retVal;
580
581
if ( srcMode == SM_F2F && opMode != OM_TEST ) {
582
fprintf ( stderr, "%s: Deleting output file %s, if it exists.\n",
583
progName, outName );
584
if (outputHandleJustInCase != NULL)
585
fclose ( outputHandleJustInCase );
586
retVal = remove ( outName );
587
if (retVal != 0)
588
fprintf ( stderr,
589
"%s: WARNING: deletion of output file (apparently) failed.\n",
590
progName );
591
}
592
if (numFileNames > 0 && numFilesProcessed < numFileNames) {
593
fprintf ( stderr,
594
"%s: WARNING: some files have not been processed:\n"
595
"\t%d specified on command line, %d not processed yet.\n\n",
596
progName, numFileNames,
597
numFileNames - numFilesProcessed );
598
}
599
exit ( ec );
600
}
601
602
603
/*---------------------------------------------*/
604
void panic ( Char* s )
605
{
606
fprintf ( stderr,
607
"\n%s: PANIC -- internal consistency error:\n"
608
"\t%s\n"
609
"\tThis is a BUG. Please report it to me at:\n"
610
"\[email protected]\n",
611
progName, s );
612
showFileNames();
613
cleanUpAndFail( 3 );
614
}
615
616
617
/*---------------------------------------------*/
618
void crcError ()
619
{
620
fprintf ( stderr,
621
"\n%s: Data integrity error when decompressing.\n",
622
progName );
623
showFileNames();
624
cadvise();
625
cleanUpAndFail( 2 );
626
}
627
628
629
/*---------------------------------------------*/
630
void compressedStreamEOF ( void )
631
{
632
fprintf ( stderr,
633
"\n%s: Compressed file ends unexpectedly;\n\t"
634
"perhaps it is corrupted? *Possible* reason follows.\n",
635
progName );
636
perror ( progName );
637
showFileNames();
638
cadvise();
639
cleanUpAndFail( 2 );
640
}
641
642
643
/*---------------------------------------------*/
644
void ioError ( )
645
{
646
fprintf ( stderr,
647
"\n%s: I/O or other error, bailing out. Possible reason follows.\n",
648
progName );
649
perror ( progName );
650
showFileNames();
651
cleanUpAndFail( 1 );
652
}
653
654
655
/*---------------------------------------------*/
656
void mySignalCatcher ( IntNative n )
657
{
658
fprintf ( stderr,
659
"\n%s: Control-C (or similar) caught, quitting.\n",
660
progName );
661
cleanUpAndFail(1);
662
}
663
664
665
/*---------------------------------------------*/
666
void mySIGSEGVorSIGBUScatcher ( IntNative n )
667
{
668
if (opMode == OM_Z)
669
fprintf ( stderr,
670
"\n%s: Caught a SIGSEGV or SIGBUS whilst compressing,\n"
671
"\twhich probably indicates a bug in bzip2. Please\n"
672
"\treport it to me at: [email protected]\n",
673
progName );
674
else
675
fprintf ( stderr,
676
"\n%s: Caught a SIGSEGV or SIGBUS whilst decompressing,\n"
677
"\twhich probably indicates that the compressed data\n"
678
"\tis corrupted.\n",
679
progName );
680
681
showFileNames();
682
if (opMode == OM_Z)
683
cleanUpAndFail( 3 ); else
684
{ cadvise(); cleanUpAndFail( 2 ); }
685
}
686
687
688
/*---------------------------------------------*/
689
void outOfMemory ( void )
690
{
691
fprintf ( stderr,
692
"\n%s: couldn't allocate enough memory\n",
693
progName );
694
showFileNames();
695
cleanUpAndFail(1);
696
}
697
698
699
/*---------------------------------------------------*/
700
/*--- The main driver machinery ---*/
701
/*---------------------------------------------------*/
702
703
/*---------------------------------------------*/
704
void pad ( Char *s )
705
{
706
Int32 i;
707
if ( (Int32)strlen(s) >= longestFileName ) return;
708
for (i = 1; i <= longestFileName - (Int32)strlen(s); i++)
709
fprintf ( stderr, " " );
710
}
711
712
713
/*---------------------------------------------*/
714
void copyFileName ( Char* to, Char* from )
715
{
716
if ( strlen(from) > FILE_NAME_LEN-10 ) {
717
fprintf (
718
stderr,
719
"bzip2: file name\n`%s'\nis suspiciously (> 1024 chars) long.\n"
720
"Try using a reasonable file name instead. Sorry! :)\n",
721
from
722
);
723
exit(1);
724
}
725
726
strncpy(to,from,FILE_NAME_LEN-10);
727
to[FILE_NAME_LEN-10]='\0';
728
}
729
730
731
/*---------------------------------------------*/
732
Bool fileExists ( Char* name )
733
{
734
FILE *tmp = fopen ( name, "rb" );
735
Bool exists = (tmp != NULL);
736
if (tmp != NULL) fclose ( tmp );
737
return exists;
738
}
739
740
741
/*---------------------------------------------*/
742
/*--
743
if in doubt, return True
744
--*/
745
Bool notAStandardFile ( Char* name )
746
{
747
IntNative i;
748
struct MY_STAT statBuf;
749
750
i = MY_LSTAT ( name, &statBuf );
751
if (i != 0) return True;
752
if (MY_S_IFREG(statBuf.st_mode)) return False;
753
return True;
754
}
755
756
757
/*---------------------------------------------*/
758
void copyDatePermissionsAndOwner ( Char *srcName, Char *dstName )
759
{
760
#if BZ_UNIX
761
IntNative retVal;
762
struct MY_STAT statBuf;
763
#if !_PACKAGE_ast
764
struct utimbuf uTimBuf;
765
#endif
766
767
retVal = MY_LSTAT ( srcName, &statBuf );
768
ERROR_IF_NOT_ZERO ( retVal );
769
#if !_PACKAGE_ast
770
uTimBuf.actime = statBuf.st_atime;
771
uTimBuf.modtime = statBuf.st_mtime;
772
#endif
773
774
retVal = chmod ( dstName, statBuf.st_mode );
775
ERROR_IF_NOT_ZERO ( retVal );
776
/* Not sure if this is really portable or not. Causes
777
problems on my x86-Linux Redhat 5.0 box. Decided
778
to omit it from 0.9.0. JRS, 27 June 98. If you
779
understand Unix file semantics and portability issues
780
well enough to fix this properly, drop me a line
781
at [email protected].
782
retVal = chown ( dstName, statBuf.st_uid, statBuf.st_gid );
783
ERROR_IF_NOT_ZERO ( retVal );
784
*/
785
#if _PACKAGE_ast
786
retVal = touch ( dstName, statBuf.st_atime, statBuf.st_mtime, 0 );
787
#else
788
retVal = utime ( dstName, &uTimBuf );
789
#endif
790
ERROR_IF_NOT_ZERO ( retVal );
791
#endif
792
}
793
794
795
/*---------------------------------------------*/
796
void setInterimPermissions ( Char *dstName )
797
{
798
#if BZ_UNIX
799
IntNative retVal;
800
retVal = chmod ( dstName, S_IRUSR | S_IWUSR );
801
ERROR_IF_NOT_ZERO ( retVal );
802
#endif
803
}
804
805
806
807
/*---------------------------------------------*/
808
Bool endsInBz2 ( Char* name )
809
{
810
Int32 n = strlen ( name );
811
if (n <= 4) return False;
812
return
813
(name[n-4] == '.' &&
814
name[n-3] == 'b' &&
815
name[n-2] == 'z' &&
816
name[n-1] == '2');
817
}
818
819
820
/*---------------------------------------------*/
821
Bool containsDubiousChars ( Char* name )
822
{
823
Bool cdc = False;
824
for (; *name != '\0'; name++)
825
if (*name == '?' || *name == '*') cdc = True;
826
return cdc;
827
}
828
829
830
/*---------------------------------------------*/
831
void compress ( Char *name )
832
{
833
FILE *inStr;
834
FILE *outStr;
835
836
if (name == NULL && srcMode != SM_I2O)
837
panic ( "compress: bad modes\n" );
838
839
switch (srcMode) {
840
case SM_I2O: copyFileName ( inName, "(stdin)" );
841
copyFileName ( outName, "(stdout)" ); break;
842
case SM_F2F: copyFileName ( inName, name );
843
copyFileName ( outName, name );
844
strcat ( outName, ".bz2" ); break;
845
case SM_F2O: copyFileName ( inName, name );
846
copyFileName ( outName, "(stdout)" ); break;
847
}
848
849
if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
850
fprintf ( stderr, "%s: There are no files matching `%s'.\n",
851
progName, inName );
852
return;
853
}
854
if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
855
fprintf ( stderr, "%s: Input file %s doesn't exist, skipping.\n",
856
progName, inName );
857
return;
858
}
859
if ( srcMode != SM_I2O && endsInBz2 ( inName )) {
860
fprintf ( stderr, "%s: Input file name %s ends in `.bz2', skipping.\n",
861
progName, inName );
862
return;
863
}
864
if ( srcMode != SM_I2O && notAStandardFile ( inName )) {
865
fprintf ( stderr, "%s: Input file %s is not a normal file, skipping.\n",
866
progName, inName );
867
return;
868
}
869
if ( srcMode == SM_F2F && !forceOverwrite && fileExists ( outName ) ) {
870
fprintf ( stderr, "%s: Output file %s already exists, skipping.\n",
871
progName, outName );
872
return;
873
}
874
875
switch ( srcMode ) {
876
877
case SM_I2O:
878
inStr = stdin;
879
outStr = stdout;
880
if ( isatty ( fileno ( stdout ) ) ) {
881
fprintf ( stderr,
882
"%s: I won't write compressed data to a terminal.\n",
883
progName );
884
fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
885
progName, progName );
886
return;
887
};
888
break;
889
890
case SM_F2O:
891
inStr = fopen ( inName, "rb" );
892
outStr = stdout;
893
if ( isatty ( fileno ( stdout ) ) ) {
894
fprintf ( stderr,
895
"%s: I won't write compressed data to a terminal.\n",
896
progName );
897
fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
898
progName, progName );
899
return;
900
};
901
if ( inStr == NULL ) {
902
fprintf ( stderr, "%s: Can't open input file %s, skipping.\n",
903
progName, inName );
904
return;
905
};
906
break;
907
908
case SM_F2F:
909
inStr = fopen ( inName, "rb" );
910
outStr = fopen ( outName, "wb" );
911
if ( outStr == NULL) {
912
fprintf ( stderr, "%s: Can't create output file %s, skipping.\n",
913
progName, outName );
914
return;
915
}
916
if ( inStr == NULL ) {
917
fprintf ( stderr, "%s: Can't open input file %s, skipping.\n",
918
progName, inName );
919
return;
920
};
921
setInterimPermissions ( outName );
922
break;
923
924
default:
925
panic ( "compress: bad srcMode" );
926
break;
927
}
928
929
if (verbosity >= 1) {
930
fprintf ( stderr, " %s: ", inName );
931
pad ( inName );
932
fflush ( stderr );
933
}
934
935
/*--- Now the input and output handles are sane. Do the Biz. ---*/
936
outputHandleJustInCase = outStr;
937
compressStream ( inStr, outStr );
938
outputHandleJustInCase = NULL;
939
940
/*--- If there was an I/O error, we won't get here. ---*/
941
if ( srcMode == SM_F2F ) {
942
copyDatePermissionsAndOwner ( inName, outName );
943
if ( !keepInputFiles ) {
944
IntNative retVal = remove ( inName );
945
ERROR_IF_NOT_ZERO ( retVal );
946
}
947
}
948
}
949
950
951
/*---------------------------------------------*/
952
void uncompress ( Char *name )
953
{
954
FILE *inStr;
955
FILE *outStr;
956
Bool magicNumberOK;
957
958
if (name == NULL && srcMode != SM_I2O)
959
panic ( "uncompress: bad modes\n" );
960
961
switch (srcMode) {
962
case SM_I2O: copyFileName ( inName, "(stdin)" );
963
copyFileName ( outName, "(stdout)" ); break;
964
case SM_F2F: copyFileName ( inName, name );
965
copyFileName ( outName, name );
966
if (endsInBz2 ( outName ))
967
outName [ strlen ( outName ) - 4 ] = '\0';
968
break;
969
case SM_F2O: copyFileName ( inName, name );
970
copyFileName ( outName, "(stdout)" ); break;
971
}
972
973
if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
974
fprintf ( stderr, "%s: There are no files matching `%s'.\n",
975
progName, inName );
976
return;
977
}
978
if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
979
fprintf ( stderr, "%s: Input file %s doesn't exist, skipping.\n",
980
progName, inName );
981
return;
982
}
983
if ( srcMode != SM_I2O && !endsInBz2 ( inName )) {
984
fprintf ( stderr,
985
"%s: Input file name %s doesn't end in `.bz2', skipping.\n",
986
progName, inName );
987
return;
988
}
989
if ( srcMode != SM_I2O && notAStandardFile ( inName )) {
990
fprintf ( stderr, "%s: Input file %s is not a normal file, skipping.\n",
991
progName, inName );
992
return;
993
}
994
if ( srcMode == SM_F2F && !forceOverwrite && fileExists ( outName ) ) {
995
fprintf ( stderr, "%s: Output file %s already exists, skipping.\n",
996
progName, outName );
997
return;
998
}
999
1000
switch ( srcMode ) {
1001
1002
case SM_I2O:
1003
inStr = stdin;
1004
outStr = stdout;
1005
if ( isatty ( fileno ( stdin ) ) ) {
1006
fprintf ( stderr,
1007
"%s: I won't read compressed data from a terminal.\n",
1008
progName );
1009
fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
1010
progName, progName );
1011
return;
1012
};
1013
break;
1014
1015
case SM_F2O:
1016
inStr = fopen ( inName, "rb" );
1017
outStr = stdout;
1018
if ( inStr == NULL ) {
1019
fprintf ( stderr, "%s: Can't open input file %s, skipping.\n",
1020
progName, inName );
1021
return;
1022
};
1023
break;
1024
1025
case SM_F2F:
1026
inStr = fopen ( inName, "rb" );
1027
outStr = fopen ( outName, "wb" );
1028
if ( outStr == NULL) {
1029
fprintf ( stderr, "%s: Can't create output file %s, skipping.\n",
1030
progName, outName );
1031
return;
1032
}
1033
if ( inStr == NULL ) {
1034
fprintf ( stderr, "%s: Can't open input file %s, skipping.\n",
1035
progName, inName );
1036
return;
1037
};
1038
setInterimPermissions ( outName );
1039
break;
1040
1041
default:
1042
panic ( "uncompress: bad srcMode" );
1043
break;
1044
}
1045
1046
if (verbosity >= 1) {
1047
fprintf ( stderr, " %s: ", inName );
1048
pad ( inName );
1049
fflush ( stderr );
1050
}
1051
1052
/*--- Now the input and output handles are sane. Do the Biz. ---*/
1053
outputHandleJustInCase = outStr;
1054
magicNumberOK = uncompressStream ( inStr, outStr );
1055
outputHandleJustInCase = NULL;
1056
1057
/*--- If there was an I/O error, we won't get here. ---*/
1058
if ( magicNumberOK ) {
1059
if ( srcMode == SM_F2F ) {
1060
copyDatePermissionsAndOwner ( inName, outName );
1061
if ( !keepInputFiles ) {
1062
IntNative retVal = remove ( inName );
1063
ERROR_IF_NOT_ZERO ( retVal );
1064
}
1065
}
1066
} else {
1067
if ( srcMode == SM_F2F ) {
1068
IntNative retVal = remove ( outName );
1069
ERROR_IF_NOT_ZERO ( retVal );
1070
}
1071
}
1072
1073
if ( magicNumberOK ) {
1074
if (verbosity >= 1)
1075
fprintf ( stderr, "done\n" );
1076
} else {
1077
if (verbosity >= 1)
1078
fprintf ( stderr, "not a bzip2 file, skipping.\n" ); else
1079
fprintf ( stderr,
1080
"%s: %s is not a bzip2 file, skipping.\n",
1081
progName, inName );
1082
}
1083
1084
}
1085
1086
1087
/*---------------------------------------------*/
1088
void testf ( Char *name )
1089
{
1090
FILE *inStr;
1091
Bool allOK;
1092
1093
if (name == NULL && srcMode != SM_I2O)
1094
panic ( "testf: bad modes\n" );
1095
1096
copyFileName ( outName, "(none)" );
1097
switch (srcMode) {
1098
case SM_I2O: copyFileName ( inName, "(stdin)" ); break;
1099
case SM_F2F: copyFileName ( inName, name ); break;
1100
case SM_F2O: copyFileName ( inName, name ); break;
1101
}
1102
1103
if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
1104
fprintf ( stderr, "%s: There are no files matching `%s'.\n",
1105
progName, inName );
1106
return;
1107
}
1108
if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
1109
fprintf ( stderr, "%s: Input file %s doesn't exist, skipping.\n",
1110
progName, inName );
1111
return;
1112
}
1113
if ( srcMode != SM_I2O && !endsInBz2 ( inName )) {
1114
fprintf ( stderr,
1115
"%s: Input file name %s doesn't end in `.bz2', skipping.\n",
1116
progName, inName );
1117
return;
1118
}
1119
if ( srcMode != SM_I2O && notAStandardFile ( inName )) {
1120
fprintf ( stderr, "%s: Input file %s is not a normal file, skipping.\n",
1121
progName, inName );
1122
return;
1123
}
1124
1125
switch ( srcMode ) {
1126
1127
case SM_I2O:
1128
if ( isatty ( fileno ( stdin ) ) ) {
1129
fprintf ( stderr,
1130
"%s: I won't read compressed data from a terminal.\n",
1131
progName );
1132
fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
1133
progName, progName );
1134
return;
1135
};
1136
inStr = stdin;
1137
break;
1138
1139
case SM_F2O: case SM_F2F:
1140
inStr = fopen ( inName, "rb" );
1141
if ( inStr == NULL ) {
1142
fprintf ( stderr, "%s: Can't open input file %s, skipping.\n",
1143
progName, inName );
1144
return;
1145
};
1146
break;
1147
1148
default:
1149
panic ( "testf: bad srcMode" );
1150
break;
1151
}
1152
1153
if (verbosity >= 1) {
1154
fprintf ( stderr, " %s: ", inName );
1155
pad ( inName );
1156
fflush ( stderr );
1157
}
1158
1159
/*--- Now the input handle is sane. Do the Biz. ---*/
1160
allOK = testStream ( inStr );
1161
1162
if (allOK && verbosity >= 1) fprintf ( stderr, "ok\n" );
1163
if (!allOK) testFailsExist = True;
1164
}
1165
1166
1167
/*---------------------------------------------*/
1168
void license ( void )
1169
{
1170
fprintf ( stderr,
1171
1172
"bzip2, a block-sorting file compressor. "
1173
"Version 0.9.0c, 18-Oct-98.\n"
1174
" \n"
1175
" Copyright (C) 1996, 1997, 1998 by Julian Seward.\n"
1176
" \n"
1177
" This program is free software; you can redistribute it and/or modify\n"
1178
" it under the terms set out in the LICENSE file, which is included\n"
1179
" in the bzip2-0.9.0c source distribution.\n"
1180
" \n"
1181
" This program is distributed in the hope that it will be useful,\n"
1182
" but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
1183
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
1184
" LICENSE file for more details.\n"
1185
" \n"
1186
);
1187
}
1188
1189
1190
/*---------------------------------------------*/
1191
void usage ( Char *fullProgName )
1192
{
1193
fprintf (
1194
stderr,
1195
"bzip2, a block-sorting file compressor. "
1196
"Version 0.9.0c, 18-Oct-98.\n"
1197
"\n usage: %s [flags and input files in any order]\n"
1198
"\n"
1199
" -h --help print this message\n"
1200
" -d --decompress force decompression\n"
1201
" -z --compress force compression\n"
1202
" -k --keep keep (don't delete) input files\n"
1203
" -f --force overwrite existing output filess\n"
1204
" -t --test test compressed file integrity\n"
1205
" -c --stdout output to standard out\n"
1206
" -v --verbose be verbose (a 2nd -v gives more)\n"
1207
" -L --license display software version & license\n"
1208
" -V --version display software version & license\n"
1209
" -s --small use less memory (at most 2500k)\n"
1210
" -1 .. -9 set block size to 100k .. 900k\n"
1211
" --repetitive-fast compress repetitive blocks faster\n"
1212
" --repetitive-best compress repetitive blocks better\n"
1213
"\n"
1214
" If invoked as `bzip2', default action is to compress.\n"
1215
" as `bunzip2', default action is to decompress.\n"
1216
" as `bz2cat', default action is to decompress to stdout.\n"
1217
"\n"
1218
" If no file names are given, bzip2 compresses or decompresses\n"
1219
" from standard input to standard output. You can combine\n"
1220
" short flags, so `-v -4' means the same as -v4 or -4v, &c.\n"
1221
#if BZ_UNIX
1222
"\n"
1223
#endif
1224
,
1225
1226
fullProgName
1227
);
1228
}
1229
1230
1231
/*---------------------------------------------*/
1232
/*--
1233
All the garbage from here to main() is purely to
1234
implement a linked list of command-line arguments,
1235
into which main() copies argv[1 .. argc-1].
1236
1237
The purpose of this ridiculous exercise is to
1238
facilitate the expansion of wildcard characters
1239
* and ? in filenames for halfwitted OSs like
1240
MSDOS, Windows 95 and NT.
1241
1242
The actual Dirty Work is done by the platform-specific
1243
macro APPEND_FILESPEC.
1244
--*/
1245
1246
typedef
1247
struct zzzz {
1248
Char *name;
1249
struct zzzz *link;
1250
}
1251
Cell;
1252
1253
1254
/*---------------------------------------------*/
1255
void *myMalloc ( Int32 n )
1256
{
1257
void* p;
1258
1259
p = malloc ( (size_t)n );
1260
if (p == NULL) outOfMemory ();
1261
return p;
1262
}
1263
1264
1265
/*---------------------------------------------*/
1266
Cell *mkCell ( void )
1267
{
1268
Cell *c;
1269
1270
c = (Cell*) myMalloc ( sizeof ( Cell ) );
1271
c->name = NULL;
1272
c->link = NULL;
1273
return c;
1274
}
1275
1276
1277
/*---------------------------------------------*/
1278
Cell *snocString ( Cell *root, Char *name )
1279
{
1280
if (root == NULL) {
1281
Cell *tmp = mkCell();
1282
tmp->name = (Char*) myMalloc ( 5 + strlen(name) );
1283
strcpy ( tmp->name, name );
1284
return tmp;
1285
} else {
1286
Cell *tmp = root;
1287
while (tmp->link != NULL) tmp = tmp->link;
1288
tmp->link = snocString ( tmp->link, name );
1289
return root;
1290
}
1291
}
1292
1293
1294
/*---------------------------------------------*/
1295
#define ISFLAG(s) (strcmp(aa->name, (s))==0)
1296
1297
1298
IntNative main ( IntNative argc, Char *argv[] )
1299
{
1300
Int32 i, j;
1301
Char *tmp;
1302
Cell *argList;
1303
Cell *aa;
1304
1305
/*-- Be really really really paranoid :-) --*/
1306
if (sizeof(Int32) != 4 || sizeof(UInt32) != 4 ||
1307
sizeof(Int16) != 2 || sizeof(UInt16) != 2 ||
1308
sizeof(Char) != 1 || sizeof(UChar) != 1) {
1309
fprintf ( stderr,
1310
"bzip2: I'm not configured correctly for this platform!\n"
1311
"\tI require Int32, Int16 and Char to have sizes\n"
1312
"\tof 4, 2 and 1 bytes to run properly, and they don't.\n"
1313
"\tProbably you can fix this by defining them correctly,\n"
1314
"\tand recompiling. Bye!\n" );
1315
exit(3);
1316
}
1317
1318
1319
/*-- Set up signal handlers --*/
1320
signal (SIGINT, mySignalCatcher);
1321
signal (SIGTERM, mySignalCatcher);
1322
signal (SIGSEGV, mySIGSEGVorSIGBUScatcher);
1323
#if BZ_UNIX
1324
signal (SIGHUP, mySignalCatcher);
1325
signal (SIGBUS, mySIGSEGVorSIGBUScatcher);
1326
#endif
1327
1328
1329
/*-- Initialise --*/
1330
outputHandleJustInCase = NULL;
1331
smallMode = False;
1332
keepInputFiles = False;
1333
forceOverwrite = False;
1334
verbosity = 0;
1335
blockSize100k = 9;
1336
testFailsExist = False;
1337
numFileNames = 0;
1338
numFilesProcessed = 0;
1339
workFactor = 30;
1340
1341
copyFileName ( inName, "(none)" );
1342
copyFileName ( outName, "(none)" );
1343
1344
copyFileName ( progNameReally, argv[0] );
1345
progName = &progNameReally[0];
1346
for (tmp = &progNameReally[0]; *tmp != '\0'; tmp++)
1347
if (*tmp == PATH_SEP) progName = tmp + 1;
1348
1349
1350
/*-- Expand filename wildcards in arg list --*/
1351
argList = NULL;
1352
for (i = 1; i <= argc-1; i++)
1353
APPEND_FILESPEC(argList, argv[i]);
1354
1355
1356
/*-- Find the length of the longest filename --*/
1357
longestFileName = 7;
1358
numFileNames = 0;
1359
for (aa = argList; aa != NULL; aa = aa->link)
1360
if (aa->name[0] != '-') {
1361
numFileNames++;
1362
if (longestFileName < (Int32)strlen(aa->name) )
1363
longestFileName = (Int32)strlen(aa->name);
1364
}
1365
1366
1367
/*-- Determine source modes; flag handling may change this too. --*/
1368
if (numFileNames == 0)
1369
srcMode = SM_I2O; else srcMode = SM_F2F;
1370
1371
1372
/*-- Determine what to do (compress/uncompress/test/cat). --*/
1373
/*-- Note that subsequent flag handling may change this. --*/
1374
opMode = OM_Z;
1375
tmp = progName;
1376
for (;;)
1377
{
1378
switch (*tmp++)
1379
{
1380
case 0:
1381
break;
1382
case 'u':
1383
case 'U':
1384
if (!strncasecmp(tmp, "nzip", 4))
1385
{
1386
opMode = OM_UNZ;
1387
break;
1388
}
1389
continue;
1390
case 'z':
1391
case 'Z':
1392
if (!strncasecmp(tmp, "zcat", 4) || !strncasecmp(tmp, "z2cat", 5))
1393
{
1394
opMode = OM_UNZ;
1395
srcMode = (numFileNames == 0) ? SM_I2O : SM_F2O;
1396
break;
1397
}
1398
continue;
1399
default:
1400
continue;
1401
}
1402
break;
1403
}
1404
1405
/*-- Look at the flags. --*/
1406
for (aa = argList; aa != NULL; aa = aa->link)
1407
if (aa->name[0] == '-' && aa->name[1] != '-')
1408
for (j = 1; aa->name[j] != '\0'; j++)
1409
switch (aa->name[j]) {
1410
case 'c': srcMode = SM_F2O; break;
1411
case 'd': opMode = OM_UNZ; break;
1412
case 'z': opMode = OM_Z; break;
1413
case 'f': forceOverwrite = True; break;
1414
case 't': opMode = OM_TEST; break;
1415
case 'k': keepInputFiles = True; break;
1416
case 's': smallMode = True; break;
1417
case '1': blockSize100k = 1; break;
1418
case '2': blockSize100k = 2; break;
1419
case '3': blockSize100k = 3; break;
1420
case '4': blockSize100k = 4; break;
1421
case '5': blockSize100k = 5; break;
1422
case '6': blockSize100k = 6; break;
1423
case '7': blockSize100k = 7; break;
1424
case '8': blockSize100k = 8; break;
1425
case '9': blockSize100k = 9; break;
1426
case 'V':
1427
case 'L': license(); break;
1428
case 'v': verbosity++; break;
1429
case 'h': usage ( progName );
1430
exit ( 1 );
1431
break;
1432
default: fprintf ( stderr, "%s: Bad flag `%s'\n",
1433
progName, aa->name );
1434
usage ( progName );
1435
exit ( 1 );
1436
break;
1437
}
1438
1439
/*-- And again ... --*/
1440
for (aa = argList; aa != NULL; aa = aa->link) {
1441
if (ISFLAG("--stdout")) srcMode = SM_F2O; else
1442
if (ISFLAG("--decompress")) opMode = OM_UNZ; else
1443
if (ISFLAG("--compress")) opMode = OM_Z; else
1444
if (ISFLAG("--force")) forceOverwrite = True; else
1445
if (ISFLAG("--test")) opMode = OM_TEST; else
1446
if (ISFLAG("--keep")) keepInputFiles = True; else
1447
if (ISFLAG("--small")) smallMode = True; else
1448
if (ISFLAG("--version")) license(); else
1449
if (ISFLAG("--license")) license(); else
1450
if (ISFLAG("--repetitive-fast")) workFactor = 5; else
1451
if (ISFLAG("--repetitive-best")) workFactor = 150; else
1452
if (ISFLAG("--verbose")) verbosity++; else
1453
if (ISFLAG("--help")) { usage ( progName ); exit ( 1 ); }
1454
else
1455
if (strncmp ( aa->name, "--", 2) == 0) {
1456
fprintf ( stderr, "%s: Bad flag `%s'\n", progName, aa->name );
1457
usage ( progName );
1458
exit ( 1 );
1459
}
1460
}
1461
1462
if (verbosity > 4) verbosity = 4;
1463
if (opMode == OM_Z && smallMode) blockSize100k = 2;
1464
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
1471
if (opMode == OM_TEST && srcMode == SM_F2O) {
1472
fprintf ( stderr, "%s: -c and -t cannot be used together.\n",
1473
progName );
1474
exit ( 1 );
1475
}
1476
1477
if (opMode != OM_Z) blockSize100k = 0;
1478
1479
if (opMode == OM_Z) {
1480
if (srcMode == SM_I2O)
1481
compress ( NULL );
1482
else
1483
for (aa = argList; aa != NULL; aa = aa->link)
1484
if (aa->name[0] != '-') {
1485
numFilesProcessed++;
1486
compress ( aa->name );
1487
}
1488
} else
1489
if (opMode == OM_UNZ) {
1490
if (srcMode == SM_I2O)
1491
uncompress ( NULL );
1492
else
1493
for (aa = argList; aa != NULL; aa = aa->link)
1494
if (aa->name[0] != '-') {
1495
numFilesProcessed++;
1496
uncompress ( aa->name );
1497
}
1498
} else {
1499
testFailsExist = False;
1500
if (srcMode == SM_I2O)
1501
testf ( NULL );
1502
else
1503
for (aa = argList; aa != NULL; aa = aa->link)
1504
if (aa->name[0] != '-') {
1505
numFilesProcessed++;
1506
testf ( aa->name );
1507
}
1508
if (testFailsExist) {
1509
fprintf ( stderr,
1510
"\n"
1511
"You can use the `bzip2recover' program to *attempt* to recover\n"
1512
"data from undamaged sections of corrupted files.\n\n"
1513
);
1514
exit(2);
1515
}
1516
}
1517
return 0;
1518
}
1519
1520
1521
/*-----------------------------------------------------------*/
1522
/*--- end bzip2.c ---*/
1523
/*-----------------------------------------------------------*/
1524
1525