171e7ee59SPeter Avalos
271e7ee59SPeter Avalos /*-----------------------------------------------------------*/
371e7ee59SPeter Avalos /*--- A block-sorting, lossless compressor bzip2.c ---*/
471e7ee59SPeter Avalos /*-----------------------------------------------------------*/
571e7ee59SPeter Avalos
671e7ee59SPeter Avalos /* ------------------------------------------------------------------
771e7ee59SPeter Avalos This file is part of bzip2/libbzip2, a program and library for
871e7ee59SPeter Avalos lossless, block-sorting data compression.
971e7ee59SPeter Avalos
10*86954436SDaniel Fojt bzip2/libbzip2 version 1.0.8 of 13 July 2019
11*86954436SDaniel Fojt Copyright (C) 1996-2019 Julian Seward <jseward@acm.org>
1271e7ee59SPeter Avalos
1371e7ee59SPeter Avalos Please read the WARNING, DISCLAIMER and PATENTS sections in the
1471e7ee59SPeter Avalos README file.
1571e7ee59SPeter Avalos
1671e7ee59SPeter Avalos This program is released under the terms of the license contained
1771e7ee59SPeter Avalos in the file LICENSE.
1871e7ee59SPeter Avalos ------------------------------------------------------------------ */
1971e7ee59SPeter Avalos
2071e7ee59SPeter Avalos
2171e7ee59SPeter Avalos /* Place a 1 beside your platform, and 0 elsewhere.
2271e7ee59SPeter Avalos Generic 32-bit Unix.
2371e7ee59SPeter Avalos Also works on 64-bit Unix boxes.
2471e7ee59SPeter Avalos This is the default.
2571e7ee59SPeter Avalos */
2671e7ee59SPeter Avalos #define BZ_UNIX 1
2771e7ee59SPeter Avalos
2871e7ee59SPeter Avalos /*--
2971e7ee59SPeter Avalos Win32, as seen by Jacob Navia's excellent
3071e7ee59SPeter Avalos port of (Chris Fraser & David Hanson)'s excellent
3171e7ee59SPeter Avalos lcc compiler. Or with MS Visual C.
3271e7ee59SPeter Avalos This is selected automatically if compiled by a compiler which
3371e7ee59SPeter Avalos defines _WIN32, not including the Cygwin GCC.
3471e7ee59SPeter Avalos --*/
3571e7ee59SPeter Avalos #define BZ_LCCWIN32 0
3671e7ee59SPeter Avalos
3771e7ee59SPeter Avalos #if defined(_WIN32) && !defined(__CYGWIN__)
3871e7ee59SPeter Avalos #undef BZ_LCCWIN32
3971e7ee59SPeter Avalos #define BZ_LCCWIN32 1
4071e7ee59SPeter Avalos #undef BZ_UNIX
4171e7ee59SPeter Avalos #define BZ_UNIX 0
4271e7ee59SPeter Avalos #endif
4371e7ee59SPeter Avalos
4471e7ee59SPeter Avalos
4571e7ee59SPeter Avalos /*---------------------------------------------*/
4671e7ee59SPeter Avalos /*--
4771e7ee59SPeter Avalos Some stuff for all platforms.
4871e7ee59SPeter Avalos --*/
4971e7ee59SPeter Avalos
5071e7ee59SPeter Avalos #include <stdio.h>
5171e7ee59SPeter Avalos #include <stdlib.h>
5271e7ee59SPeter Avalos #include <string.h>
5371e7ee59SPeter Avalos #include <signal.h>
5471e7ee59SPeter Avalos #include <math.h>
5571e7ee59SPeter Avalos #include <errno.h>
5671e7ee59SPeter Avalos #include <ctype.h>
5771e7ee59SPeter Avalos #include "bzlib.h"
5871e7ee59SPeter Avalos
5971e7ee59SPeter Avalos #define ERROR_IF_EOF(i) { if ((i) == EOF) ioError(); }
6071e7ee59SPeter Avalos #define ERROR_IF_NOT_ZERO(i) { if ((i) != 0) ioError(); }
6171e7ee59SPeter Avalos #define ERROR_IF_MINUS_ONE(i) { if ((i) == (-1)) ioError(); }
6271e7ee59SPeter Avalos
6371e7ee59SPeter Avalos
6471e7ee59SPeter Avalos /*---------------------------------------------*/
6571e7ee59SPeter Avalos /*--
6671e7ee59SPeter Avalos Platform-specific stuff.
6771e7ee59SPeter Avalos --*/
6871e7ee59SPeter Avalos
6971e7ee59SPeter Avalos #if BZ_UNIX
7071e7ee59SPeter Avalos # include <fcntl.h>
7171e7ee59SPeter Avalos # include <sys/types.h>
7271e7ee59SPeter Avalos # include <utime.h>
7371e7ee59SPeter Avalos # include <unistd.h>
7471e7ee59SPeter Avalos # include <sys/stat.h>
7571e7ee59SPeter Avalos # include <sys/times.h>
7671e7ee59SPeter Avalos
7771e7ee59SPeter Avalos # define PATH_SEP '/'
7871e7ee59SPeter Avalos # define MY_LSTAT lstat
7971e7ee59SPeter Avalos # define MY_STAT stat
8071e7ee59SPeter Avalos # define MY_S_ISREG S_ISREG
8171e7ee59SPeter Avalos # define MY_S_ISDIR S_ISDIR
8271e7ee59SPeter Avalos
8371e7ee59SPeter Avalos # define APPEND_FILESPEC(root, name) \
8471e7ee59SPeter Avalos root=snocString((root), (name))
8571e7ee59SPeter Avalos
8671e7ee59SPeter Avalos # define APPEND_FLAG(root, name) \
8771e7ee59SPeter Avalos root=snocString((root), (name))
8871e7ee59SPeter Avalos
8971e7ee59SPeter Avalos # define SET_BINARY_MODE(fd) /**/
9071e7ee59SPeter Avalos
9171e7ee59SPeter Avalos # ifdef __GNUC__
9271e7ee59SPeter Avalos # define NORETURN __attribute__ ((noreturn))
9371e7ee59SPeter Avalos # else
9471e7ee59SPeter Avalos # define NORETURN /**/
9571e7ee59SPeter Avalos # endif
9671e7ee59SPeter Avalos
9771e7ee59SPeter Avalos # ifdef __DJGPP__
9871e7ee59SPeter Avalos # include <io.h>
9971e7ee59SPeter Avalos # include <fcntl.h>
10071e7ee59SPeter Avalos # undef MY_LSTAT
10171e7ee59SPeter Avalos # undef MY_STAT
10271e7ee59SPeter Avalos # define MY_LSTAT stat
10371e7ee59SPeter Avalos # define MY_STAT stat
10471e7ee59SPeter Avalos # undef SET_BINARY_MODE
10571e7ee59SPeter Avalos # define SET_BINARY_MODE(fd) \
10671e7ee59SPeter Avalos do { \
10771e7ee59SPeter Avalos int retVal = setmode ( fileno ( fd ), \
10871e7ee59SPeter Avalos O_BINARY ); \
10971e7ee59SPeter Avalos ERROR_IF_MINUS_ONE ( retVal ); \
11071e7ee59SPeter Avalos } while ( 0 )
11171e7ee59SPeter Avalos # endif
11271e7ee59SPeter Avalos
11371e7ee59SPeter Avalos # ifdef __CYGWIN__
11471e7ee59SPeter Avalos # include <io.h>
11571e7ee59SPeter Avalos # include <fcntl.h>
11671e7ee59SPeter Avalos # undef SET_BINARY_MODE
11771e7ee59SPeter Avalos # define SET_BINARY_MODE(fd) \
11871e7ee59SPeter Avalos do { \
11971e7ee59SPeter Avalos int retVal = setmode ( fileno ( fd ), \
12071e7ee59SPeter Avalos O_BINARY ); \
12171e7ee59SPeter Avalos ERROR_IF_MINUS_ONE ( retVal ); \
12271e7ee59SPeter Avalos } while ( 0 )
12371e7ee59SPeter Avalos # endif
12471e7ee59SPeter Avalos #endif /* BZ_UNIX */
12571e7ee59SPeter Avalos
12671e7ee59SPeter Avalos
12771e7ee59SPeter Avalos
12871e7ee59SPeter Avalos #if BZ_LCCWIN32
12971e7ee59SPeter Avalos # include <io.h>
13071e7ee59SPeter Avalos # include <fcntl.h>
131*86954436SDaniel Fojt # include <sys/stat.h>
13271e7ee59SPeter Avalos
13371e7ee59SPeter Avalos # define NORETURN /**/
13471e7ee59SPeter Avalos # define PATH_SEP '\\'
135*86954436SDaniel Fojt # define MY_LSTAT _stati64
136*86954436SDaniel Fojt # define MY_STAT _stati64
13771e7ee59SPeter Avalos # define MY_S_ISREG(x) ((x) & _S_IFREG)
13871e7ee59SPeter Avalos # define MY_S_ISDIR(x) ((x) & _S_IFDIR)
13971e7ee59SPeter Avalos
14071e7ee59SPeter Avalos # define APPEND_FLAG(root, name) \
14171e7ee59SPeter Avalos root=snocString((root), (name))
14271e7ee59SPeter Avalos
14371e7ee59SPeter Avalos # define APPEND_FILESPEC(root, name) \
14471e7ee59SPeter Avalos root = snocString ((root), (name))
14571e7ee59SPeter Avalos
14671e7ee59SPeter Avalos # define SET_BINARY_MODE(fd) \
14771e7ee59SPeter Avalos do { \
14871e7ee59SPeter Avalos int retVal = setmode ( fileno ( fd ), \
14971e7ee59SPeter Avalos O_BINARY ); \
15071e7ee59SPeter Avalos ERROR_IF_MINUS_ONE ( retVal ); \
15171e7ee59SPeter Avalos } while ( 0 )
15271e7ee59SPeter Avalos
15371e7ee59SPeter Avalos #endif /* BZ_LCCWIN32 */
15471e7ee59SPeter Avalos
15571e7ee59SPeter Avalos
15671e7ee59SPeter Avalos /*---------------------------------------------*/
15771e7ee59SPeter Avalos /*--
15871e7ee59SPeter Avalos Some more stuff for all platforms :-)
15971e7ee59SPeter Avalos --*/
16071e7ee59SPeter Avalos
16171e7ee59SPeter Avalos typedef char Char;
16271e7ee59SPeter Avalos typedef unsigned char Bool;
16371e7ee59SPeter Avalos typedef unsigned char UChar;
16471e7ee59SPeter Avalos typedef int Int32;
16571e7ee59SPeter Avalos typedef unsigned int UInt32;
16671e7ee59SPeter Avalos typedef short Int16;
16771e7ee59SPeter Avalos typedef unsigned short UInt16;
16871e7ee59SPeter Avalos
16971e7ee59SPeter Avalos #define True ((Bool)1)
17071e7ee59SPeter Avalos #define False ((Bool)0)
17171e7ee59SPeter Avalos
17271e7ee59SPeter Avalos /*--
17371e7ee59SPeter Avalos IntNative is your platform's `native' int size.
17471e7ee59SPeter Avalos Only here to avoid probs with 64-bit platforms.
17571e7ee59SPeter Avalos --*/
17671e7ee59SPeter Avalos typedef int IntNative;
17771e7ee59SPeter Avalos
17871e7ee59SPeter Avalos
17971e7ee59SPeter Avalos /*---------------------------------------------------*/
18071e7ee59SPeter Avalos /*--- Misc (file handling) data decls ---*/
18171e7ee59SPeter Avalos /*---------------------------------------------------*/
18271e7ee59SPeter Avalos
18371e7ee59SPeter Avalos Int32 verbosity;
18471e7ee59SPeter Avalos Bool keepInputFiles, smallMode, deleteOutputOnInterrupt;
18571e7ee59SPeter Avalos Bool forceOverwrite, testFailsExist, unzFailsExist, noisy;
18671e7ee59SPeter Avalos Int32 numFileNames, numFilesProcessed, blockSize100k;
18771e7ee59SPeter Avalos Int32 exitValue;
18871e7ee59SPeter Avalos
18971e7ee59SPeter Avalos /*-- source modes; F==file, I==stdin, O==stdout --*/
19071e7ee59SPeter Avalos #define SM_I2O 1
19171e7ee59SPeter Avalos #define SM_F2O 2
19271e7ee59SPeter Avalos #define SM_F2F 3
19371e7ee59SPeter Avalos
19471e7ee59SPeter Avalos /*-- operation modes --*/
19571e7ee59SPeter Avalos #define OM_Z 1
19671e7ee59SPeter Avalos #define OM_UNZ 2
19771e7ee59SPeter Avalos #define OM_TEST 3
19871e7ee59SPeter Avalos
19971e7ee59SPeter Avalos Int32 opMode;
20071e7ee59SPeter Avalos Int32 srcMode;
20171e7ee59SPeter Avalos
20271e7ee59SPeter Avalos #define FILE_NAME_LEN 1034
20371e7ee59SPeter Avalos
20471e7ee59SPeter Avalos Int32 longestFileName;
20571e7ee59SPeter Avalos Char inName [FILE_NAME_LEN];
20671e7ee59SPeter Avalos Char outName[FILE_NAME_LEN];
20771e7ee59SPeter Avalos Char tmpName[FILE_NAME_LEN];
20871e7ee59SPeter Avalos Char *progName;
20971e7ee59SPeter Avalos Char progNameReally[FILE_NAME_LEN];
21071e7ee59SPeter Avalos FILE *outputHandleJustInCase;
21171e7ee59SPeter Avalos Int32 workFactor;
21271e7ee59SPeter Avalos
21371e7ee59SPeter Avalos static void panic ( const Char* ) NORETURN;
21471e7ee59SPeter Avalos static void ioError ( void ) NORETURN;
21571e7ee59SPeter Avalos static void outOfMemory ( void ) NORETURN;
21671e7ee59SPeter Avalos static void configError ( void ) NORETURN;
21771e7ee59SPeter Avalos static void crcError ( void ) NORETURN;
21871e7ee59SPeter Avalos static void cleanUpAndFail ( Int32 ) NORETURN;
21971e7ee59SPeter Avalos static void compressedStreamEOF ( void ) NORETURN;
22071e7ee59SPeter Avalos
22171e7ee59SPeter Avalos static void copyFileName ( Char*, Char* );
22271e7ee59SPeter Avalos static void* myMalloc ( Int32 );
22371e7ee59SPeter Avalos static void applySavedFileAttrToOutputFile ( IntNative fd );
22471e7ee59SPeter Avalos
22571e7ee59SPeter Avalos
22671e7ee59SPeter Avalos
22771e7ee59SPeter Avalos /*---------------------------------------------------*/
22871e7ee59SPeter Avalos /*--- An implementation of 64-bit ints. Sigh. ---*/
22971e7ee59SPeter Avalos /*--- Roll on widespread deployment of ANSI C9X ! ---*/
23071e7ee59SPeter Avalos /*---------------------------------------------------*/
23171e7ee59SPeter Avalos
23271e7ee59SPeter Avalos typedef
23371e7ee59SPeter Avalos struct { UChar b[8]; }
23471e7ee59SPeter Avalos UInt64;
23571e7ee59SPeter Avalos
23671e7ee59SPeter Avalos
23771e7ee59SPeter Avalos static
uInt64_from_UInt32s(UInt64 * n,UInt32 lo32,UInt32 hi32)23871e7ee59SPeter Avalos void uInt64_from_UInt32s ( UInt64* n, UInt32 lo32, UInt32 hi32 )
23971e7ee59SPeter Avalos {
24071e7ee59SPeter Avalos n->b[7] = (UChar)((hi32 >> 24) & 0xFF);
24171e7ee59SPeter Avalos n->b[6] = (UChar)((hi32 >> 16) & 0xFF);
24271e7ee59SPeter Avalos n->b[5] = (UChar)((hi32 >> 8) & 0xFF);
24371e7ee59SPeter Avalos n->b[4] = (UChar) (hi32 & 0xFF);
24471e7ee59SPeter Avalos n->b[3] = (UChar)((lo32 >> 24) & 0xFF);
24571e7ee59SPeter Avalos n->b[2] = (UChar)((lo32 >> 16) & 0xFF);
24671e7ee59SPeter Avalos n->b[1] = (UChar)((lo32 >> 8) & 0xFF);
24771e7ee59SPeter Avalos n->b[0] = (UChar) (lo32 & 0xFF);
24871e7ee59SPeter Avalos }
24971e7ee59SPeter Avalos
25071e7ee59SPeter Avalos
25171e7ee59SPeter Avalos static
uInt64_to_double(UInt64 * n)25271e7ee59SPeter Avalos double uInt64_to_double ( UInt64* n )
25371e7ee59SPeter Avalos {
25471e7ee59SPeter Avalos Int32 i;
25571e7ee59SPeter Avalos double base = 1.0;
25671e7ee59SPeter Avalos double sum = 0.0;
25771e7ee59SPeter Avalos for (i = 0; i < 8; i++) {
25871e7ee59SPeter Avalos sum += base * (double)(n->b[i]);
25971e7ee59SPeter Avalos base *= 256.0;
26071e7ee59SPeter Avalos }
26171e7ee59SPeter Avalos return sum;
26271e7ee59SPeter Avalos }
26371e7ee59SPeter Avalos
26471e7ee59SPeter Avalos
26571e7ee59SPeter Avalos static
uInt64_isZero(UInt64 * n)26671e7ee59SPeter Avalos Bool uInt64_isZero ( UInt64* n )
26771e7ee59SPeter Avalos {
26871e7ee59SPeter Avalos Int32 i;
26971e7ee59SPeter Avalos for (i = 0; i < 8; i++)
27071e7ee59SPeter Avalos if (n->b[i] != 0) return 0;
27171e7ee59SPeter Avalos return 1;
27271e7ee59SPeter Avalos }
27371e7ee59SPeter Avalos
27471e7ee59SPeter Avalos
27571e7ee59SPeter Avalos /* Divide *n by 10, and return the remainder. */
27671e7ee59SPeter Avalos static
uInt64_qrm10(UInt64 * n)27771e7ee59SPeter Avalos Int32 uInt64_qrm10 ( UInt64* n )
27871e7ee59SPeter Avalos {
27971e7ee59SPeter Avalos UInt32 rem, tmp;
28071e7ee59SPeter Avalos Int32 i;
28171e7ee59SPeter Avalos rem = 0;
28271e7ee59SPeter Avalos for (i = 7; i >= 0; i--) {
28371e7ee59SPeter Avalos tmp = rem * 256 + n->b[i];
28471e7ee59SPeter Avalos n->b[i] = tmp / 10;
28571e7ee59SPeter Avalos rem = tmp % 10;
28671e7ee59SPeter Avalos }
28771e7ee59SPeter Avalos return rem;
28871e7ee59SPeter Avalos }
28971e7ee59SPeter Avalos
29071e7ee59SPeter Avalos
29171e7ee59SPeter Avalos /* ... and the Whole Entire Point of all this UInt64 stuff is
29271e7ee59SPeter Avalos so that we can supply the following function.
29371e7ee59SPeter Avalos */
29471e7ee59SPeter Avalos static
uInt64_toAscii(char * outbuf,UInt64 * n)29571e7ee59SPeter Avalos void uInt64_toAscii ( char* outbuf, UInt64* n )
29671e7ee59SPeter Avalos {
29771e7ee59SPeter Avalos Int32 i, q;
29871e7ee59SPeter Avalos UChar buf[32];
29971e7ee59SPeter Avalos Int32 nBuf = 0;
30071e7ee59SPeter Avalos UInt64 n_copy = *n;
30171e7ee59SPeter Avalos do {
30271e7ee59SPeter Avalos q = uInt64_qrm10 ( &n_copy );
30371e7ee59SPeter Avalos buf[nBuf] = q + '0';
30471e7ee59SPeter Avalos nBuf++;
30571e7ee59SPeter Avalos } while (!uInt64_isZero(&n_copy));
30671e7ee59SPeter Avalos outbuf[nBuf] = 0;
30771e7ee59SPeter Avalos for (i = 0; i < nBuf; i++)
30871e7ee59SPeter Avalos outbuf[i] = buf[nBuf-i-1];
30971e7ee59SPeter Avalos }
31071e7ee59SPeter Avalos
31171e7ee59SPeter Avalos
31271e7ee59SPeter Avalos /*---------------------------------------------------*/
31371e7ee59SPeter Avalos /*--- Processing of complete files and streams ---*/
31471e7ee59SPeter Avalos /*---------------------------------------------------*/
31571e7ee59SPeter Avalos
31671e7ee59SPeter Avalos /*---------------------------------------------*/
31771e7ee59SPeter Avalos static
myfeof(FILE * f)31871e7ee59SPeter Avalos Bool myfeof ( FILE* f )
31971e7ee59SPeter Avalos {
32071e7ee59SPeter Avalos Int32 c = fgetc ( f );
32171e7ee59SPeter Avalos if (c == EOF) return True;
32271e7ee59SPeter Avalos ungetc ( c, f );
32371e7ee59SPeter Avalos return False;
32471e7ee59SPeter Avalos }
32571e7ee59SPeter Avalos
32671e7ee59SPeter Avalos
32771e7ee59SPeter Avalos /*---------------------------------------------*/
32871e7ee59SPeter Avalos static
compressStream(FILE * stream,FILE * zStream)32971e7ee59SPeter Avalos void compressStream ( FILE *stream, FILE *zStream )
33071e7ee59SPeter Avalos {
33171e7ee59SPeter Avalos BZFILE* bzf = NULL;
33271e7ee59SPeter Avalos UChar ibuf[5000];
33371e7ee59SPeter Avalos Int32 nIbuf;
33471e7ee59SPeter Avalos UInt32 nbytes_in_lo32, nbytes_in_hi32;
33571e7ee59SPeter Avalos UInt32 nbytes_out_lo32, nbytes_out_hi32;
33671e7ee59SPeter Avalos Int32 bzerr, bzerr_dummy, ret;
33771e7ee59SPeter Avalos
33871e7ee59SPeter Avalos SET_BINARY_MODE(stream);
33971e7ee59SPeter Avalos SET_BINARY_MODE(zStream);
34071e7ee59SPeter Avalos
34171e7ee59SPeter Avalos if (ferror(stream)) goto errhandler_io;
34271e7ee59SPeter Avalos if (ferror(zStream)) goto errhandler_io;
34371e7ee59SPeter Avalos
34471e7ee59SPeter Avalos bzf = BZ2_bzWriteOpen ( &bzerr, zStream,
34571e7ee59SPeter Avalos blockSize100k, verbosity, workFactor );
34671e7ee59SPeter Avalos if (bzerr != BZ_OK) goto errhandler;
34771e7ee59SPeter Avalos
34871e7ee59SPeter Avalos if (verbosity >= 2) fprintf ( stderr, "\n" );
34971e7ee59SPeter Avalos
35071e7ee59SPeter Avalos while (True) {
35171e7ee59SPeter Avalos
35271e7ee59SPeter Avalos if (myfeof(stream)) break;
35371e7ee59SPeter Avalos nIbuf = fread ( ibuf, sizeof(UChar), 5000, stream );
35471e7ee59SPeter Avalos if (ferror(stream)) goto errhandler_io;
35571e7ee59SPeter Avalos if (nIbuf > 0) BZ2_bzWrite ( &bzerr, bzf, (void*)ibuf, nIbuf );
35671e7ee59SPeter Avalos if (bzerr != BZ_OK) goto errhandler;
35771e7ee59SPeter Avalos
35871e7ee59SPeter Avalos }
35971e7ee59SPeter Avalos
36071e7ee59SPeter Avalos BZ2_bzWriteClose64 ( &bzerr, bzf, 0,
36171e7ee59SPeter Avalos &nbytes_in_lo32, &nbytes_in_hi32,
36271e7ee59SPeter Avalos &nbytes_out_lo32, &nbytes_out_hi32 );
36371e7ee59SPeter Avalos if (bzerr != BZ_OK) goto errhandler;
36471e7ee59SPeter Avalos
36571e7ee59SPeter Avalos if (ferror(zStream)) goto errhandler_io;
36671e7ee59SPeter Avalos ret = fflush ( zStream );
36771e7ee59SPeter Avalos if (ret == EOF) goto errhandler_io;
36871e7ee59SPeter Avalos if (zStream != stdout) {
36971e7ee59SPeter Avalos Int32 fd = fileno ( zStream );
37071e7ee59SPeter Avalos if (fd < 0) goto errhandler_io;
37171e7ee59SPeter Avalos applySavedFileAttrToOutputFile ( fd );
37271e7ee59SPeter Avalos ret = fclose ( zStream );
37371e7ee59SPeter Avalos outputHandleJustInCase = NULL;
37471e7ee59SPeter Avalos if (ret == EOF) goto errhandler_io;
37571e7ee59SPeter Avalos }
37671e7ee59SPeter Avalos outputHandleJustInCase = NULL;
37771e7ee59SPeter Avalos if (ferror(stream)) goto errhandler_io;
37871e7ee59SPeter Avalos ret = fclose ( stream );
37971e7ee59SPeter Avalos if (ret == EOF) goto errhandler_io;
38071e7ee59SPeter Avalos
38171e7ee59SPeter Avalos if (verbosity >= 1) {
38271e7ee59SPeter Avalos if (nbytes_in_lo32 == 0 && nbytes_in_hi32 == 0) {
38371e7ee59SPeter Avalos fprintf ( stderr, " no data compressed.\n");
38471e7ee59SPeter Avalos } else {
38571e7ee59SPeter Avalos Char buf_nin[32], buf_nout[32];
38671e7ee59SPeter Avalos UInt64 nbytes_in, nbytes_out;
38771e7ee59SPeter Avalos double nbytes_in_d, nbytes_out_d;
38871e7ee59SPeter Avalos uInt64_from_UInt32s ( &nbytes_in,
38971e7ee59SPeter Avalos nbytes_in_lo32, nbytes_in_hi32 );
39071e7ee59SPeter Avalos uInt64_from_UInt32s ( &nbytes_out,
39171e7ee59SPeter Avalos nbytes_out_lo32, nbytes_out_hi32 );
39271e7ee59SPeter Avalos nbytes_in_d = uInt64_to_double ( &nbytes_in );
39371e7ee59SPeter Avalos nbytes_out_d = uInt64_to_double ( &nbytes_out );
39471e7ee59SPeter Avalos uInt64_toAscii ( buf_nin, &nbytes_in );
39571e7ee59SPeter Avalos uInt64_toAscii ( buf_nout, &nbytes_out );
39671e7ee59SPeter Avalos fprintf ( stderr, "%6.3f:1, %6.3f bits/byte, "
39771e7ee59SPeter Avalos "%5.2f%% saved, %s in, %s out.\n",
39871e7ee59SPeter Avalos nbytes_in_d / nbytes_out_d,
39971e7ee59SPeter Avalos (8.0 * nbytes_out_d) / nbytes_in_d,
40071e7ee59SPeter Avalos 100.0 * (1.0 - nbytes_out_d / nbytes_in_d),
40171e7ee59SPeter Avalos buf_nin,
40271e7ee59SPeter Avalos buf_nout
40371e7ee59SPeter Avalos );
40471e7ee59SPeter Avalos }
40571e7ee59SPeter Avalos }
40671e7ee59SPeter Avalos
40771e7ee59SPeter Avalos return;
40871e7ee59SPeter Avalos
40971e7ee59SPeter Avalos errhandler:
41071e7ee59SPeter Avalos BZ2_bzWriteClose64 ( &bzerr_dummy, bzf, 1,
41171e7ee59SPeter Avalos &nbytes_in_lo32, &nbytes_in_hi32,
41271e7ee59SPeter Avalos &nbytes_out_lo32, &nbytes_out_hi32 );
41371e7ee59SPeter Avalos switch (bzerr) {
41471e7ee59SPeter Avalos case BZ_CONFIG_ERROR:
41571e7ee59SPeter Avalos configError(); break;
41671e7ee59SPeter Avalos case BZ_MEM_ERROR:
41771e7ee59SPeter Avalos outOfMemory (); break;
41871e7ee59SPeter Avalos case BZ_IO_ERROR:
41971e7ee59SPeter Avalos errhandler_io:
42071e7ee59SPeter Avalos ioError(); break;
42171e7ee59SPeter Avalos default:
42271e7ee59SPeter Avalos panic ( "compress:unexpected error" );
42371e7ee59SPeter Avalos }
42471e7ee59SPeter Avalos
42571e7ee59SPeter Avalos panic ( "compress:end" );
42671e7ee59SPeter Avalos /*notreached*/
42771e7ee59SPeter Avalos }
42871e7ee59SPeter Avalos
42971e7ee59SPeter Avalos
43071e7ee59SPeter Avalos
43171e7ee59SPeter Avalos /*---------------------------------------------*/
43271e7ee59SPeter Avalos static
uncompressStream(FILE * zStream,FILE * stream)43371e7ee59SPeter Avalos Bool uncompressStream ( FILE *zStream, FILE *stream )
43471e7ee59SPeter Avalos {
43571e7ee59SPeter Avalos BZFILE* bzf = NULL;
43671e7ee59SPeter Avalos Int32 bzerr, bzerr_dummy, ret, nread, streamNo, i;
43771e7ee59SPeter Avalos UChar obuf[5000];
43871e7ee59SPeter Avalos UChar unused[BZ_MAX_UNUSED];
43971e7ee59SPeter Avalos Int32 nUnused;
44071e7ee59SPeter Avalos void* unusedTmpV;
44171e7ee59SPeter Avalos UChar* unusedTmp;
44271e7ee59SPeter Avalos
44371e7ee59SPeter Avalos nUnused = 0;
44471e7ee59SPeter Avalos streamNo = 0;
44571e7ee59SPeter Avalos
44671e7ee59SPeter Avalos SET_BINARY_MODE(stream);
44771e7ee59SPeter Avalos SET_BINARY_MODE(zStream);
44871e7ee59SPeter Avalos
44971e7ee59SPeter Avalos if (ferror(stream)) goto errhandler_io;
45071e7ee59SPeter Avalos if (ferror(zStream)) goto errhandler_io;
45171e7ee59SPeter Avalos
45271e7ee59SPeter Avalos while (True) {
45371e7ee59SPeter Avalos
45471e7ee59SPeter Avalos bzf = BZ2_bzReadOpen (
45571e7ee59SPeter Avalos &bzerr, zStream, verbosity,
45671e7ee59SPeter Avalos (int)smallMode, unused, nUnused
45771e7ee59SPeter Avalos );
45871e7ee59SPeter Avalos if (bzf == NULL || bzerr != BZ_OK) goto errhandler;
45971e7ee59SPeter Avalos streamNo++;
46071e7ee59SPeter Avalos
46171e7ee59SPeter Avalos while (bzerr == BZ_OK) {
46271e7ee59SPeter Avalos nread = BZ2_bzRead ( &bzerr, bzf, obuf, 5000 );
46371e7ee59SPeter Avalos if (bzerr == BZ_DATA_ERROR_MAGIC) goto trycat;
46471e7ee59SPeter Avalos if ((bzerr == BZ_OK || bzerr == BZ_STREAM_END) && nread > 0)
46571e7ee59SPeter Avalos fwrite ( obuf, sizeof(UChar), nread, stream );
46671e7ee59SPeter Avalos if (ferror(stream)) goto errhandler_io;
46771e7ee59SPeter Avalos }
46871e7ee59SPeter Avalos if (bzerr != BZ_STREAM_END) goto errhandler;
46971e7ee59SPeter Avalos
47071e7ee59SPeter Avalos BZ2_bzReadGetUnused ( &bzerr, bzf, &unusedTmpV, &nUnused );
47171e7ee59SPeter Avalos if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" );
47271e7ee59SPeter Avalos
47371e7ee59SPeter Avalos unusedTmp = (UChar*)unusedTmpV;
47471e7ee59SPeter Avalos for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i];
47571e7ee59SPeter Avalos
47671e7ee59SPeter Avalos BZ2_bzReadClose ( &bzerr, bzf );
47771e7ee59SPeter Avalos if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" );
47871e7ee59SPeter Avalos
47971e7ee59SPeter Avalos if (nUnused == 0 && myfeof(zStream)) break;
48071e7ee59SPeter Avalos }
48171e7ee59SPeter Avalos
48271e7ee59SPeter Avalos closeok:
48371e7ee59SPeter Avalos if (ferror(zStream)) goto errhandler_io;
48471e7ee59SPeter Avalos if (stream != stdout) {
48571e7ee59SPeter Avalos Int32 fd = fileno ( stream );
48671e7ee59SPeter Avalos if (fd < 0) goto errhandler_io;
48771e7ee59SPeter Avalos applySavedFileAttrToOutputFile ( fd );
48871e7ee59SPeter Avalos }
48971e7ee59SPeter Avalos ret = fclose ( zStream );
49071e7ee59SPeter Avalos if (ret == EOF) goto errhandler_io;
49171e7ee59SPeter Avalos
49271e7ee59SPeter Avalos if (ferror(stream)) goto errhandler_io;
49371e7ee59SPeter Avalos ret = fflush ( stream );
49471e7ee59SPeter Avalos if (ret != 0) goto errhandler_io;
49571e7ee59SPeter Avalos if (stream != stdout) {
49671e7ee59SPeter Avalos ret = fclose ( stream );
49771e7ee59SPeter Avalos outputHandleJustInCase = NULL;
49871e7ee59SPeter Avalos if (ret == EOF) goto errhandler_io;
49971e7ee59SPeter Avalos }
50071e7ee59SPeter Avalos outputHandleJustInCase = NULL;
50171e7ee59SPeter Avalos if (verbosity >= 2) fprintf ( stderr, "\n " );
50271e7ee59SPeter Avalos return True;
50371e7ee59SPeter Avalos
50471e7ee59SPeter Avalos trycat:
50571e7ee59SPeter Avalos if (forceOverwrite) {
50671e7ee59SPeter Avalos rewind(zStream);
50771e7ee59SPeter Avalos while (True) {
50871e7ee59SPeter Avalos if (myfeof(zStream)) break;
50971e7ee59SPeter Avalos nread = fread ( obuf, sizeof(UChar), 5000, zStream );
51071e7ee59SPeter Avalos if (ferror(zStream)) goto errhandler_io;
51171e7ee59SPeter Avalos if (nread > 0) fwrite ( obuf, sizeof(UChar), nread, stream );
51271e7ee59SPeter Avalos if (ferror(stream)) goto errhandler_io;
51371e7ee59SPeter Avalos }
51471e7ee59SPeter Avalos goto closeok;
51571e7ee59SPeter Avalos }
51671e7ee59SPeter Avalos
51771e7ee59SPeter Avalos errhandler:
51871e7ee59SPeter Avalos BZ2_bzReadClose ( &bzerr_dummy, bzf );
51971e7ee59SPeter Avalos switch (bzerr) {
52071e7ee59SPeter Avalos case BZ_CONFIG_ERROR:
52171e7ee59SPeter Avalos configError(); break;
52271e7ee59SPeter Avalos case BZ_IO_ERROR:
52371e7ee59SPeter Avalos errhandler_io:
52471e7ee59SPeter Avalos ioError(); break;
52571e7ee59SPeter Avalos case BZ_DATA_ERROR:
52671e7ee59SPeter Avalos crcError();
52771e7ee59SPeter Avalos case BZ_MEM_ERROR:
52871e7ee59SPeter Avalos outOfMemory();
52971e7ee59SPeter Avalos case BZ_UNEXPECTED_EOF:
53071e7ee59SPeter Avalos compressedStreamEOF();
53171e7ee59SPeter Avalos case BZ_DATA_ERROR_MAGIC:
53271e7ee59SPeter Avalos if (zStream != stdin) fclose(zStream);
53371e7ee59SPeter Avalos if (stream != stdout) fclose(stream);
53471e7ee59SPeter Avalos if (streamNo == 1) {
53571e7ee59SPeter Avalos return False;
53671e7ee59SPeter Avalos } else {
53771e7ee59SPeter Avalos if (noisy)
53871e7ee59SPeter Avalos fprintf ( stderr,
53971e7ee59SPeter Avalos "\n%s: %s: trailing garbage after EOF ignored\n",
54071e7ee59SPeter Avalos progName, inName );
54171e7ee59SPeter Avalos return True;
54271e7ee59SPeter Avalos }
54371e7ee59SPeter Avalos default:
54471e7ee59SPeter Avalos panic ( "decompress:unexpected error" );
54571e7ee59SPeter Avalos }
54671e7ee59SPeter Avalos
54771e7ee59SPeter Avalos panic ( "decompress:end" );
54871e7ee59SPeter Avalos return True; /*notreached*/
54971e7ee59SPeter Avalos }
55071e7ee59SPeter Avalos
55171e7ee59SPeter Avalos
55271e7ee59SPeter Avalos /*---------------------------------------------*/
55371e7ee59SPeter Avalos static
testStream(FILE * zStream)55471e7ee59SPeter Avalos Bool testStream ( FILE *zStream )
55571e7ee59SPeter Avalos {
55671e7ee59SPeter Avalos BZFILE* bzf = NULL;
557*86954436SDaniel Fojt Int32 bzerr, bzerr_dummy, ret, streamNo, i;
55871e7ee59SPeter Avalos UChar obuf[5000];
55971e7ee59SPeter Avalos UChar unused[BZ_MAX_UNUSED];
56071e7ee59SPeter Avalos Int32 nUnused;
56171e7ee59SPeter Avalos void* unusedTmpV;
56271e7ee59SPeter Avalos UChar* unusedTmp;
56371e7ee59SPeter Avalos
56471e7ee59SPeter Avalos nUnused = 0;
56571e7ee59SPeter Avalos streamNo = 0;
56671e7ee59SPeter Avalos
56771e7ee59SPeter Avalos SET_BINARY_MODE(zStream);
56871e7ee59SPeter Avalos if (ferror(zStream)) goto errhandler_io;
56971e7ee59SPeter Avalos
57071e7ee59SPeter Avalos while (True) {
57171e7ee59SPeter Avalos
57271e7ee59SPeter Avalos bzf = BZ2_bzReadOpen (
57371e7ee59SPeter Avalos &bzerr, zStream, verbosity,
57471e7ee59SPeter Avalos (int)smallMode, unused, nUnused
57571e7ee59SPeter Avalos );
57671e7ee59SPeter Avalos if (bzf == NULL || bzerr != BZ_OK) goto errhandler;
57771e7ee59SPeter Avalos streamNo++;
57871e7ee59SPeter Avalos
57971e7ee59SPeter Avalos while (bzerr == BZ_OK) {
580*86954436SDaniel Fojt BZ2_bzRead ( &bzerr, bzf, obuf, 5000 );
58171e7ee59SPeter Avalos if (bzerr == BZ_DATA_ERROR_MAGIC) goto errhandler;
58271e7ee59SPeter Avalos }
58371e7ee59SPeter Avalos if (bzerr != BZ_STREAM_END) goto errhandler;
58471e7ee59SPeter Avalos
58571e7ee59SPeter Avalos BZ2_bzReadGetUnused ( &bzerr, bzf, &unusedTmpV, &nUnused );
58671e7ee59SPeter Avalos if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" );
58771e7ee59SPeter Avalos
58871e7ee59SPeter Avalos unusedTmp = (UChar*)unusedTmpV;
58971e7ee59SPeter Avalos for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i];
59071e7ee59SPeter Avalos
59171e7ee59SPeter Avalos BZ2_bzReadClose ( &bzerr, bzf );
59271e7ee59SPeter Avalos if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" );
59371e7ee59SPeter Avalos if (nUnused == 0 && myfeof(zStream)) break;
59471e7ee59SPeter Avalos
59571e7ee59SPeter Avalos }
59671e7ee59SPeter Avalos
59771e7ee59SPeter Avalos if (ferror(zStream)) goto errhandler_io;
59871e7ee59SPeter Avalos ret = fclose ( zStream );
59971e7ee59SPeter Avalos if (ret == EOF) goto errhandler_io;
60071e7ee59SPeter Avalos
60171e7ee59SPeter Avalos if (verbosity >= 2) fprintf ( stderr, "\n " );
60271e7ee59SPeter Avalos return True;
60371e7ee59SPeter Avalos
60471e7ee59SPeter Avalos errhandler:
60571e7ee59SPeter Avalos BZ2_bzReadClose ( &bzerr_dummy, bzf );
60671e7ee59SPeter Avalos if (verbosity == 0)
60771e7ee59SPeter Avalos fprintf ( stderr, "%s: %s: ", progName, inName );
60871e7ee59SPeter Avalos switch (bzerr) {
60971e7ee59SPeter Avalos case BZ_CONFIG_ERROR:
61071e7ee59SPeter Avalos configError(); break;
61171e7ee59SPeter Avalos case BZ_IO_ERROR:
61271e7ee59SPeter Avalos errhandler_io:
61371e7ee59SPeter Avalos ioError(); break;
61471e7ee59SPeter Avalos case BZ_DATA_ERROR:
61571e7ee59SPeter Avalos fprintf ( stderr,
61671e7ee59SPeter Avalos "data integrity (CRC) error in data\n" );
61771e7ee59SPeter Avalos return False;
61871e7ee59SPeter Avalos case BZ_MEM_ERROR:
61971e7ee59SPeter Avalos outOfMemory();
62071e7ee59SPeter Avalos case BZ_UNEXPECTED_EOF:
62171e7ee59SPeter Avalos fprintf ( stderr,
62271e7ee59SPeter Avalos "file ends unexpectedly\n" );
62371e7ee59SPeter Avalos return False;
62471e7ee59SPeter Avalos case BZ_DATA_ERROR_MAGIC:
62571e7ee59SPeter Avalos if (zStream != stdin) fclose(zStream);
62671e7ee59SPeter Avalos if (streamNo == 1) {
62771e7ee59SPeter Avalos fprintf ( stderr,
62871e7ee59SPeter Avalos "bad magic number (file not created by bzip2)\n" );
62971e7ee59SPeter Avalos return False;
63071e7ee59SPeter Avalos } else {
63171e7ee59SPeter Avalos if (noisy)
63271e7ee59SPeter Avalos fprintf ( stderr,
63371e7ee59SPeter Avalos "trailing garbage after EOF ignored\n" );
63471e7ee59SPeter Avalos return True;
63571e7ee59SPeter Avalos }
63671e7ee59SPeter Avalos default:
63771e7ee59SPeter Avalos panic ( "test:unexpected error" );
63871e7ee59SPeter Avalos }
63971e7ee59SPeter Avalos
64071e7ee59SPeter Avalos panic ( "test:end" );
64171e7ee59SPeter Avalos return True; /*notreached*/
64271e7ee59SPeter Avalos }
64371e7ee59SPeter Avalos
64471e7ee59SPeter Avalos
64571e7ee59SPeter Avalos /*---------------------------------------------------*/
64671e7ee59SPeter Avalos /*--- Error [non-] handling grunge ---*/
64771e7ee59SPeter Avalos /*---------------------------------------------------*/
64871e7ee59SPeter Avalos
64971e7ee59SPeter Avalos /*---------------------------------------------*/
65071e7ee59SPeter Avalos static
setExit(Int32 v)65171e7ee59SPeter Avalos void setExit ( Int32 v )
65271e7ee59SPeter Avalos {
65371e7ee59SPeter Avalos if (v > exitValue) exitValue = v;
65471e7ee59SPeter Avalos }
65571e7ee59SPeter Avalos
65671e7ee59SPeter Avalos
65771e7ee59SPeter Avalos /*---------------------------------------------*/
65871e7ee59SPeter Avalos static
cadvise(void)65971e7ee59SPeter Avalos void cadvise ( void )
66071e7ee59SPeter Avalos {
66171e7ee59SPeter Avalos if (noisy)
66271e7ee59SPeter Avalos fprintf (
66371e7ee59SPeter Avalos stderr,
66471e7ee59SPeter Avalos "\nIt is possible that the compressed file(s) have become corrupted.\n"
66571e7ee59SPeter Avalos "You can use the -tvv option to test integrity of such files.\n\n"
66671e7ee59SPeter Avalos "You can use the `bzip2recover' program to attempt to recover\n"
66771e7ee59SPeter Avalos "data from undamaged sections of corrupted files.\n\n"
66871e7ee59SPeter Avalos );
66971e7ee59SPeter Avalos }
67071e7ee59SPeter Avalos
67171e7ee59SPeter Avalos
67271e7ee59SPeter Avalos /*---------------------------------------------*/
67371e7ee59SPeter Avalos static
showFileNames(void)67471e7ee59SPeter Avalos void showFileNames ( void )
67571e7ee59SPeter Avalos {
67671e7ee59SPeter Avalos if (noisy)
67771e7ee59SPeter Avalos fprintf (
67871e7ee59SPeter Avalos stderr,
67971e7ee59SPeter Avalos "\tInput file = %s, output file = %s\n",
68071e7ee59SPeter Avalos inName, outName
68171e7ee59SPeter Avalos );
68271e7ee59SPeter Avalos }
68371e7ee59SPeter Avalos
68471e7ee59SPeter Avalos
68571e7ee59SPeter Avalos /*---------------------------------------------*/
68671e7ee59SPeter Avalos static
cleanUpAndFail(Int32 ec)68771e7ee59SPeter Avalos void cleanUpAndFail ( Int32 ec )
68871e7ee59SPeter Avalos {
68971e7ee59SPeter Avalos IntNative retVal;
69071e7ee59SPeter Avalos struct MY_STAT statBuf;
69171e7ee59SPeter Avalos
69271e7ee59SPeter Avalos if ( srcMode == SM_F2F
69371e7ee59SPeter Avalos && opMode != OM_TEST
69471e7ee59SPeter Avalos && deleteOutputOnInterrupt ) {
69571e7ee59SPeter Avalos
69671e7ee59SPeter Avalos /* Check whether input file still exists. Delete output file
69771e7ee59SPeter Avalos only if input exists to avoid loss of data. Joerg Prante, 5
69871e7ee59SPeter Avalos January 2002. (JRS 06-Jan-2002: other changes in 1.0.2 mean
69971e7ee59SPeter Avalos this is less likely to happen. But to be ultra-paranoid, we
70071e7ee59SPeter Avalos do the check anyway.) */
70171e7ee59SPeter Avalos retVal = MY_STAT ( inName, &statBuf );
70271e7ee59SPeter Avalos if (retVal == 0) {
70371e7ee59SPeter Avalos if (noisy)
70471e7ee59SPeter Avalos fprintf ( stderr,
70571e7ee59SPeter Avalos "%s: Deleting output file %s, if it exists.\n",
70671e7ee59SPeter Avalos progName, outName );
70771e7ee59SPeter Avalos if (outputHandleJustInCase != NULL)
70871e7ee59SPeter Avalos fclose ( outputHandleJustInCase );
70971e7ee59SPeter Avalos retVal = remove ( outName );
71071e7ee59SPeter Avalos if (retVal != 0)
71171e7ee59SPeter Avalos fprintf ( stderr,
71271e7ee59SPeter Avalos "%s: WARNING: deletion of output file "
71371e7ee59SPeter Avalos "(apparently) failed.\n",
71471e7ee59SPeter Avalos progName );
71571e7ee59SPeter Avalos } else {
71671e7ee59SPeter Avalos fprintf ( stderr,
71771e7ee59SPeter Avalos "%s: WARNING: deletion of output file suppressed\n",
71871e7ee59SPeter Avalos progName );
71971e7ee59SPeter Avalos fprintf ( stderr,
72071e7ee59SPeter Avalos "%s: since input file no longer exists. Output file\n",
72171e7ee59SPeter Avalos progName );
72271e7ee59SPeter Avalos fprintf ( stderr,
72371e7ee59SPeter Avalos "%s: `%s' may be incomplete.\n",
72471e7ee59SPeter Avalos progName, outName );
72571e7ee59SPeter Avalos fprintf ( stderr,
72671e7ee59SPeter Avalos "%s: I suggest doing an integrity test (bzip2 -tv)"
72771e7ee59SPeter Avalos " of it.\n",
72871e7ee59SPeter Avalos progName );
72971e7ee59SPeter Avalos }
73071e7ee59SPeter Avalos }
73171e7ee59SPeter Avalos
73271e7ee59SPeter Avalos if (noisy && numFileNames > 0 && numFilesProcessed < numFileNames) {
73371e7ee59SPeter Avalos fprintf ( stderr,
73471e7ee59SPeter Avalos "%s: WARNING: some files have not been processed:\n"
73571e7ee59SPeter Avalos "%s: %d specified on command line, %d not processed yet.\n\n",
73671e7ee59SPeter Avalos progName, progName,
73771e7ee59SPeter Avalos numFileNames, numFileNames - numFilesProcessed );
73871e7ee59SPeter Avalos }
73971e7ee59SPeter Avalos setExit(ec);
74071e7ee59SPeter Avalos exit(exitValue);
74171e7ee59SPeter Avalos }
74271e7ee59SPeter Avalos
74371e7ee59SPeter Avalos
74471e7ee59SPeter Avalos /*---------------------------------------------*/
74571e7ee59SPeter Avalos static
panic(const Char * s)74671e7ee59SPeter Avalos void panic ( const Char* s )
74771e7ee59SPeter Avalos {
74871e7ee59SPeter Avalos fprintf ( stderr,
74971e7ee59SPeter Avalos "\n%s: PANIC -- internal consistency error:\n"
75071e7ee59SPeter Avalos "\t%s\n"
751*86954436SDaniel Fojt "\tThis is a BUG. Please report it to:\n"
752*86954436SDaniel Fojt "\tbzip2-devel@sourceware.org\n",
75371e7ee59SPeter Avalos progName, s );
75471e7ee59SPeter Avalos showFileNames();
75571e7ee59SPeter Avalos cleanUpAndFail( 3 );
75671e7ee59SPeter Avalos }
75771e7ee59SPeter Avalos
75871e7ee59SPeter Avalos
75971e7ee59SPeter Avalos /*---------------------------------------------*/
76071e7ee59SPeter Avalos static
crcError(void)76171e7ee59SPeter Avalos void crcError ( void )
76271e7ee59SPeter Avalos {
76371e7ee59SPeter Avalos fprintf ( stderr,
76471e7ee59SPeter Avalos "\n%s: Data integrity error when decompressing.\n",
76571e7ee59SPeter Avalos progName );
76671e7ee59SPeter Avalos showFileNames();
76771e7ee59SPeter Avalos cadvise();
76871e7ee59SPeter Avalos cleanUpAndFail( 2 );
76971e7ee59SPeter Avalos }
77071e7ee59SPeter Avalos
77171e7ee59SPeter Avalos
77271e7ee59SPeter Avalos /*---------------------------------------------*/
77371e7ee59SPeter Avalos static
compressedStreamEOF(void)77471e7ee59SPeter Avalos void compressedStreamEOF ( void )
77571e7ee59SPeter Avalos {
77671e7ee59SPeter Avalos if (noisy) {
77771e7ee59SPeter Avalos fprintf ( stderr,
77871e7ee59SPeter Avalos "\n%s: Compressed file ends unexpectedly;\n\t"
77971e7ee59SPeter Avalos "perhaps it is corrupted? *Possible* reason follows.\n",
78071e7ee59SPeter Avalos progName );
78171e7ee59SPeter Avalos perror ( progName );
78271e7ee59SPeter Avalos showFileNames();
78371e7ee59SPeter Avalos cadvise();
78471e7ee59SPeter Avalos }
78571e7ee59SPeter Avalos cleanUpAndFail( 2 );
78671e7ee59SPeter Avalos }
78771e7ee59SPeter Avalos
78871e7ee59SPeter Avalos
78971e7ee59SPeter Avalos /*---------------------------------------------*/
79071e7ee59SPeter Avalos static
ioError(void)79171e7ee59SPeter Avalos void ioError ( void )
79271e7ee59SPeter Avalos {
79371e7ee59SPeter Avalos fprintf ( stderr,
79471e7ee59SPeter Avalos "\n%s: I/O or other error, bailing out. "
79571e7ee59SPeter Avalos "Possible reason follows.\n",
79671e7ee59SPeter Avalos progName );
79771e7ee59SPeter Avalos perror ( progName );
79871e7ee59SPeter Avalos showFileNames();
79971e7ee59SPeter Avalos cleanUpAndFail( 1 );
80071e7ee59SPeter Avalos }
80171e7ee59SPeter Avalos
80271e7ee59SPeter Avalos
80371e7ee59SPeter Avalos /*---------------------------------------------*/
80471e7ee59SPeter Avalos static
mySignalCatcher(IntNative n)80571e7ee59SPeter Avalos void mySignalCatcher ( IntNative n )
80671e7ee59SPeter Avalos {
80771e7ee59SPeter Avalos fprintf ( stderr,
80871e7ee59SPeter Avalos "\n%s: Control-C or similar caught, quitting.\n",
80971e7ee59SPeter Avalos progName );
81071e7ee59SPeter Avalos cleanUpAndFail(1);
81171e7ee59SPeter Avalos }
81271e7ee59SPeter Avalos
81371e7ee59SPeter Avalos
81471e7ee59SPeter Avalos /*---------------------------------------------*/
81571e7ee59SPeter Avalos static
mySIGSEGVorSIGBUScatcher(IntNative n)81671e7ee59SPeter Avalos void mySIGSEGVorSIGBUScatcher ( IntNative n )
81771e7ee59SPeter Avalos {
81871e7ee59SPeter Avalos if (opMode == OM_Z)
81971e7ee59SPeter Avalos fprintf (
82071e7ee59SPeter Avalos stderr,
82171e7ee59SPeter Avalos "\n%s: Caught a SIGSEGV or SIGBUS whilst compressing.\n"
82271e7ee59SPeter Avalos "\n"
82371e7ee59SPeter Avalos " Possible causes are (most likely first):\n"
82471e7ee59SPeter Avalos " (1) This computer has unreliable memory or cache hardware\n"
82571e7ee59SPeter Avalos " (a surprisingly common problem; try a different machine.)\n"
82671e7ee59SPeter Avalos " (2) A bug in the compiler used to create this executable\n"
82771e7ee59SPeter Avalos " (unlikely, if you didn't compile bzip2 yourself.)\n"
82871e7ee59SPeter Avalos " (3) A real bug in bzip2 -- I hope this should never be the case.\n"
82971e7ee59SPeter Avalos " The user's manual, Section 4.3, has more info on (1) and (2).\n"
83071e7ee59SPeter Avalos " \n"
83171e7ee59SPeter Avalos " If you suspect this is a bug in bzip2, or are unsure about (1)\n"
832*86954436SDaniel Fojt " or (2), feel free to report it to: bzip2-devel@sourceware.org.\n"
83371e7ee59SPeter Avalos " Section 4.3 of the user's manual describes the info a useful\n"
83471e7ee59SPeter Avalos " bug report should have. If the manual is available on your\n"
83571e7ee59SPeter Avalos " system, please try and read it before mailing me. If you don't\n"
83671e7ee59SPeter Avalos " have the manual or can't be bothered to read it, mail me anyway.\n"
83771e7ee59SPeter Avalos "\n",
83871e7ee59SPeter Avalos progName );
83971e7ee59SPeter Avalos else
84071e7ee59SPeter Avalos fprintf (
84171e7ee59SPeter Avalos stderr,
84271e7ee59SPeter Avalos "\n%s: Caught a SIGSEGV or SIGBUS whilst decompressing.\n"
84371e7ee59SPeter Avalos "\n"
84471e7ee59SPeter Avalos " Possible causes are (most likely first):\n"
84571e7ee59SPeter Avalos " (1) The compressed data is corrupted, and bzip2's usual checks\n"
84671e7ee59SPeter Avalos " failed to detect this. Try bzip2 -tvv my_file.bz2.\n"
84771e7ee59SPeter Avalos " (2) This computer has unreliable memory or cache hardware\n"
84871e7ee59SPeter Avalos " (a surprisingly common problem; try a different machine.)\n"
84971e7ee59SPeter Avalos " (3) A bug in the compiler used to create this executable\n"
85071e7ee59SPeter Avalos " (unlikely, if you didn't compile bzip2 yourself.)\n"
85171e7ee59SPeter Avalos " (4) A real bug in bzip2 -- I hope this should never be the case.\n"
85271e7ee59SPeter Avalos " The user's manual, Section 4.3, has more info on (2) and (3).\n"
85371e7ee59SPeter Avalos " \n"
85471e7ee59SPeter Avalos " If you suspect this is a bug in bzip2, or are unsure about (2)\n"
855*86954436SDaniel Fojt " or (3), feel free to report it to: bzip2-devel@sourceware.org.\n"
85671e7ee59SPeter Avalos " Section 4.3 of the user's manual describes the info a useful\n"
85771e7ee59SPeter Avalos " bug report should have. If the manual is available on your\n"
85871e7ee59SPeter Avalos " system, please try and read it before mailing me. If you don't\n"
85971e7ee59SPeter Avalos " have the manual or can't be bothered to read it, mail me anyway.\n"
86071e7ee59SPeter Avalos "\n",
86171e7ee59SPeter Avalos progName );
86271e7ee59SPeter Avalos
86371e7ee59SPeter Avalos showFileNames();
86471e7ee59SPeter Avalos if (opMode == OM_Z)
86571e7ee59SPeter Avalos cleanUpAndFail( 3 ); else
86671e7ee59SPeter Avalos { cadvise(); cleanUpAndFail( 2 ); }
86771e7ee59SPeter Avalos }
86871e7ee59SPeter Avalos
86971e7ee59SPeter Avalos
87071e7ee59SPeter Avalos /*---------------------------------------------*/
87171e7ee59SPeter Avalos static
outOfMemory(void)87271e7ee59SPeter Avalos void outOfMemory ( void )
87371e7ee59SPeter Avalos {
87471e7ee59SPeter Avalos fprintf ( stderr,
87571e7ee59SPeter Avalos "\n%s: couldn't allocate enough memory\n",
87671e7ee59SPeter Avalos progName );
87771e7ee59SPeter Avalos showFileNames();
87871e7ee59SPeter Avalos cleanUpAndFail(1);
87971e7ee59SPeter Avalos }
88071e7ee59SPeter Avalos
88171e7ee59SPeter Avalos
88271e7ee59SPeter Avalos /*---------------------------------------------*/
88371e7ee59SPeter Avalos static
configError(void)88471e7ee59SPeter Avalos void configError ( void )
88571e7ee59SPeter Avalos {
88671e7ee59SPeter Avalos fprintf ( stderr,
88771e7ee59SPeter Avalos "bzip2: I'm not configured correctly for this platform!\n"
88871e7ee59SPeter Avalos "\tI require Int32, Int16 and Char to have sizes\n"
88971e7ee59SPeter Avalos "\tof 4, 2 and 1 bytes to run properly, and they don't.\n"
89071e7ee59SPeter Avalos "\tProbably you can fix this by defining them correctly,\n"
89171e7ee59SPeter Avalos "\tand recompiling. Bye!\n" );
89271e7ee59SPeter Avalos setExit(3);
89371e7ee59SPeter Avalos exit(exitValue);
89471e7ee59SPeter Avalos }
89571e7ee59SPeter Avalos
89671e7ee59SPeter Avalos
89771e7ee59SPeter Avalos /*---------------------------------------------------*/
89871e7ee59SPeter Avalos /*--- The main driver machinery ---*/
89971e7ee59SPeter Avalos /*---------------------------------------------------*/
90071e7ee59SPeter Avalos
90171e7ee59SPeter Avalos /* All rather crufty. The main problem is that input files
90271e7ee59SPeter Avalos are stat()d multiple times before use. This should be
90371e7ee59SPeter Avalos cleaned up.
90471e7ee59SPeter Avalos */
90571e7ee59SPeter Avalos
90671e7ee59SPeter Avalos /*---------------------------------------------*/
90771e7ee59SPeter Avalos static
pad(Char * s)90871e7ee59SPeter Avalos void pad ( Char *s )
90971e7ee59SPeter Avalos {
91071e7ee59SPeter Avalos Int32 i;
91171e7ee59SPeter Avalos if ( (Int32)strlen(s) >= longestFileName ) return;
91271e7ee59SPeter Avalos for (i = 1; i <= longestFileName - (Int32)strlen(s); i++)
91371e7ee59SPeter Avalos fprintf ( stderr, " " );
91471e7ee59SPeter Avalos }
91571e7ee59SPeter Avalos
91671e7ee59SPeter Avalos
91771e7ee59SPeter Avalos /*---------------------------------------------*/
91871e7ee59SPeter Avalos static
copyFileName(Char * to,Char * from)91971e7ee59SPeter Avalos void copyFileName ( Char* to, Char* from )
92071e7ee59SPeter Avalos {
92171e7ee59SPeter Avalos if ( strlen(from) > FILE_NAME_LEN-10 ) {
92271e7ee59SPeter Avalos fprintf (
92371e7ee59SPeter Avalos stderr,
92471e7ee59SPeter Avalos "bzip2: file name\n`%s'\n"
92571e7ee59SPeter Avalos "is suspiciously (more than %d chars) long.\n"
92671e7ee59SPeter Avalos "Try using a reasonable file name instead. Sorry! :-)\n",
92771e7ee59SPeter Avalos from, FILE_NAME_LEN-10
92871e7ee59SPeter Avalos );
92971e7ee59SPeter Avalos setExit(1);
93071e7ee59SPeter Avalos exit(exitValue);
93171e7ee59SPeter Avalos }
93271e7ee59SPeter Avalos
93371e7ee59SPeter Avalos strncpy(to,from,FILE_NAME_LEN-10);
93471e7ee59SPeter Avalos to[FILE_NAME_LEN-10]='\0';
93571e7ee59SPeter Avalos }
93671e7ee59SPeter Avalos
93771e7ee59SPeter Avalos
93871e7ee59SPeter Avalos /*---------------------------------------------*/
93971e7ee59SPeter Avalos static
fileExists(Char * name)94071e7ee59SPeter Avalos Bool fileExists ( Char* name )
94171e7ee59SPeter Avalos {
94271e7ee59SPeter Avalos FILE *tmp = fopen ( name, "rb" );
94371e7ee59SPeter Avalos Bool exists = (tmp != NULL);
94471e7ee59SPeter Avalos if (tmp != NULL) fclose ( tmp );
94571e7ee59SPeter Avalos return exists;
94671e7ee59SPeter Avalos }
94771e7ee59SPeter Avalos
94871e7ee59SPeter Avalos
94971e7ee59SPeter Avalos /*---------------------------------------------*/
95071e7ee59SPeter Avalos /* Open an output file safely with O_EXCL and good permissions.
95171e7ee59SPeter Avalos This avoids a race condition in versions < 1.0.2, in which
95271e7ee59SPeter Avalos the file was first opened and then had its interim permissions
95371e7ee59SPeter Avalos set safely. We instead use open() to create the file with
95471e7ee59SPeter Avalos the interim permissions required. (--- --- rw-).
95571e7ee59SPeter Avalos
95671e7ee59SPeter Avalos For non-Unix platforms, if we are not worrying about
95771e7ee59SPeter Avalos security issues, simple this simply behaves like fopen.
95871e7ee59SPeter Avalos */
95971e7ee59SPeter Avalos static
fopen_output_safely(Char * name,const char * mode)96071e7ee59SPeter Avalos FILE* fopen_output_safely ( Char* name, const char* mode )
96171e7ee59SPeter Avalos {
96271e7ee59SPeter Avalos # if BZ_UNIX
96371e7ee59SPeter Avalos FILE* fp;
96471e7ee59SPeter Avalos IntNative fh;
96571e7ee59SPeter Avalos fh = open(name, O_WRONLY|O_CREAT|O_EXCL, S_IWUSR|S_IRUSR);
96671e7ee59SPeter Avalos if (fh == -1) return NULL;
96771e7ee59SPeter Avalos fp = fdopen(fh, mode);
96871e7ee59SPeter Avalos if (fp == NULL) close(fh);
96971e7ee59SPeter Avalos return fp;
97071e7ee59SPeter Avalos # else
97171e7ee59SPeter Avalos return fopen(name, mode);
97271e7ee59SPeter Avalos # endif
97371e7ee59SPeter Avalos }
97471e7ee59SPeter Avalos
97571e7ee59SPeter Avalos
97671e7ee59SPeter Avalos /*---------------------------------------------*/
97771e7ee59SPeter Avalos /*--
97871e7ee59SPeter Avalos if in doubt, return True
97971e7ee59SPeter Avalos --*/
98071e7ee59SPeter Avalos static
notAStandardFile(Char * name)98171e7ee59SPeter Avalos Bool notAStandardFile ( Char* name )
98271e7ee59SPeter Avalos {
98371e7ee59SPeter Avalos IntNative i;
98471e7ee59SPeter Avalos struct MY_STAT statBuf;
98571e7ee59SPeter Avalos
98671e7ee59SPeter Avalos i = MY_LSTAT ( name, &statBuf );
98771e7ee59SPeter Avalos if (i != 0) return True;
98871e7ee59SPeter Avalos if (MY_S_ISREG(statBuf.st_mode)) return False;
98971e7ee59SPeter Avalos return True;
99071e7ee59SPeter Avalos }
99171e7ee59SPeter Avalos
99271e7ee59SPeter Avalos
99371e7ee59SPeter Avalos /*---------------------------------------------*/
99471e7ee59SPeter Avalos /*--
99571e7ee59SPeter Avalos rac 11/21/98 see if file has hard links to it
99671e7ee59SPeter Avalos --*/
99771e7ee59SPeter Avalos static
countHardLinks(Char * name)99871e7ee59SPeter Avalos Int32 countHardLinks ( Char* name )
99971e7ee59SPeter Avalos {
100071e7ee59SPeter Avalos IntNative i;
100171e7ee59SPeter Avalos struct MY_STAT statBuf;
100271e7ee59SPeter Avalos
100371e7ee59SPeter Avalos i = MY_LSTAT ( name, &statBuf );
100471e7ee59SPeter Avalos if (i != 0) return 0;
100571e7ee59SPeter Avalos return (statBuf.st_nlink - 1);
100671e7ee59SPeter Avalos }
100771e7ee59SPeter Avalos
100871e7ee59SPeter Avalos
100971e7ee59SPeter Avalos /*---------------------------------------------*/
101071e7ee59SPeter Avalos /* Copy modification date, access date, permissions and owner from the
101171e7ee59SPeter Avalos source to destination file. We have to copy this meta-info off
101271e7ee59SPeter Avalos into fileMetaInfo before starting to compress / decompress it,
101371e7ee59SPeter Avalos because doing it afterwards means we get the wrong access time.
101471e7ee59SPeter Avalos
101571e7ee59SPeter Avalos To complicate matters, in compress() and decompress() below, the
101671e7ee59SPeter Avalos sequence of tests preceding the call to saveInputFileMetaInfo()
101771e7ee59SPeter Avalos involves calling fileExists(), which in turn establishes its result
101871e7ee59SPeter Avalos by attempting to fopen() the file, and if successful, immediately
101971e7ee59SPeter Avalos fclose()ing it again. So we have to assume that the fopen() call
102071e7ee59SPeter Avalos does not cause the access time field to be updated.
102171e7ee59SPeter Avalos
102271e7ee59SPeter Avalos Reading of the man page for stat() (man 2 stat) on RedHat 7.2 seems
102371e7ee59SPeter Avalos to imply that merely doing open() will not affect the access time.
102471e7ee59SPeter Avalos Therefore we merely need to hope that the C library only does
102571e7ee59SPeter Avalos open() as a result of fopen(), and not any kind of read()-ahead
102671e7ee59SPeter Avalos cleverness.
102771e7ee59SPeter Avalos
102871e7ee59SPeter Avalos It sounds pretty fragile to me. Whether this carries across
102971e7ee59SPeter Avalos robustly to arbitrary Unix-like platforms (or even works robustly
103071e7ee59SPeter Avalos on this one, RedHat 7.2) is unknown to me. Nevertheless ...
103171e7ee59SPeter Avalos */
103271e7ee59SPeter Avalos #if BZ_UNIX
103371e7ee59SPeter Avalos static
103471e7ee59SPeter Avalos struct MY_STAT fileMetaInfo;
103571e7ee59SPeter Avalos #endif
103671e7ee59SPeter Avalos
103771e7ee59SPeter Avalos static
saveInputFileMetaInfo(Char * srcName)103871e7ee59SPeter Avalos void saveInputFileMetaInfo ( Char *srcName )
103971e7ee59SPeter Avalos {
104071e7ee59SPeter Avalos # if BZ_UNIX
104171e7ee59SPeter Avalos IntNative retVal;
104271e7ee59SPeter Avalos /* Note use of stat here, not lstat. */
104371e7ee59SPeter Avalos retVal = MY_STAT( srcName, &fileMetaInfo );
104471e7ee59SPeter Avalos ERROR_IF_NOT_ZERO ( retVal );
104571e7ee59SPeter Avalos # endif
104671e7ee59SPeter Avalos }
104771e7ee59SPeter Avalos
104871e7ee59SPeter Avalos
104971e7ee59SPeter Avalos static
applySavedTimeInfoToOutputFile(Char * dstName)105071e7ee59SPeter Avalos void applySavedTimeInfoToOutputFile ( Char *dstName )
105171e7ee59SPeter Avalos {
105271e7ee59SPeter Avalos # if BZ_UNIX
105371e7ee59SPeter Avalos IntNative retVal;
105471e7ee59SPeter Avalos struct utimbuf uTimBuf;
105571e7ee59SPeter Avalos
105671e7ee59SPeter Avalos uTimBuf.actime = fileMetaInfo.st_atime;
105771e7ee59SPeter Avalos uTimBuf.modtime = fileMetaInfo.st_mtime;
105871e7ee59SPeter Avalos
105971e7ee59SPeter Avalos retVal = utime ( dstName, &uTimBuf );
106071e7ee59SPeter Avalos ERROR_IF_NOT_ZERO ( retVal );
106171e7ee59SPeter Avalos # endif
106271e7ee59SPeter Avalos }
106371e7ee59SPeter Avalos
106471e7ee59SPeter Avalos static
applySavedFileAttrToOutputFile(IntNative fd)106571e7ee59SPeter Avalos void applySavedFileAttrToOutputFile ( IntNative fd )
106671e7ee59SPeter Avalos {
106771e7ee59SPeter Avalos # if BZ_UNIX
106871e7ee59SPeter Avalos IntNative retVal;
106971e7ee59SPeter Avalos
107071e7ee59SPeter Avalos retVal = fchmod ( fd, fileMetaInfo.st_mode );
107171e7ee59SPeter Avalos ERROR_IF_NOT_ZERO ( retVal );
107271e7ee59SPeter Avalos
107371e7ee59SPeter Avalos (void) fchown ( fd, fileMetaInfo.st_uid, fileMetaInfo.st_gid );
107471e7ee59SPeter Avalos /* chown() will in many cases return with EPERM, which can
107571e7ee59SPeter Avalos be safely ignored.
107671e7ee59SPeter Avalos */
107771e7ee59SPeter Avalos # endif
107871e7ee59SPeter Avalos }
107971e7ee59SPeter Avalos
108071e7ee59SPeter Avalos
108171e7ee59SPeter Avalos /*---------------------------------------------*/
108271e7ee59SPeter Avalos static
containsDubiousChars(Char * name)108371e7ee59SPeter Avalos Bool containsDubiousChars ( Char* name )
108471e7ee59SPeter Avalos {
108571e7ee59SPeter Avalos # if BZ_UNIX
108671e7ee59SPeter Avalos /* On unix, files can contain any characters and the file expansion
108771e7ee59SPeter Avalos * is performed by the shell.
108871e7ee59SPeter Avalos */
108971e7ee59SPeter Avalos return False;
109071e7ee59SPeter Avalos # else /* ! BZ_UNIX */
109171e7ee59SPeter Avalos /* On non-unix (Win* platforms), wildcard characters are not allowed in
109271e7ee59SPeter Avalos * filenames.
109371e7ee59SPeter Avalos */
109471e7ee59SPeter Avalos for (; *name != '\0'; name++)
109571e7ee59SPeter Avalos if (*name == '?' || *name == '*') return True;
109671e7ee59SPeter Avalos return False;
109771e7ee59SPeter Avalos # endif /* BZ_UNIX */
109871e7ee59SPeter Avalos }
109971e7ee59SPeter Avalos
110071e7ee59SPeter Avalos
110171e7ee59SPeter Avalos /*---------------------------------------------*/
110271e7ee59SPeter Avalos #define BZ_N_SUFFIX_PAIRS 4
110371e7ee59SPeter Avalos
110471e7ee59SPeter Avalos const Char* zSuffix[BZ_N_SUFFIX_PAIRS]
110571e7ee59SPeter Avalos = { ".bz2", ".bz", ".tbz2", ".tbz" };
110671e7ee59SPeter Avalos const Char* unzSuffix[BZ_N_SUFFIX_PAIRS]
110771e7ee59SPeter Avalos = { "", "", ".tar", ".tar" };
110871e7ee59SPeter Avalos
110971e7ee59SPeter Avalos static
hasSuffix(Char * s,const Char * suffix)111071e7ee59SPeter Avalos Bool hasSuffix ( Char* s, const Char* suffix )
111171e7ee59SPeter Avalos {
111271e7ee59SPeter Avalos Int32 ns = strlen(s);
111371e7ee59SPeter Avalos Int32 nx = strlen(suffix);
111471e7ee59SPeter Avalos if (ns < nx) return False;
111571e7ee59SPeter Avalos if (strcmp(s + ns - nx, suffix) == 0) return True;
111671e7ee59SPeter Avalos return False;
111771e7ee59SPeter Avalos }
111871e7ee59SPeter Avalos
111971e7ee59SPeter Avalos static
mapSuffix(Char * name,const Char * oldSuffix,const Char * newSuffix)112071e7ee59SPeter Avalos Bool mapSuffix ( Char* name,
112171e7ee59SPeter Avalos const Char* oldSuffix,
112271e7ee59SPeter Avalos const Char* newSuffix )
112371e7ee59SPeter Avalos {
112471e7ee59SPeter Avalos if (!hasSuffix(name,oldSuffix)) return False;
112571e7ee59SPeter Avalos name[strlen(name)-strlen(oldSuffix)] = 0;
112671e7ee59SPeter Avalos strcat ( name, newSuffix );
112771e7ee59SPeter Avalos return True;
112871e7ee59SPeter Avalos }
112971e7ee59SPeter Avalos
113071e7ee59SPeter Avalos
113171e7ee59SPeter Avalos /*---------------------------------------------*/
113271e7ee59SPeter Avalos static
compress(Char * name)113371e7ee59SPeter Avalos void compress ( Char *name )
113471e7ee59SPeter Avalos {
113571e7ee59SPeter Avalos FILE *inStr;
113671e7ee59SPeter Avalos FILE *outStr;
113771e7ee59SPeter Avalos Int32 n, i;
113871e7ee59SPeter Avalos struct MY_STAT statBuf;
113971e7ee59SPeter Avalos
114071e7ee59SPeter Avalos deleteOutputOnInterrupt = False;
114171e7ee59SPeter Avalos
114271e7ee59SPeter Avalos if (name == NULL && srcMode != SM_I2O)
114371e7ee59SPeter Avalos panic ( "compress: bad modes\n" );
114471e7ee59SPeter Avalos
114571e7ee59SPeter Avalos switch (srcMode) {
114671e7ee59SPeter Avalos case SM_I2O:
114771e7ee59SPeter Avalos copyFileName ( inName, (Char*)"(stdin)" );
114871e7ee59SPeter Avalos copyFileName ( outName, (Char*)"(stdout)" );
114971e7ee59SPeter Avalos break;
115071e7ee59SPeter Avalos case SM_F2F:
115171e7ee59SPeter Avalos copyFileName ( inName, name );
115271e7ee59SPeter Avalos copyFileName ( outName, name );
115371e7ee59SPeter Avalos strcat ( outName, ".bz2" );
115471e7ee59SPeter Avalos break;
115571e7ee59SPeter Avalos case SM_F2O:
115671e7ee59SPeter Avalos copyFileName ( inName, name );
115771e7ee59SPeter Avalos copyFileName ( outName, (Char*)"(stdout)" );
115871e7ee59SPeter Avalos break;
115971e7ee59SPeter Avalos }
116071e7ee59SPeter Avalos
116171e7ee59SPeter Avalos if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
116271e7ee59SPeter Avalos if (noisy)
116371e7ee59SPeter Avalos fprintf ( stderr, "%s: There are no files matching `%s'.\n",
116471e7ee59SPeter Avalos progName, inName );
116571e7ee59SPeter Avalos setExit(1);
116671e7ee59SPeter Avalos return;
116771e7ee59SPeter Avalos }
116871e7ee59SPeter Avalos if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
116971e7ee59SPeter Avalos fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
117071e7ee59SPeter Avalos progName, inName, strerror(errno) );
117171e7ee59SPeter Avalos setExit(1);
117271e7ee59SPeter Avalos return;
117371e7ee59SPeter Avalos }
117471e7ee59SPeter Avalos for (i = 0; i < BZ_N_SUFFIX_PAIRS; i++) {
117571e7ee59SPeter Avalos if (hasSuffix(inName, zSuffix[i])) {
117671e7ee59SPeter Avalos if (noisy)
117771e7ee59SPeter Avalos fprintf ( stderr,
117871e7ee59SPeter Avalos "%s: Input file %s already has %s suffix.\n",
117971e7ee59SPeter Avalos progName, inName, zSuffix[i] );
118071e7ee59SPeter Avalos setExit(1);
118171e7ee59SPeter Avalos return;
118271e7ee59SPeter Avalos }
118371e7ee59SPeter Avalos }
118471e7ee59SPeter Avalos if ( srcMode == SM_F2F || srcMode == SM_F2O ) {
118571e7ee59SPeter Avalos MY_STAT(inName, &statBuf);
118671e7ee59SPeter Avalos if ( MY_S_ISDIR(statBuf.st_mode) ) {
118771e7ee59SPeter Avalos fprintf( stderr,
118871e7ee59SPeter Avalos "%s: Input file %s is a directory.\n",
118971e7ee59SPeter Avalos progName,inName);
119071e7ee59SPeter Avalos setExit(1);
119171e7ee59SPeter Avalos return;
119271e7ee59SPeter Avalos }
119371e7ee59SPeter Avalos }
119471e7ee59SPeter Avalos if ( srcMode == SM_F2F && !forceOverwrite && notAStandardFile ( inName )) {
119571e7ee59SPeter Avalos if (noisy)
119671e7ee59SPeter Avalos fprintf ( stderr, "%s: Input file %s is not a normal file.\n",
119771e7ee59SPeter Avalos progName, inName );
119871e7ee59SPeter Avalos setExit(1);
119971e7ee59SPeter Avalos return;
120071e7ee59SPeter Avalos }
120171e7ee59SPeter Avalos if ( srcMode == SM_F2F && fileExists ( outName ) ) {
120271e7ee59SPeter Avalos if (forceOverwrite) {
120371e7ee59SPeter Avalos remove(outName);
120471e7ee59SPeter Avalos } else {
120571e7ee59SPeter Avalos fprintf ( stderr, "%s: Output file %s already exists.\n",
120671e7ee59SPeter Avalos progName, outName );
120771e7ee59SPeter Avalos setExit(1);
120871e7ee59SPeter Avalos return;
120971e7ee59SPeter Avalos }
121071e7ee59SPeter Avalos }
121171e7ee59SPeter Avalos if ( srcMode == SM_F2F && !forceOverwrite &&
121271e7ee59SPeter Avalos (n=countHardLinks ( inName )) > 0) {
121371e7ee59SPeter Avalos fprintf ( stderr, "%s: Input file %s has %d other link%s.\n",
121471e7ee59SPeter Avalos progName, inName, n, n > 1 ? "s" : "" );
121571e7ee59SPeter Avalos setExit(1);
121671e7ee59SPeter Avalos return;
121771e7ee59SPeter Avalos }
121871e7ee59SPeter Avalos
121971e7ee59SPeter Avalos if ( srcMode == SM_F2F ) {
122071e7ee59SPeter Avalos /* Save the file's meta-info before we open it. Doing it later
122171e7ee59SPeter Avalos means we mess up the access times. */
122271e7ee59SPeter Avalos saveInputFileMetaInfo ( inName );
122371e7ee59SPeter Avalos }
122471e7ee59SPeter Avalos
122571e7ee59SPeter Avalos switch ( srcMode ) {
122671e7ee59SPeter Avalos
122771e7ee59SPeter Avalos case SM_I2O:
122871e7ee59SPeter Avalos inStr = stdin;
122971e7ee59SPeter Avalos outStr = stdout;
123071e7ee59SPeter Avalos if ( isatty ( fileno ( stdout ) ) ) {
123171e7ee59SPeter Avalos fprintf ( stderr,
123271e7ee59SPeter Avalos "%s: I won't write compressed data to a terminal.\n",
123371e7ee59SPeter Avalos progName );
123471e7ee59SPeter Avalos fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
123571e7ee59SPeter Avalos progName, progName );
123671e7ee59SPeter Avalos setExit(1);
123771e7ee59SPeter Avalos return;
123871e7ee59SPeter Avalos };
123971e7ee59SPeter Avalos break;
124071e7ee59SPeter Avalos
124171e7ee59SPeter Avalos case SM_F2O:
124271e7ee59SPeter Avalos inStr = fopen ( inName, "rb" );
124371e7ee59SPeter Avalos outStr = stdout;
124471e7ee59SPeter Avalos if ( isatty ( fileno ( stdout ) ) ) {
124571e7ee59SPeter Avalos fprintf ( stderr,
124671e7ee59SPeter Avalos "%s: I won't write compressed data to a terminal.\n",
124771e7ee59SPeter Avalos progName );
124871e7ee59SPeter Avalos fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
124971e7ee59SPeter Avalos progName, progName );
125071e7ee59SPeter Avalos if ( inStr != NULL ) fclose ( inStr );
125171e7ee59SPeter Avalos setExit(1);
125271e7ee59SPeter Avalos return;
125371e7ee59SPeter Avalos };
125471e7ee59SPeter Avalos if ( inStr == NULL ) {
125571e7ee59SPeter Avalos fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
125671e7ee59SPeter Avalos progName, inName, strerror(errno) );
125771e7ee59SPeter Avalos setExit(1);
125871e7ee59SPeter Avalos return;
125971e7ee59SPeter Avalos };
126071e7ee59SPeter Avalos break;
126171e7ee59SPeter Avalos
126271e7ee59SPeter Avalos case SM_F2F:
126371e7ee59SPeter Avalos inStr = fopen ( inName, "rb" );
126471e7ee59SPeter Avalos outStr = fopen_output_safely ( outName, "wb" );
126571e7ee59SPeter Avalos if ( outStr == NULL) {
126671e7ee59SPeter Avalos fprintf ( stderr, "%s: Can't create output file %s: %s.\n",
126771e7ee59SPeter Avalos progName, outName, strerror(errno) );
126871e7ee59SPeter Avalos if ( inStr != NULL ) fclose ( inStr );
126971e7ee59SPeter Avalos setExit(1);
127071e7ee59SPeter Avalos return;
127171e7ee59SPeter Avalos }
127271e7ee59SPeter Avalos if ( inStr == NULL ) {
127371e7ee59SPeter Avalos fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
127471e7ee59SPeter Avalos progName, inName, strerror(errno) );
127571e7ee59SPeter Avalos if ( outStr != NULL ) fclose ( outStr );
127671e7ee59SPeter Avalos setExit(1);
127771e7ee59SPeter Avalos return;
127871e7ee59SPeter Avalos };
127971e7ee59SPeter Avalos break;
128071e7ee59SPeter Avalos
128171e7ee59SPeter Avalos default:
128271e7ee59SPeter Avalos panic ( "compress: bad srcMode" );
128371e7ee59SPeter Avalos break;
128471e7ee59SPeter Avalos }
128571e7ee59SPeter Avalos
128671e7ee59SPeter Avalos if (verbosity >= 1) {
128771e7ee59SPeter Avalos fprintf ( stderr, " %s: ", inName );
128871e7ee59SPeter Avalos pad ( inName );
128971e7ee59SPeter Avalos fflush ( stderr );
129071e7ee59SPeter Avalos }
129171e7ee59SPeter Avalos
129271e7ee59SPeter Avalos /*--- Now the input and output handles are sane. Do the Biz. ---*/
129371e7ee59SPeter Avalos outputHandleJustInCase = outStr;
129471e7ee59SPeter Avalos deleteOutputOnInterrupt = True;
129571e7ee59SPeter Avalos compressStream ( inStr, outStr );
129671e7ee59SPeter Avalos outputHandleJustInCase = NULL;
129771e7ee59SPeter Avalos
129871e7ee59SPeter Avalos /*--- If there was an I/O error, we won't get here. ---*/
129971e7ee59SPeter Avalos if ( srcMode == SM_F2F ) {
130071e7ee59SPeter Avalos applySavedTimeInfoToOutputFile ( outName );
130171e7ee59SPeter Avalos deleteOutputOnInterrupt = False;
130271e7ee59SPeter Avalos if ( !keepInputFiles ) {
130371e7ee59SPeter Avalos IntNative retVal = remove ( inName );
130471e7ee59SPeter Avalos ERROR_IF_NOT_ZERO ( retVal );
130571e7ee59SPeter Avalos }
130671e7ee59SPeter Avalos }
130771e7ee59SPeter Avalos
130871e7ee59SPeter Avalos deleteOutputOnInterrupt = False;
130971e7ee59SPeter Avalos }
131071e7ee59SPeter Avalos
131171e7ee59SPeter Avalos
131271e7ee59SPeter Avalos /*---------------------------------------------*/
131371e7ee59SPeter Avalos static
uncompress(Char * name)131471e7ee59SPeter Avalos void uncompress ( Char *name )
131571e7ee59SPeter Avalos {
131671e7ee59SPeter Avalos FILE *inStr;
131771e7ee59SPeter Avalos FILE *outStr;
131871e7ee59SPeter Avalos Int32 n, i;
131971e7ee59SPeter Avalos Bool magicNumberOK;
132071e7ee59SPeter Avalos Bool cantGuess;
132171e7ee59SPeter Avalos struct MY_STAT statBuf;
132271e7ee59SPeter Avalos
132371e7ee59SPeter Avalos deleteOutputOnInterrupt = False;
132471e7ee59SPeter Avalos
132571e7ee59SPeter Avalos if (name == NULL && srcMode != SM_I2O)
132671e7ee59SPeter Avalos panic ( "uncompress: bad modes\n" );
132771e7ee59SPeter Avalos
132871e7ee59SPeter Avalos cantGuess = False;
132971e7ee59SPeter Avalos switch (srcMode) {
133071e7ee59SPeter Avalos case SM_I2O:
133171e7ee59SPeter Avalos copyFileName ( inName, (Char*)"(stdin)" );
133271e7ee59SPeter Avalos copyFileName ( outName, (Char*)"(stdout)" );
133371e7ee59SPeter Avalos break;
133471e7ee59SPeter Avalos case SM_F2F:
133571e7ee59SPeter Avalos copyFileName ( inName, name );
133671e7ee59SPeter Avalos copyFileName ( outName, name );
133771e7ee59SPeter Avalos for (i = 0; i < BZ_N_SUFFIX_PAIRS; i++)
133871e7ee59SPeter Avalos if (mapSuffix(outName,zSuffix[i],unzSuffix[i]))
133971e7ee59SPeter Avalos goto zzz;
134071e7ee59SPeter Avalos cantGuess = True;
134171e7ee59SPeter Avalos strcat ( outName, ".out" );
134271e7ee59SPeter Avalos break;
134371e7ee59SPeter Avalos case SM_F2O:
134471e7ee59SPeter Avalos copyFileName ( inName, name );
134571e7ee59SPeter Avalos copyFileName ( outName, (Char*)"(stdout)" );
134671e7ee59SPeter Avalos break;
134771e7ee59SPeter Avalos }
134871e7ee59SPeter Avalos
134971e7ee59SPeter Avalos zzz:
135071e7ee59SPeter Avalos if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
135171e7ee59SPeter Avalos if (noisy)
135271e7ee59SPeter Avalos fprintf ( stderr, "%s: There are no files matching `%s'.\n",
135371e7ee59SPeter Avalos progName, inName );
135471e7ee59SPeter Avalos setExit(1);
135571e7ee59SPeter Avalos return;
135671e7ee59SPeter Avalos }
135771e7ee59SPeter Avalos if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
135871e7ee59SPeter Avalos fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
135971e7ee59SPeter Avalos progName, inName, strerror(errno) );
136071e7ee59SPeter Avalos setExit(1);
136171e7ee59SPeter Avalos return;
136271e7ee59SPeter Avalos }
136371e7ee59SPeter Avalos if ( srcMode == SM_F2F || srcMode == SM_F2O ) {
136471e7ee59SPeter Avalos MY_STAT(inName, &statBuf);
136571e7ee59SPeter Avalos if ( MY_S_ISDIR(statBuf.st_mode) ) {
136671e7ee59SPeter Avalos fprintf( stderr,
136771e7ee59SPeter Avalos "%s: Input file %s is a directory.\n",
136871e7ee59SPeter Avalos progName,inName);
136971e7ee59SPeter Avalos setExit(1);
137071e7ee59SPeter Avalos return;
137171e7ee59SPeter Avalos }
137271e7ee59SPeter Avalos }
137371e7ee59SPeter Avalos if ( srcMode == SM_F2F && !forceOverwrite && notAStandardFile ( inName )) {
137471e7ee59SPeter Avalos if (noisy)
137571e7ee59SPeter Avalos fprintf ( stderr, "%s: Input file %s is not a normal file.\n",
137671e7ee59SPeter Avalos progName, inName );
137771e7ee59SPeter Avalos setExit(1);
137871e7ee59SPeter Avalos return;
137971e7ee59SPeter Avalos }
138071e7ee59SPeter Avalos if ( /* srcMode == SM_F2F implied && */ cantGuess ) {
138171e7ee59SPeter Avalos if (noisy)
138271e7ee59SPeter Avalos fprintf ( stderr,
138371e7ee59SPeter Avalos "%s: Can't guess original name for %s -- using %s\n",
138471e7ee59SPeter Avalos progName, inName, outName );
138571e7ee59SPeter Avalos /* just a warning, no return */
138671e7ee59SPeter Avalos }
138771e7ee59SPeter Avalos if ( srcMode == SM_F2F && fileExists ( outName ) ) {
138871e7ee59SPeter Avalos if (forceOverwrite) {
138971e7ee59SPeter Avalos remove(outName);
139071e7ee59SPeter Avalos } else {
139171e7ee59SPeter Avalos fprintf ( stderr, "%s: Output file %s already exists.\n",
139271e7ee59SPeter Avalos progName, outName );
139371e7ee59SPeter Avalos setExit(1);
139471e7ee59SPeter Avalos return;
139571e7ee59SPeter Avalos }
139671e7ee59SPeter Avalos }
139771e7ee59SPeter Avalos if ( srcMode == SM_F2F && !forceOverwrite &&
139871e7ee59SPeter Avalos (n=countHardLinks ( inName ) ) > 0) {
139971e7ee59SPeter Avalos fprintf ( stderr, "%s: Input file %s has %d other link%s.\n",
140071e7ee59SPeter Avalos progName, inName, n, n > 1 ? "s" : "" );
140171e7ee59SPeter Avalos setExit(1);
140271e7ee59SPeter Avalos return;
140371e7ee59SPeter Avalos }
140471e7ee59SPeter Avalos
140571e7ee59SPeter Avalos if ( srcMode == SM_F2F ) {
140671e7ee59SPeter Avalos /* Save the file's meta-info before we open it. Doing it later
140771e7ee59SPeter Avalos means we mess up the access times. */
140871e7ee59SPeter Avalos saveInputFileMetaInfo ( inName );
140971e7ee59SPeter Avalos }
141071e7ee59SPeter Avalos
141171e7ee59SPeter Avalos switch ( srcMode ) {
141271e7ee59SPeter Avalos
141371e7ee59SPeter Avalos case SM_I2O:
141471e7ee59SPeter Avalos inStr = stdin;
141571e7ee59SPeter Avalos outStr = stdout;
141671e7ee59SPeter Avalos if ( isatty ( fileno ( stdin ) ) ) {
141771e7ee59SPeter Avalos fprintf ( stderr,
141871e7ee59SPeter Avalos "%s: I won't read compressed data from a terminal.\n",
141971e7ee59SPeter Avalos progName );
142071e7ee59SPeter Avalos fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
142171e7ee59SPeter Avalos progName, progName );
142271e7ee59SPeter Avalos setExit(1);
142371e7ee59SPeter Avalos return;
142471e7ee59SPeter Avalos };
142571e7ee59SPeter Avalos break;
142671e7ee59SPeter Avalos
142771e7ee59SPeter Avalos case SM_F2O:
142871e7ee59SPeter Avalos inStr = fopen ( inName, "rb" );
142971e7ee59SPeter Avalos outStr = stdout;
143071e7ee59SPeter Avalos if ( inStr == NULL ) {
143171e7ee59SPeter Avalos fprintf ( stderr, "%s: Can't open input file %s:%s.\n",
143271e7ee59SPeter Avalos progName, inName, strerror(errno) );
143371e7ee59SPeter Avalos if ( inStr != NULL ) fclose ( inStr );
143471e7ee59SPeter Avalos setExit(1);
143571e7ee59SPeter Avalos return;
143671e7ee59SPeter Avalos };
143771e7ee59SPeter Avalos break;
143871e7ee59SPeter Avalos
143971e7ee59SPeter Avalos case SM_F2F:
144071e7ee59SPeter Avalos inStr = fopen ( inName, "rb" );
144171e7ee59SPeter Avalos outStr = fopen_output_safely ( outName, "wb" );
144271e7ee59SPeter Avalos if ( outStr == NULL) {
144371e7ee59SPeter Avalos fprintf ( stderr, "%s: Can't create output file %s: %s.\n",
144471e7ee59SPeter Avalos progName, outName, strerror(errno) );
144571e7ee59SPeter Avalos if ( inStr != NULL ) fclose ( inStr );
144671e7ee59SPeter Avalos setExit(1);
144771e7ee59SPeter Avalos return;
144871e7ee59SPeter Avalos }
144971e7ee59SPeter Avalos if ( inStr == NULL ) {
145071e7ee59SPeter Avalos fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
145171e7ee59SPeter Avalos progName, inName, strerror(errno) );
145271e7ee59SPeter Avalos if ( outStr != NULL ) fclose ( outStr );
145371e7ee59SPeter Avalos setExit(1);
145471e7ee59SPeter Avalos return;
145571e7ee59SPeter Avalos };
145671e7ee59SPeter Avalos break;
145771e7ee59SPeter Avalos
145871e7ee59SPeter Avalos default:
145971e7ee59SPeter Avalos panic ( "uncompress: bad srcMode" );
146071e7ee59SPeter Avalos break;
146171e7ee59SPeter Avalos }
146271e7ee59SPeter Avalos
146371e7ee59SPeter Avalos if (verbosity >= 1) {
146471e7ee59SPeter Avalos fprintf ( stderr, " %s: ", inName );
146571e7ee59SPeter Avalos pad ( inName );
146671e7ee59SPeter Avalos fflush ( stderr );
146771e7ee59SPeter Avalos }
146871e7ee59SPeter Avalos
146971e7ee59SPeter Avalos /*--- Now the input and output handles are sane. Do the Biz. ---*/
147071e7ee59SPeter Avalos outputHandleJustInCase = outStr;
147171e7ee59SPeter Avalos deleteOutputOnInterrupt = True;
147271e7ee59SPeter Avalos magicNumberOK = uncompressStream ( inStr, outStr );
147371e7ee59SPeter Avalos outputHandleJustInCase = NULL;
147471e7ee59SPeter Avalos
147571e7ee59SPeter Avalos /*--- If there was an I/O error, we won't get here. ---*/
147671e7ee59SPeter Avalos if ( magicNumberOK ) {
147771e7ee59SPeter Avalos if ( srcMode == SM_F2F ) {
147871e7ee59SPeter Avalos applySavedTimeInfoToOutputFile ( outName );
147971e7ee59SPeter Avalos deleteOutputOnInterrupt = False;
148071e7ee59SPeter Avalos if ( !keepInputFiles ) {
148171e7ee59SPeter Avalos IntNative retVal = remove ( inName );
148271e7ee59SPeter Avalos ERROR_IF_NOT_ZERO ( retVal );
148371e7ee59SPeter Avalos }
148471e7ee59SPeter Avalos }
148571e7ee59SPeter Avalos } else {
148671e7ee59SPeter Avalos unzFailsExist = True;
148771e7ee59SPeter Avalos deleteOutputOnInterrupt = False;
148871e7ee59SPeter Avalos if ( srcMode == SM_F2F ) {
148971e7ee59SPeter Avalos IntNative retVal = remove ( outName );
149071e7ee59SPeter Avalos ERROR_IF_NOT_ZERO ( retVal );
149171e7ee59SPeter Avalos }
149271e7ee59SPeter Avalos }
149371e7ee59SPeter Avalos deleteOutputOnInterrupt = False;
149471e7ee59SPeter Avalos
149571e7ee59SPeter Avalos if ( magicNumberOK ) {
149671e7ee59SPeter Avalos if (verbosity >= 1)
149771e7ee59SPeter Avalos fprintf ( stderr, "done\n" );
149871e7ee59SPeter Avalos } else {
149971e7ee59SPeter Avalos setExit(2);
150071e7ee59SPeter Avalos if (verbosity >= 1)
150171e7ee59SPeter Avalos fprintf ( stderr, "not a bzip2 file.\n" ); else
150271e7ee59SPeter Avalos fprintf ( stderr,
150371e7ee59SPeter Avalos "%s: %s is not a bzip2 file.\n",
150471e7ee59SPeter Avalos progName, inName );
150571e7ee59SPeter Avalos }
150671e7ee59SPeter Avalos
150771e7ee59SPeter Avalos }
150871e7ee59SPeter Avalos
150971e7ee59SPeter Avalos
151071e7ee59SPeter Avalos /*---------------------------------------------*/
151171e7ee59SPeter Avalos static
testf(Char * name)151271e7ee59SPeter Avalos void testf ( Char *name )
151371e7ee59SPeter Avalos {
151471e7ee59SPeter Avalos FILE *inStr;
151571e7ee59SPeter Avalos Bool allOK;
151671e7ee59SPeter Avalos struct MY_STAT statBuf;
151771e7ee59SPeter Avalos
151871e7ee59SPeter Avalos deleteOutputOnInterrupt = False;
151971e7ee59SPeter Avalos
152071e7ee59SPeter Avalos if (name == NULL && srcMode != SM_I2O)
152171e7ee59SPeter Avalos panic ( "testf: bad modes\n" );
152271e7ee59SPeter Avalos
152371e7ee59SPeter Avalos copyFileName ( outName, (Char*)"(none)" );
152471e7ee59SPeter Avalos switch (srcMode) {
152571e7ee59SPeter Avalos case SM_I2O: copyFileName ( inName, (Char*)"(stdin)" ); break;
152671e7ee59SPeter Avalos case SM_F2F: copyFileName ( inName, name ); break;
152771e7ee59SPeter Avalos case SM_F2O: copyFileName ( inName, name ); break;
152871e7ee59SPeter Avalos }
152971e7ee59SPeter Avalos
153071e7ee59SPeter Avalos if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
153171e7ee59SPeter Avalos if (noisy)
153271e7ee59SPeter Avalos fprintf ( stderr, "%s: There are no files matching `%s'.\n",
153371e7ee59SPeter Avalos progName, inName );
153471e7ee59SPeter Avalos setExit(1);
153571e7ee59SPeter Avalos return;
153671e7ee59SPeter Avalos }
153771e7ee59SPeter Avalos if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
153871e7ee59SPeter Avalos fprintf ( stderr, "%s: Can't open input %s: %s.\n",
153971e7ee59SPeter Avalos progName, inName, strerror(errno) );
154071e7ee59SPeter Avalos setExit(1);
154171e7ee59SPeter Avalos return;
154271e7ee59SPeter Avalos }
154371e7ee59SPeter Avalos if ( srcMode != SM_I2O ) {
154471e7ee59SPeter Avalos MY_STAT(inName, &statBuf);
154571e7ee59SPeter Avalos if ( MY_S_ISDIR(statBuf.st_mode) ) {
154671e7ee59SPeter Avalos fprintf( stderr,
154771e7ee59SPeter Avalos "%s: Input file %s is a directory.\n",
154871e7ee59SPeter Avalos progName,inName);
154971e7ee59SPeter Avalos setExit(1);
155071e7ee59SPeter Avalos return;
155171e7ee59SPeter Avalos }
155271e7ee59SPeter Avalos }
155371e7ee59SPeter Avalos
155471e7ee59SPeter Avalos switch ( srcMode ) {
155571e7ee59SPeter Avalos
155671e7ee59SPeter Avalos case SM_I2O:
155771e7ee59SPeter Avalos if ( isatty ( fileno ( stdin ) ) ) {
155871e7ee59SPeter Avalos fprintf ( stderr,
155971e7ee59SPeter Avalos "%s: I won't read compressed data from a terminal.\n",
156071e7ee59SPeter Avalos progName );
156171e7ee59SPeter Avalos fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
156271e7ee59SPeter Avalos progName, progName );
156371e7ee59SPeter Avalos setExit(1);
156471e7ee59SPeter Avalos return;
156571e7ee59SPeter Avalos };
156671e7ee59SPeter Avalos inStr = stdin;
156771e7ee59SPeter Avalos break;
156871e7ee59SPeter Avalos
156971e7ee59SPeter Avalos case SM_F2O: case SM_F2F:
157071e7ee59SPeter Avalos inStr = fopen ( inName, "rb" );
157171e7ee59SPeter Avalos if ( inStr == NULL ) {
157271e7ee59SPeter Avalos fprintf ( stderr, "%s: Can't open input file %s:%s.\n",
157371e7ee59SPeter Avalos progName, inName, strerror(errno) );
157471e7ee59SPeter Avalos setExit(1);
157571e7ee59SPeter Avalos return;
157671e7ee59SPeter Avalos };
157771e7ee59SPeter Avalos break;
157871e7ee59SPeter Avalos
157971e7ee59SPeter Avalos default:
158071e7ee59SPeter Avalos panic ( "testf: bad srcMode" );
158171e7ee59SPeter Avalos break;
158271e7ee59SPeter Avalos }
158371e7ee59SPeter Avalos
158471e7ee59SPeter Avalos if (verbosity >= 1) {
158571e7ee59SPeter Avalos fprintf ( stderr, " %s: ", inName );
158671e7ee59SPeter Avalos pad ( inName );
158771e7ee59SPeter Avalos fflush ( stderr );
158871e7ee59SPeter Avalos }
158971e7ee59SPeter Avalos
159071e7ee59SPeter Avalos /*--- Now the input handle is sane. Do the Biz. ---*/
159171e7ee59SPeter Avalos outputHandleJustInCase = NULL;
159271e7ee59SPeter Avalos allOK = testStream ( inStr );
159371e7ee59SPeter Avalos
159471e7ee59SPeter Avalos if (allOK && verbosity >= 1) fprintf ( stderr, "ok\n" );
159571e7ee59SPeter Avalos if (!allOK) testFailsExist = True;
159671e7ee59SPeter Avalos }
159771e7ee59SPeter Avalos
159871e7ee59SPeter Avalos
159971e7ee59SPeter Avalos /*---------------------------------------------*/
160071e7ee59SPeter Avalos static
license(void)160171e7ee59SPeter Avalos void license ( void )
160271e7ee59SPeter Avalos {
160371e7ee59SPeter Avalos fprintf ( stderr,
160471e7ee59SPeter Avalos
160571e7ee59SPeter Avalos "bzip2, a block-sorting file compressor. "
160671e7ee59SPeter Avalos "Version %s.\n"
160771e7ee59SPeter Avalos " \n"
1608*86954436SDaniel Fojt " Copyright (C) 1996-2019 by Julian Seward.\n"
160971e7ee59SPeter Avalos " \n"
161071e7ee59SPeter Avalos " This program is free software; you can redistribute it and/or modify\n"
161171e7ee59SPeter Avalos " it under the terms set out in the LICENSE file, which is included\n"
1612*86954436SDaniel Fojt " in the bzip2 source distribution.\n"
161371e7ee59SPeter Avalos " \n"
161471e7ee59SPeter Avalos " This program is distributed in the hope that it will be useful,\n"
161571e7ee59SPeter Avalos " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
161671e7ee59SPeter Avalos " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
161771e7ee59SPeter Avalos " LICENSE file for more details.\n"
161871e7ee59SPeter Avalos " \n",
161971e7ee59SPeter Avalos BZ2_bzlibVersion()
162071e7ee59SPeter Avalos );
162171e7ee59SPeter Avalos }
162271e7ee59SPeter Avalos
162371e7ee59SPeter Avalos
162471e7ee59SPeter Avalos /*---------------------------------------------*/
162571e7ee59SPeter Avalos static
usage(Char * fullProgName)162671e7ee59SPeter Avalos void usage ( Char *fullProgName )
162771e7ee59SPeter Avalos {
162871e7ee59SPeter Avalos fprintf (
162971e7ee59SPeter Avalos stderr,
163071e7ee59SPeter Avalos "bzip2, a block-sorting file compressor. "
163171e7ee59SPeter Avalos "Version %s.\n"
163271e7ee59SPeter Avalos "\n usage: %s [flags and input files in any order]\n"
163371e7ee59SPeter Avalos "\n"
163471e7ee59SPeter Avalos " -h --help print this message\n"
163571e7ee59SPeter Avalos " -d --decompress force decompression\n"
163671e7ee59SPeter Avalos " -z --compress force compression\n"
163771e7ee59SPeter Avalos " -k --keep keep (don't delete) input files\n"
163871e7ee59SPeter Avalos " -f --force overwrite existing output files\n"
163971e7ee59SPeter Avalos " -t --test test compressed file integrity\n"
164071e7ee59SPeter Avalos " -c --stdout output to standard out\n"
164171e7ee59SPeter Avalos " -q --quiet suppress noncritical error messages\n"
164271e7ee59SPeter Avalos " -v --verbose be verbose (a 2nd -v gives more)\n"
164371e7ee59SPeter Avalos " -L --license display software version & license\n"
164471e7ee59SPeter Avalos " -V --version display software version & license\n"
164571e7ee59SPeter Avalos " -s --small use less memory (at most 2500k)\n"
164671e7ee59SPeter Avalos " -1 .. -9 set block size to 100k .. 900k\n"
164771e7ee59SPeter Avalos " --fast alias for -1\n"
164871e7ee59SPeter Avalos " --best alias for -9\n"
164971e7ee59SPeter Avalos "\n"
165071e7ee59SPeter Avalos " If invoked as `bzip2', default action is to compress.\n"
165171e7ee59SPeter Avalos " as `bunzip2', default action is to decompress.\n"
165271e7ee59SPeter Avalos " as `bzcat', default action is to decompress to stdout.\n"
165371e7ee59SPeter Avalos "\n"
165471e7ee59SPeter Avalos " If no file names are given, bzip2 compresses or decompresses\n"
165571e7ee59SPeter Avalos " from standard input to standard output. You can combine\n"
165671e7ee59SPeter Avalos " short flags, so `-v -4' means the same as -v4 or -4v, &c.\n"
165771e7ee59SPeter Avalos # if BZ_UNIX
165871e7ee59SPeter Avalos "\n"
165971e7ee59SPeter Avalos # endif
166071e7ee59SPeter Avalos ,
166171e7ee59SPeter Avalos
166271e7ee59SPeter Avalos BZ2_bzlibVersion(),
166371e7ee59SPeter Avalos fullProgName
166471e7ee59SPeter Avalos );
166571e7ee59SPeter Avalos }
166671e7ee59SPeter Avalos
166771e7ee59SPeter Avalos
166871e7ee59SPeter Avalos /*---------------------------------------------*/
166971e7ee59SPeter Avalos static
redundant(Char * flag)167071e7ee59SPeter Avalos void redundant ( Char* flag )
167171e7ee59SPeter Avalos {
167271e7ee59SPeter Avalos fprintf (
167371e7ee59SPeter Avalos stderr,
167471e7ee59SPeter Avalos "%s: %s is redundant in versions 0.9.5 and above\n",
167571e7ee59SPeter Avalos progName, flag );
167671e7ee59SPeter Avalos }
167771e7ee59SPeter Avalos
167871e7ee59SPeter Avalos
167971e7ee59SPeter Avalos /*---------------------------------------------*/
168071e7ee59SPeter Avalos /*--
168171e7ee59SPeter Avalos All the garbage from here to main() is purely to
168271e7ee59SPeter Avalos implement a linked list of command-line arguments,
168371e7ee59SPeter Avalos into which main() copies argv[1 .. argc-1].
168471e7ee59SPeter Avalos
168571e7ee59SPeter Avalos The purpose of this exercise is to facilitate
168671e7ee59SPeter Avalos the expansion of wildcard characters * and ? in
168771e7ee59SPeter Avalos filenames for OSs which don't know how to do it
168871e7ee59SPeter Avalos themselves, like MSDOS, Windows 95 and NT.
168971e7ee59SPeter Avalos
169071e7ee59SPeter Avalos The actual Dirty Work is done by the platform-
169171e7ee59SPeter Avalos specific macro APPEND_FILESPEC.
169271e7ee59SPeter Avalos --*/
169371e7ee59SPeter Avalos
169471e7ee59SPeter Avalos typedef
169571e7ee59SPeter Avalos struct zzzz {
169671e7ee59SPeter Avalos Char *name;
169771e7ee59SPeter Avalos struct zzzz *link;
169871e7ee59SPeter Avalos }
169971e7ee59SPeter Avalos Cell;
170071e7ee59SPeter Avalos
170171e7ee59SPeter Avalos
170271e7ee59SPeter Avalos /*---------------------------------------------*/
170371e7ee59SPeter Avalos static
myMalloc(Int32 n)170471e7ee59SPeter Avalos void *myMalloc ( Int32 n )
170571e7ee59SPeter Avalos {
170671e7ee59SPeter Avalos void* p;
170771e7ee59SPeter Avalos
170871e7ee59SPeter Avalos p = malloc ( (size_t)n );
170971e7ee59SPeter Avalos if (p == NULL) outOfMemory ();
171071e7ee59SPeter Avalos return p;
171171e7ee59SPeter Avalos }
171271e7ee59SPeter Avalos
171371e7ee59SPeter Avalos
171471e7ee59SPeter Avalos /*---------------------------------------------*/
171571e7ee59SPeter Avalos static
mkCell(void)171671e7ee59SPeter Avalos Cell *mkCell ( void )
171771e7ee59SPeter Avalos {
171871e7ee59SPeter Avalos Cell *c;
171971e7ee59SPeter Avalos
172071e7ee59SPeter Avalos c = (Cell*) myMalloc ( sizeof ( Cell ) );
172171e7ee59SPeter Avalos c->name = NULL;
172271e7ee59SPeter Avalos c->link = NULL;
172371e7ee59SPeter Avalos return c;
172471e7ee59SPeter Avalos }
172571e7ee59SPeter Avalos
172671e7ee59SPeter Avalos
172771e7ee59SPeter Avalos /*---------------------------------------------*/
172871e7ee59SPeter Avalos static
snocString(Cell * root,Char * name)172971e7ee59SPeter Avalos Cell *snocString ( Cell *root, Char *name )
173071e7ee59SPeter Avalos {
173171e7ee59SPeter Avalos if (root == NULL) {
173271e7ee59SPeter Avalos Cell *tmp = mkCell();
173371e7ee59SPeter Avalos tmp->name = (Char*) myMalloc ( 5 + strlen(name) );
173471e7ee59SPeter Avalos strcpy ( tmp->name, name );
173571e7ee59SPeter Avalos return tmp;
173671e7ee59SPeter Avalos } else {
173771e7ee59SPeter Avalos Cell *tmp = root;
173871e7ee59SPeter Avalos while (tmp->link != NULL) tmp = tmp->link;
173971e7ee59SPeter Avalos tmp->link = snocString ( tmp->link, name );
174071e7ee59SPeter Avalos return root;
174171e7ee59SPeter Avalos }
174271e7ee59SPeter Avalos }
174371e7ee59SPeter Avalos
174471e7ee59SPeter Avalos
174571e7ee59SPeter Avalos /*---------------------------------------------*/
174671e7ee59SPeter Avalos static
addFlagsFromEnvVar(Cell ** argList,Char * varName)174771e7ee59SPeter Avalos void addFlagsFromEnvVar ( Cell** argList, Char* varName )
174871e7ee59SPeter Avalos {
174971e7ee59SPeter Avalos Int32 i, j, k;
175071e7ee59SPeter Avalos Char *envbase, *p;
175171e7ee59SPeter Avalos
175271e7ee59SPeter Avalos envbase = getenv(varName);
175371e7ee59SPeter Avalos if (envbase != NULL) {
175471e7ee59SPeter Avalos p = envbase;
175571e7ee59SPeter Avalos i = 0;
175671e7ee59SPeter Avalos while (True) {
175771e7ee59SPeter Avalos if (p[i] == 0) break;
175871e7ee59SPeter Avalos p += i;
175971e7ee59SPeter Avalos i = 0;
176071e7ee59SPeter Avalos while (isspace((Int32)(p[0]))) p++;
176171e7ee59SPeter Avalos while (p[i] != 0 && !isspace((Int32)(p[i]))) i++;
176271e7ee59SPeter Avalos if (i > 0) {
176371e7ee59SPeter Avalos k = i; if (k > FILE_NAME_LEN-10) k = FILE_NAME_LEN-10;
176471e7ee59SPeter Avalos for (j = 0; j < k; j++) tmpName[j] = p[j];
176571e7ee59SPeter Avalos tmpName[k] = 0;
176671e7ee59SPeter Avalos APPEND_FLAG(*argList, tmpName);
176771e7ee59SPeter Avalos }
176871e7ee59SPeter Avalos }
176971e7ee59SPeter Avalos }
177071e7ee59SPeter Avalos }
177171e7ee59SPeter Avalos
177271e7ee59SPeter Avalos
177371e7ee59SPeter Avalos /*---------------------------------------------*/
177471e7ee59SPeter Avalos #define ISFLAG(s) (strcmp(aa->name, (s))==0)
177571e7ee59SPeter Avalos
main(IntNative argc,Char * argv[])177671e7ee59SPeter Avalos IntNative main ( IntNative argc, Char *argv[] )
177771e7ee59SPeter Avalos {
177871e7ee59SPeter Avalos Int32 i, j;
177971e7ee59SPeter Avalos Char *tmp;
178071e7ee59SPeter Avalos Cell *argList;
178171e7ee59SPeter Avalos Cell *aa;
178271e7ee59SPeter Avalos Bool decode;
178371e7ee59SPeter Avalos
178471e7ee59SPeter Avalos /*-- Be really really really paranoid :-) --*/
178571e7ee59SPeter Avalos if (sizeof(Int32) != 4 || sizeof(UInt32) != 4 ||
178671e7ee59SPeter Avalos sizeof(Int16) != 2 || sizeof(UInt16) != 2 ||
178771e7ee59SPeter Avalos sizeof(Char) != 1 || sizeof(UChar) != 1)
178871e7ee59SPeter Avalos configError();
178971e7ee59SPeter Avalos
179071e7ee59SPeter Avalos /*-- Initialise --*/
179171e7ee59SPeter Avalos outputHandleJustInCase = NULL;
179271e7ee59SPeter Avalos smallMode = False;
179371e7ee59SPeter Avalos keepInputFiles = False;
179471e7ee59SPeter Avalos forceOverwrite = False;
179571e7ee59SPeter Avalos noisy = True;
179671e7ee59SPeter Avalos verbosity = 0;
179771e7ee59SPeter Avalos blockSize100k = 9;
179871e7ee59SPeter Avalos testFailsExist = False;
179971e7ee59SPeter Avalos unzFailsExist = False;
180071e7ee59SPeter Avalos numFileNames = 0;
180171e7ee59SPeter Avalos numFilesProcessed = 0;
180271e7ee59SPeter Avalos workFactor = 30;
180371e7ee59SPeter Avalos deleteOutputOnInterrupt = False;
180471e7ee59SPeter Avalos exitValue = 0;
180571e7ee59SPeter Avalos i = j = 0; /* avoid bogus warning from egcs-1.1.X */
180671e7ee59SPeter Avalos
180771e7ee59SPeter Avalos /*-- Set up signal handlers for mem access errors --*/
180871e7ee59SPeter Avalos signal (SIGSEGV, mySIGSEGVorSIGBUScatcher);
180971e7ee59SPeter Avalos # if BZ_UNIX
181071e7ee59SPeter Avalos # ifndef __DJGPP__
181171e7ee59SPeter Avalos signal (SIGBUS, mySIGSEGVorSIGBUScatcher);
181271e7ee59SPeter Avalos # endif
181371e7ee59SPeter Avalos # endif
181471e7ee59SPeter Avalos
181571e7ee59SPeter Avalos copyFileName ( inName, (Char*)"(none)" );
181671e7ee59SPeter Avalos copyFileName ( outName, (Char*)"(none)" );
181771e7ee59SPeter Avalos
181871e7ee59SPeter Avalos copyFileName ( progNameReally, argv[0] );
181971e7ee59SPeter Avalos progName = &progNameReally[0];
182071e7ee59SPeter Avalos for (tmp = &progNameReally[0]; *tmp != '\0'; tmp++)
182171e7ee59SPeter Avalos if (*tmp == PATH_SEP) progName = tmp + 1;
182271e7ee59SPeter Avalos
182371e7ee59SPeter Avalos
182471e7ee59SPeter Avalos /*-- Copy flags from env var BZIP2, and
182571e7ee59SPeter Avalos expand filename wildcards in arg list.
182671e7ee59SPeter Avalos --*/
182771e7ee59SPeter Avalos argList = NULL;
182871e7ee59SPeter Avalos addFlagsFromEnvVar ( &argList, (Char*)"BZIP2" );
182971e7ee59SPeter Avalos addFlagsFromEnvVar ( &argList, (Char*)"BZIP" );
183071e7ee59SPeter Avalos for (i = 1; i <= argc-1; i++)
183171e7ee59SPeter Avalos APPEND_FILESPEC(argList, argv[i]);
183271e7ee59SPeter Avalos
183371e7ee59SPeter Avalos
183471e7ee59SPeter Avalos /*-- Find the length of the longest filename --*/
183571e7ee59SPeter Avalos longestFileName = 7;
183671e7ee59SPeter Avalos numFileNames = 0;
183771e7ee59SPeter Avalos decode = True;
183871e7ee59SPeter Avalos for (aa = argList; aa != NULL; aa = aa->link) {
183971e7ee59SPeter Avalos if (ISFLAG("--")) { decode = False; continue; }
184071e7ee59SPeter Avalos if (aa->name[0] == '-' && decode) continue;
184171e7ee59SPeter Avalos numFileNames++;
184271e7ee59SPeter Avalos if (longestFileName < (Int32)strlen(aa->name) )
184371e7ee59SPeter Avalos longestFileName = (Int32)strlen(aa->name);
184471e7ee59SPeter Avalos }
184571e7ee59SPeter Avalos
184671e7ee59SPeter Avalos
184771e7ee59SPeter Avalos /*-- Determine source modes; flag handling may change this too. --*/
184871e7ee59SPeter Avalos if (numFileNames == 0)
184971e7ee59SPeter Avalos srcMode = SM_I2O; else srcMode = SM_F2F;
185071e7ee59SPeter Avalos
185171e7ee59SPeter Avalos
185271e7ee59SPeter Avalos /*-- Determine what to do (compress/uncompress/test/cat). --*/
185371e7ee59SPeter Avalos /*-- Note that subsequent flag handling may change this. --*/
185471e7ee59SPeter Avalos opMode = OM_Z;
185571e7ee59SPeter Avalos
185671e7ee59SPeter Avalos if ( (strstr ( progName, "unzip" ) != 0) ||
185771e7ee59SPeter Avalos (strstr ( progName, "UNZIP" ) != 0) )
185871e7ee59SPeter Avalos opMode = OM_UNZ;
185971e7ee59SPeter Avalos
186071e7ee59SPeter Avalos if ( (strstr ( progName, "z2cat" ) != 0) ||
186171e7ee59SPeter Avalos (strstr ( progName, "Z2CAT" ) != 0) ||
186271e7ee59SPeter Avalos (strstr ( progName, "zcat" ) != 0) ||
186371e7ee59SPeter Avalos (strstr ( progName, "ZCAT" ) != 0) ) {
186471e7ee59SPeter Avalos opMode = OM_UNZ;
186571e7ee59SPeter Avalos srcMode = (numFileNames == 0) ? SM_I2O : SM_F2O;
186671e7ee59SPeter Avalos }
186771e7ee59SPeter Avalos
186871e7ee59SPeter Avalos
186971e7ee59SPeter Avalos /*-- Look at the flags. --*/
187071e7ee59SPeter Avalos for (aa = argList; aa != NULL; aa = aa->link) {
187171e7ee59SPeter Avalos if (ISFLAG("--")) break;
187271e7ee59SPeter Avalos if (aa->name[0] == '-' && aa->name[1] != '-') {
187371e7ee59SPeter Avalos for (j = 1; aa->name[j] != '\0'; j++) {
187471e7ee59SPeter Avalos switch (aa->name[j]) {
187571e7ee59SPeter Avalos case 'c': srcMode = SM_F2O; break;
187671e7ee59SPeter Avalos case 'd': opMode = OM_UNZ; break;
187771e7ee59SPeter Avalos case 'z': opMode = OM_Z; break;
187871e7ee59SPeter Avalos case 'f': forceOverwrite = True; break;
187971e7ee59SPeter Avalos case 't': opMode = OM_TEST; break;
188071e7ee59SPeter Avalos case 'k': keepInputFiles = True; break;
188171e7ee59SPeter Avalos case 's': smallMode = True; break;
188271e7ee59SPeter Avalos case 'q': noisy = False; break;
188371e7ee59SPeter Avalos case '1': blockSize100k = 1; break;
188471e7ee59SPeter Avalos case '2': blockSize100k = 2; break;
188571e7ee59SPeter Avalos case '3': blockSize100k = 3; break;
188671e7ee59SPeter Avalos case '4': blockSize100k = 4; break;
188771e7ee59SPeter Avalos case '5': blockSize100k = 5; break;
188871e7ee59SPeter Avalos case '6': blockSize100k = 6; break;
188971e7ee59SPeter Avalos case '7': blockSize100k = 7; break;
189071e7ee59SPeter Avalos case '8': blockSize100k = 8; break;
189171e7ee59SPeter Avalos case '9': blockSize100k = 9; break;
189271e7ee59SPeter Avalos case 'V':
189371e7ee59SPeter Avalos case 'L': license(); break;
189471e7ee59SPeter Avalos case 'v': verbosity++; break;
189571e7ee59SPeter Avalos case 'h': usage ( progName );
189671e7ee59SPeter Avalos exit ( 0 );
189771e7ee59SPeter Avalos break;
189871e7ee59SPeter Avalos default: fprintf ( stderr, "%s: Bad flag `%s'\n",
189971e7ee59SPeter Avalos progName, aa->name );
190071e7ee59SPeter Avalos usage ( progName );
190171e7ee59SPeter Avalos exit ( 1 );
190271e7ee59SPeter Avalos break;
190371e7ee59SPeter Avalos }
190471e7ee59SPeter Avalos }
190571e7ee59SPeter Avalos }
190671e7ee59SPeter Avalos }
190771e7ee59SPeter Avalos
190871e7ee59SPeter Avalos /*-- And again ... --*/
190971e7ee59SPeter Avalos for (aa = argList; aa != NULL; aa = aa->link) {
191071e7ee59SPeter Avalos if (ISFLAG("--")) break;
191171e7ee59SPeter Avalos if (ISFLAG("--stdout")) srcMode = SM_F2O; else
191271e7ee59SPeter Avalos if (ISFLAG("--decompress")) opMode = OM_UNZ; else
191371e7ee59SPeter Avalos if (ISFLAG("--compress")) opMode = OM_Z; else
191471e7ee59SPeter Avalos if (ISFLAG("--force")) forceOverwrite = True; else
191571e7ee59SPeter Avalos if (ISFLAG("--test")) opMode = OM_TEST; else
191671e7ee59SPeter Avalos if (ISFLAG("--keep")) keepInputFiles = True; else
191771e7ee59SPeter Avalos if (ISFLAG("--small")) smallMode = True; else
191871e7ee59SPeter Avalos if (ISFLAG("--quiet")) noisy = False; else
191971e7ee59SPeter Avalos if (ISFLAG("--version")) license(); else
192071e7ee59SPeter Avalos if (ISFLAG("--license")) license(); else
192171e7ee59SPeter Avalos if (ISFLAG("--exponential")) workFactor = 1; else
192271e7ee59SPeter Avalos if (ISFLAG("--repetitive-best")) redundant(aa->name); else
192371e7ee59SPeter Avalos if (ISFLAG("--repetitive-fast")) redundant(aa->name); else
192471e7ee59SPeter Avalos if (ISFLAG("--fast")) blockSize100k = 1; else
192571e7ee59SPeter Avalos if (ISFLAG("--best")) blockSize100k = 9; else
192671e7ee59SPeter Avalos if (ISFLAG("--verbose")) verbosity++; else
192771e7ee59SPeter Avalos if (ISFLAG("--help")) { usage ( progName ); exit ( 0 ); }
192871e7ee59SPeter Avalos else
192971e7ee59SPeter Avalos if (strncmp ( aa->name, "--", 2) == 0) {
193071e7ee59SPeter Avalos fprintf ( stderr, "%s: Bad flag `%s'\n", progName, aa->name );
193171e7ee59SPeter Avalos usage ( progName );
193271e7ee59SPeter Avalos exit ( 1 );
193371e7ee59SPeter Avalos }
193471e7ee59SPeter Avalos }
193571e7ee59SPeter Avalos
193671e7ee59SPeter Avalos if (verbosity > 4) verbosity = 4;
193771e7ee59SPeter Avalos if (opMode == OM_Z && smallMode && blockSize100k > 2)
193871e7ee59SPeter Avalos blockSize100k = 2;
193971e7ee59SPeter Avalos
194071e7ee59SPeter Avalos if (opMode == OM_TEST && srcMode == SM_F2O) {
194171e7ee59SPeter Avalos fprintf ( stderr, "%s: -c and -t cannot be used together.\n",
194271e7ee59SPeter Avalos progName );
194371e7ee59SPeter Avalos exit ( 1 );
194471e7ee59SPeter Avalos }
194571e7ee59SPeter Avalos
194671e7ee59SPeter Avalos if (srcMode == SM_F2O && numFileNames == 0)
194771e7ee59SPeter Avalos srcMode = SM_I2O;
194871e7ee59SPeter Avalos
194971e7ee59SPeter Avalos if (opMode != OM_Z) blockSize100k = 0;
195071e7ee59SPeter Avalos
195171e7ee59SPeter Avalos if (srcMode == SM_F2F) {
195271e7ee59SPeter Avalos signal (SIGINT, mySignalCatcher);
195371e7ee59SPeter Avalos signal (SIGTERM, mySignalCatcher);
195471e7ee59SPeter Avalos # if BZ_UNIX
195571e7ee59SPeter Avalos signal (SIGHUP, mySignalCatcher);
195671e7ee59SPeter Avalos # endif
195771e7ee59SPeter Avalos }
195871e7ee59SPeter Avalos
195971e7ee59SPeter Avalos if (opMode == OM_Z) {
196071e7ee59SPeter Avalos if (srcMode == SM_I2O) {
196171e7ee59SPeter Avalos compress ( NULL );
196271e7ee59SPeter Avalos } else {
196371e7ee59SPeter Avalos decode = True;
196471e7ee59SPeter Avalos for (aa = argList; aa != NULL; aa = aa->link) {
196571e7ee59SPeter Avalos if (ISFLAG("--")) { decode = False; continue; }
196671e7ee59SPeter Avalos if (aa->name[0] == '-' && decode) continue;
196771e7ee59SPeter Avalos numFilesProcessed++;
196871e7ee59SPeter Avalos compress ( aa->name );
196971e7ee59SPeter Avalos }
197071e7ee59SPeter Avalos }
197171e7ee59SPeter Avalos }
197271e7ee59SPeter Avalos else
197371e7ee59SPeter Avalos
197471e7ee59SPeter Avalos if (opMode == OM_UNZ) {
197571e7ee59SPeter Avalos unzFailsExist = False;
197671e7ee59SPeter Avalos if (srcMode == SM_I2O) {
197771e7ee59SPeter Avalos uncompress ( NULL );
197871e7ee59SPeter Avalos } else {
197971e7ee59SPeter Avalos decode = True;
198071e7ee59SPeter Avalos for (aa = argList; aa != NULL; aa = aa->link) {
198171e7ee59SPeter Avalos if (ISFLAG("--")) { decode = False; continue; }
198271e7ee59SPeter Avalos if (aa->name[0] == '-' && decode) continue;
198371e7ee59SPeter Avalos numFilesProcessed++;
198471e7ee59SPeter Avalos uncompress ( aa->name );
198571e7ee59SPeter Avalos }
198671e7ee59SPeter Avalos }
198771e7ee59SPeter Avalos if (unzFailsExist) {
198871e7ee59SPeter Avalos setExit(2);
198971e7ee59SPeter Avalos exit(exitValue);
199071e7ee59SPeter Avalos }
199171e7ee59SPeter Avalos }
199271e7ee59SPeter Avalos
199371e7ee59SPeter Avalos else {
199471e7ee59SPeter Avalos testFailsExist = False;
199571e7ee59SPeter Avalos if (srcMode == SM_I2O) {
199671e7ee59SPeter Avalos testf ( NULL );
199771e7ee59SPeter Avalos } else {
199871e7ee59SPeter Avalos decode = True;
199971e7ee59SPeter Avalos for (aa = argList; aa != NULL; aa = aa->link) {
200071e7ee59SPeter Avalos if (ISFLAG("--")) { decode = False; continue; }
200171e7ee59SPeter Avalos if (aa->name[0] == '-' && decode) continue;
200271e7ee59SPeter Avalos numFilesProcessed++;
200371e7ee59SPeter Avalos testf ( aa->name );
200471e7ee59SPeter Avalos }
200571e7ee59SPeter Avalos }
2006*86954436SDaniel Fojt if (testFailsExist) {
2007*86954436SDaniel Fojt if (noisy) {
200871e7ee59SPeter Avalos fprintf ( stderr,
200971e7ee59SPeter Avalos "\n"
201071e7ee59SPeter Avalos "You can use the `bzip2recover' program to attempt to recover\n"
201171e7ee59SPeter Avalos "data from undamaged sections of corrupted files.\n\n"
201271e7ee59SPeter Avalos );
2013*86954436SDaniel Fojt }
201471e7ee59SPeter Avalos setExit(2);
201571e7ee59SPeter Avalos exit(exitValue);
201671e7ee59SPeter Avalos }
201771e7ee59SPeter Avalos }
201871e7ee59SPeter Avalos
201971e7ee59SPeter Avalos /* Free the argument list memory to mollify leak detectors
202071e7ee59SPeter Avalos (eg) Purify, Checker. Serves no other useful purpose.
202171e7ee59SPeter Avalos */
202271e7ee59SPeter Avalos aa = argList;
202371e7ee59SPeter Avalos while (aa != NULL) {
202471e7ee59SPeter Avalos Cell* aa2 = aa->link;
202571e7ee59SPeter Avalos if (aa->name != NULL) free(aa->name);
202671e7ee59SPeter Avalos free(aa);
202771e7ee59SPeter Avalos aa = aa2;
202871e7ee59SPeter Avalos }
202971e7ee59SPeter Avalos
203071e7ee59SPeter Avalos return exitValue;
203171e7ee59SPeter Avalos }
203271e7ee59SPeter Avalos
203371e7ee59SPeter Avalos
203471e7ee59SPeter Avalos /*-----------------------------------------------------------*/
203571e7ee59SPeter Avalos /*--- end bzip2.c ---*/
203671e7ee59SPeter Avalos /*-----------------------------------------------------------*/
2037