Blame bzlib-src/bzip2.c

Packit Service 4d3269
Packit Service 4d3269
/*-----------------------------------------------------------*/
Packit Service 4d3269
/*--- A block-sorting, lossless compressor        bzip2.c ---*/
Packit Service 4d3269
/*-----------------------------------------------------------*/
Packit Service 4d3269
Packit Service 4d3269
/* ------------------------------------------------------------------
Packit Service 4d3269
   This file is part of bzip2/libbzip2, a program and library for
Packit Service 4d3269
   lossless, block-sorting data compression.
Packit Service 4d3269
Packit Service 4d3269
   bzip2/libbzip2 version 1.0.6 of 6 September 2010
Packit Service 4d3269
   Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
Packit Service 4d3269
Packit Service 4d3269
   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
Packit Service 4d3269
   README file.
Packit Service 4d3269
Packit Service 4d3269
   This program is released under the terms of the license contained
Packit Service 4d3269
   in the file LICENSE.
Packit Service 4d3269
   ------------------------------------------------------------------ */
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/* Place a 1 beside your platform, and 0 elsewhere.
Packit Service 4d3269
   Generic 32-bit Unix.
Packit Service 4d3269
   Also works on 64-bit Unix boxes.
Packit Service 4d3269
   This is the default.
Packit Service 4d3269
*/
Packit Service 4d3269
#define BZ_UNIX      1
Packit Service 4d3269
Packit Service 4d3269
/*--
Packit Service 4d3269
  Win32, as seen by Jacob Navia's excellent
Packit Service 4d3269
  port of (Chris Fraser & David Hanson)'s excellent
Packit Service 4d3269
  lcc compiler.  Or with MS Visual C.
Packit Service 4d3269
  This is selected automatically if compiled by a compiler which
Packit Service 4d3269
  defines _WIN32, not including the Cygwin GCC.
Packit Service 4d3269
--*/
Packit Service 4d3269
#define BZ_LCCWIN32  0
Packit Service 4d3269
Packit Service 4d3269
#if defined(_WIN32) && !defined(__CYGWIN__)
Packit Service 4d3269
#undef  BZ_LCCWIN32
Packit Service 4d3269
#define BZ_LCCWIN32 1
Packit Service 4d3269
#undef  BZ_UNIX
Packit Service 4d3269
#define BZ_UNIX 0
Packit Service 4d3269
#endif
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
/*--
Packit Service 4d3269
  Some stuff for all platforms.
Packit Service 4d3269
--*/
Packit Service 4d3269
Packit Service 4d3269
#include <stdio.h>
Packit Service 4d3269
#include <stdlib.h>
Packit Service 4d3269
#include <string.h>
Packit Service 4d3269
#include <signal.h>
Packit Service 4d3269
#include <math.h>
Packit Service 4d3269
#include <errno.h>
Packit Service 4d3269
#include <ctype.h>
Packit Service 4d3269
#include "bzlib.h"
Packit Service 4d3269
Packit Service 4d3269
#define ERROR_IF_EOF(i)       { if ((i) == EOF)  ioError(); }
Packit Service 4d3269
#define ERROR_IF_NOT_ZERO(i)  { if ((i) != 0)    ioError(); }
Packit Service 4d3269
#define ERROR_IF_MINUS_ONE(i) { if ((i) == (-1)) ioError(); }
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
/*--
Packit Service 4d3269
   Platform-specific stuff.
Packit Service 4d3269
--*/
Packit Service 4d3269
Packit Service 4d3269
#if BZ_UNIX
Packit Service 4d3269
#   include <fcntl.h>
Packit Service 4d3269
#   include <sys/types.h>
Packit Service 4d3269
#   include <utime.h>
Packit Service 4d3269
#   include <unistd.h>
Packit Service 4d3269
#   include <sys/stat.h>
Packit Service 4d3269
#   include <sys/times.h>
Packit Service 4d3269
Packit Service 4d3269
#   define PATH_SEP    '/'
Packit Service 4d3269
#   define MY_LSTAT    lstat
Packit Service 4d3269
#   define MY_STAT     stat
Packit Service 4d3269
#   define MY_S_ISREG  S_ISREG
Packit Service 4d3269
#   define MY_S_ISDIR  S_ISDIR
Packit Service 4d3269
Packit Service 4d3269
#   define APPEND_FILESPEC(root, name) \
Packit Service 4d3269
      root=snocString((root), (name))
Packit Service 4d3269
Packit Service 4d3269
#   define APPEND_FLAG(root, name) \
Packit Service 4d3269
      root=snocString((root), (name))
Packit Service 4d3269
Packit Service 4d3269
#   define SET_BINARY_MODE(fd) /**/
Packit Service 4d3269
Packit Service 4d3269
#   ifdef __GNUC__
Packit Service 4d3269
#      define NORETURN __attribute__ ((noreturn))
Packit Service 4d3269
#   else
Packit Service 4d3269
#      define NORETURN /**/
Packit Service 4d3269
#   endif
Packit Service 4d3269
Packit Service 4d3269
#   ifdef __DJGPP__
Packit Service 4d3269
#     include <io.h>
Packit Service 4d3269
#     include <fcntl.h>
Packit Service 4d3269
#     undef MY_LSTAT
Packit Service 4d3269
#     undef MY_STAT
Packit Service 4d3269
#     define MY_LSTAT stat
Packit Service 4d3269
#     define MY_STAT stat
Packit Service 4d3269
#     undef SET_BINARY_MODE
Packit Service 4d3269
#     define SET_BINARY_MODE(fd)                        \
Packit Service 4d3269
        do {                                            \
Packit Service 4d3269
           int retVal = setmode ( fileno ( fd ),        \
Packit Service 4d3269
                                  O_BINARY );           \
Packit Service 4d3269
           ERROR_IF_MINUS_ONE ( retVal );               \
Packit Service 4d3269
        } while ( 0 )
Packit Service 4d3269
#   endif
Packit Service 4d3269
Packit Service 4d3269
#   ifdef __CYGWIN__
Packit Service 4d3269
#     include <io.h>
Packit Service 4d3269
#     include <fcntl.h>
Packit Service 4d3269
#     undef SET_BINARY_MODE
Packit Service 4d3269
#     define SET_BINARY_MODE(fd)                        \
Packit Service 4d3269
        do {                                            \
Packit Service 4d3269
           int retVal = setmode ( fileno ( fd ),        \
Packit Service 4d3269
                                  O_BINARY );           \
Packit Service 4d3269
           ERROR_IF_MINUS_ONE ( retVal );               \
Packit Service 4d3269
        } while ( 0 )
Packit Service 4d3269
#   endif
Packit Service 4d3269
#endif /* BZ_UNIX */
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
#if BZ_LCCWIN32
Packit Service 4d3269
#   include <io.h>
Packit Service 4d3269
#   include <fcntl.h>
Packit Service 4d3269
#   include <sys\stat.h>
Packit Service 4d3269
Packit Service 4d3269
#   define NORETURN       /**/
Packit Service 4d3269
#   define PATH_SEP       '\\'
Packit Service 4d3269
#   define MY_LSTAT       _stat
Packit Service 4d3269
#   define MY_STAT        _stat
Packit Service 4d3269
#   define MY_S_ISREG(x)  ((x) & _S_IFREG)
Packit Service 4d3269
#   define MY_S_ISDIR(x)  ((x) & _S_IFDIR)
Packit Service 4d3269
Packit Service 4d3269
#   define APPEND_FLAG(root, name) \
Packit Service 4d3269
      root=snocString((root), (name))
Packit Service 4d3269
Packit Service 4d3269
#   define APPEND_FILESPEC(root, name)                \
Packit Service 4d3269
      root = snocString ((root), (name))
Packit Service 4d3269
Packit Service 4d3269
#   define SET_BINARY_MODE(fd)                        \
Packit Service 4d3269
      do {                                            \
Packit Service 4d3269
         int retVal = setmode ( fileno ( fd ),        \
Packit Service 4d3269
                                O_BINARY );           \
Packit Service 4d3269
         ERROR_IF_MINUS_ONE ( retVal );               \
Packit Service 4d3269
      } while ( 0 )
Packit Service 4d3269
Packit Service 4d3269
#endif /* BZ_LCCWIN32 */
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
/*--
Packit Service 4d3269
  Some more stuff for all platforms :-)
Packit Service 4d3269
--*/
Packit Service 4d3269
Packit Service 4d3269
typedef char            Char;
Packit Service 4d3269
typedef unsigned char   Bool;
Packit Service 4d3269
typedef unsigned char   UChar;
Packit Service 4d3269
typedef int             Int32;
Packit Service 4d3269
typedef unsigned int    UInt32;
Packit Service 4d3269
typedef short           Int16;
Packit Service 4d3269
typedef unsigned short  UInt16;
Packit Service 4d3269
                                       
Packit Service 4d3269
#define True  ((Bool)1)
Packit Service 4d3269
#define False ((Bool)0)
Packit Service 4d3269
Packit Service 4d3269
/*--
Packit Service 4d3269
  IntNative is your platform's `native' int size.
Packit Service 4d3269
  Only here to avoid probs with 64-bit platforms.
Packit Service 4d3269
--*/
Packit Service 4d3269
typedef int IntNative;
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------------*/
Packit Service 4d3269
/*--- Misc (file handling) data decls             ---*/
Packit Service 4d3269
/*---------------------------------------------------*/
Packit Service 4d3269
Packit Service 4d3269
Int32   verbosity;
Packit Service 4d3269
Bool    keepInputFiles, smallMode, deleteOutputOnInterrupt;
Packit Service 4d3269
Bool    forceOverwrite, testFailsExist, unzFailsExist, noisy;
Packit Service 4d3269
Int32   numFileNames, numFilesProcessed, blockSize100k;
Packit Service 4d3269
Int32   exitValue;
Packit Service 4d3269
Packit Service 4d3269
/*-- source modes; F==file, I==stdin, O==stdout --*/
Packit Service 4d3269
#define SM_I2O           1
Packit Service 4d3269
#define SM_F2O           2
Packit Service 4d3269
#define SM_F2F           3
Packit Service 4d3269
Packit Service 4d3269
/*-- operation modes --*/
Packit Service 4d3269
#define OM_Z             1
Packit Service 4d3269
#define OM_UNZ           2
Packit Service 4d3269
#define OM_TEST          3
Packit Service 4d3269
Packit Service 4d3269
Int32   opMode;
Packit Service 4d3269
Int32   srcMode;
Packit Service 4d3269
Packit Service 4d3269
#define FILE_NAME_LEN 1034
Packit Service 4d3269
Packit Service 4d3269
Int32   longestFileName;
Packit Service 4d3269
Char    inName [FILE_NAME_LEN];
Packit Service 4d3269
Char    outName[FILE_NAME_LEN];
Packit Service 4d3269
Char    tmpName[FILE_NAME_LEN];
Packit Service 4d3269
Char    *progName;
Packit Service 4d3269
Char    progNameReally[FILE_NAME_LEN];
Packit Service 4d3269
FILE    *outputHandleJustInCase;
Packit Service 4d3269
Int32   workFactor;
Packit Service 4d3269
Packit Service 4d3269
static void    panic                 ( const Char* ) NORETURN;
Packit Service 4d3269
static void    ioError               ( void )        NORETURN;
Packit Service 4d3269
static void    outOfMemory           ( void )        NORETURN;
Packit Service 4d3269
static void    configError           ( void )        NORETURN;
Packit Service 4d3269
static void    crcError              ( void )        NORETURN;
Packit Service 4d3269
static void    cleanUpAndFail        ( Int32 )       NORETURN;
Packit Service 4d3269
static void    compressedStreamEOF   ( void )        NORETURN;
Packit Service 4d3269
Packit Service 4d3269
static void    copyFileName ( Char*, Char* );
Packit Service 4d3269
static void*   myMalloc     ( Int32 );
Packit Service 4d3269
static void    applySavedFileAttrToOutputFile ( IntNative fd );
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------------*/
Packit Service 4d3269
/*--- An implementation of 64-bit ints.  Sigh.    ---*/
Packit Service 4d3269
/*--- Roll on widespread deployment of ANSI C9X ! ---*/
Packit Service 4d3269
/*---------------------------------------------------*/
Packit Service 4d3269
Packit Service 4d3269
typedef
Packit Service 4d3269
   struct { UChar b[8]; } 
Packit Service 4d3269
   UInt64;
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
static
Packit Service 4d3269
void uInt64_from_UInt32s ( UInt64* n, UInt32 lo32, UInt32 hi32 )
Packit Service 4d3269
{
Packit Service 4d3269
   n->b[7] = (UChar)((hi32 >> 24) & 0xFF);
Packit Service 4d3269
   n->b[6] = (UChar)((hi32 >> 16) & 0xFF);
Packit Service 4d3269
   n->b[5] = (UChar)((hi32 >> 8)  & 0xFF);
Packit Service 4d3269
   n->b[4] = (UChar) (hi32        & 0xFF);
Packit Service 4d3269
   n->b[3] = (UChar)((lo32 >> 24) & 0xFF);
Packit Service 4d3269
   n->b[2] = (UChar)((lo32 >> 16) & 0xFF);
Packit Service 4d3269
   n->b[1] = (UChar)((lo32 >> 8)  & 0xFF);
Packit Service 4d3269
   n->b[0] = (UChar) (lo32        & 0xFF);
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
static
Packit Service 4d3269
double uInt64_to_double ( UInt64* n )
Packit Service 4d3269
{
Packit Service 4d3269
   Int32  i;
Packit Service 4d3269
   double base = 1.0;
Packit Service 4d3269
   double sum  = 0.0;
Packit Service 4d3269
   for (i = 0; i < 8; i++) {
Packit Service 4d3269
      sum  += base * (double)(n->b[i]);
Packit Service 4d3269
      base *= 256.0;
Packit Service 4d3269
   }
Packit Service 4d3269
   return sum;
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
static
Packit Service 4d3269
Bool uInt64_isZero ( UInt64* n )
Packit Service 4d3269
{
Packit Service 4d3269
   Int32 i;
Packit Service 4d3269
   for (i = 0; i < 8; i++)
Packit Service 4d3269
      if (n->b[i] != 0) return 0;
Packit Service 4d3269
   return 1;
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/* Divide *n by 10, and return the remainder.  */
Packit Service 4d3269
static 
Packit Service 4d3269
Int32 uInt64_qrm10 ( UInt64* n )
Packit Service 4d3269
{
Packit Service 4d3269
   UInt32 rem, tmp;
Packit Service 4d3269
   Int32  i;
Packit Service 4d3269
   rem = 0;
Packit Service 4d3269
   for (i = 7; i >= 0; i--) {
Packit Service 4d3269
      tmp = rem * 256 + n->b[i];
Packit Service 4d3269
      n->b[i] = tmp / 10;
Packit Service 4d3269
      rem = tmp % 10;
Packit Service 4d3269
   }
Packit Service 4d3269
   return rem;
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/* ... and the Whole Entire Point of all this UInt64 stuff is
Packit Service 4d3269
   so that we can supply the following function.
Packit Service 4d3269
*/
Packit Service 4d3269
static
Packit Service 4d3269
void uInt64_toAscii ( char* outbuf, UInt64* n )
Packit Service 4d3269
{
Packit Service 4d3269
   Int32  i, q;
Packit Service 4d3269
   UChar  buf[32];
Packit Service 4d3269
   Int32  nBuf   = 0;
Packit Service 4d3269
   UInt64 n_copy = *n;
Packit Service 4d3269
   do {
Packit Service 4d3269
      q = uInt64_qrm10 ( &n_copy );
Packit Service 4d3269
      buf[nBuf] = q + '0';
Packit Service 4d3269
      nBuf++;
Packit Service 4d3269
   } while (!uInt64_isZero(&n_copy));
Packit Service 4d3269
   outbuf[nBuf] = 0;
Packit Service 4d3269
   for (i = 0; i < nBuf; i++) 
Packit Service 4d3269
      outbuf[i] = buf[nBuf-i-1];
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------------*/
Packit Service 4d3269
/*--- Processing of complete files and streams    ---*/
Packit Service 4d3269
/*---------------------------------------------------*/
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
static 
Packit Service 4d3269
Bool myfeof ( FILE* f )
Packit Service 4d3269
{
Packit Service 4d3269
   Int32 c = fgetc ( f );
Packit Service 4d3269
   if (c == EOF) return True;
Packit Service 4d3269
   ungetc ( c, f );
Packit Service 4d3269
   return False;
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
static 
Packit Service 4d3269
void compressStream ( FILE *stream, FILE *zStream )
Packit Service 4d3269
{
Packit Service 4d3269
   BZFILE* bzf = NULL;
Packit Service 4d3269
   UChar   ibuf[5000];
Packit Service 4d3269
   Int32   nIbuf;
Packit Service 4d3269
   UInt32  nbytes_in_lo32, nbytes_in_hi32;
Packit Service 4d3269
   UInt32  nbytes_out_lo32, nbytes_out_hi32;
Packit Service 4d3269
   Int32   bzerr, bzerr_dummy, ret;
Packit Service 4d3269
Packit Service 4d3269
   SET_BINARY_MODE(stream);
Packit Service 4d3269
   SET_BINARY_MODE(zStream);
Packit Service 4d3269
Packit Service 4d3269
   if (ferror(stream)) goto errhandler_io;
Packit Service 4d3269
   if (ferror(zStream)) goto errhandler_io;
Packit Service 4d3269
Packit Service 4d3269
   bzf = BZ2_bzWriteOpen ( &bzerr, zStream, 
Packit Service 4d3269
                           blockSize100k, verbosity, workFactor );   
Packit Service 4d3269
   if (bzerr != BZ_OK) goto errhandler;
Packit Service 4d3269
Packit Service 4d3269
   if (verbosity >= 2) fprintf ( stderr, "\n" );
Packit Service 4d3269
Packit Service 4d3269
   while (True) {
Packit Service 4d3269
Packit Service 4d3269
      if (myfeof(stream)) break;
Packit Service 4d3269
      nIbuf = fread ( ibuf, sizeof(UChar), 5000, stream );
Packit Service 4d3269
      if (ferror(stream)) goto errhandler_io;
Packit Service 4d3269
      if (nIbuf > 0) BZ2_bzWrite ( &bzerr, bzf, (void*)ibuf, nIbuf );
Packit Service 4d3269
      if (bzerr != BZ_OK) goto errhandler;
Packit Service 4d3269
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
   BZ2_bzWriteClose64 ( &bzerr, bzf, 0, 
Packit Service 4d3269
                        &nbytes_in_lo32, &nbytes_in_hi32,
Packit Service 4d3269
                        &nbytes_out_lo32, &nbytes_out_hi32 );
Packit Service 4d3269
   if (bzerr != BZ_OK) goto errhandler;
Packit Service 4d3269
Packit Service 4d3269
   if (ferror(zStream)) goto errhandler_io;
Packit Service 4d3269
   ret = fflush ( zStream );
Packit Service 4d3269
   if (ret == EOF) goto errhandler_io;
Packit Service 4d3269
   if (zStream != stdout) {
Packit Service 4d3269
      Int32 fd = fileno ( zStream );
Packit Service 4d3269
      if (fd < 0) goto errhandler_io;
Packit Service 4d3269
      applySavedFileAttrToOutputFile ( fd );
Packit Service 4d3269
      ret = fclose ( zStream );
Packit Service 4d3269
      outputHandleJustInCase = NULL;
Packit Service 4d3269
      if (ret == EOF) goto errhandler_io;
Packit Service 4d3269
   }
Packit Service 4d3269
   outputHandleJustInCase = NULL;
Packit Service 4d3269
   if (ferror(stream)) goto errhandler_io;
Packit Service 4d3269
   ret = fclose ( stream );
Packit Service 4d3269
   if (ret == EOF) goto errhandler_io;
Packit Service 4d3269
Packit Service 4d3269
   if (verbosity >= 1) {
Packit Service 4d3269
      if (nbytes_in_lo32 == 0 && nbytes_in_hi32 == 0) {
Packit Service 4d3269
	 fprintf ( stderr, " no data compressed.\n");
Packit Service 4d3269
      } else {
Packit Service 4d3269
	 Char   buf_nin[32], buf_nout[32];
Packit Service 4d3269
	 UInt64 nbytes_in,   nbytes_out;
Packit Service 4d3269
	 double nbytes_in_d, nbytes_out_d;
Packit Service 4d3269
	 uInt64_from_UInt32s ( &nbytes_in, 
Packit Service 4d3269
			       nbytes_in_lo32, nbytes_in_hi32 );
Packit Service 4d3269
	 uInt64_from_UInt32s ( &nbytes_out, 
Packit Service 4d3269
			       nbytes_out_lo32, nbytes_out_hi32 );
Packit Service 4d3269
	 nbytes_in_d  = uInt64_to_double ( &nbytes_in );
Packit Service 4d3269
	 nbytes_out_d = uInt64_to_double ( &nbytes_out );
Packit Service 4d3269
	 uInt64_toAscii ( buf_nin, &nbytes_in );
Packit Service 4d3269
	 uInt64_toAscii ( buf_nout, &nbytes_out );
Packit Service 4d3269
	 fprintf ( stderr, "%6.3f:1, %6.3f bits/byte, "
Packit Service 4d3269
		   "%5.2f%% saved, %s in, %s out.\n",
Packit Service 4d3269
		   nbytes_in_d / nbytes_out_d,
Packit Service 4d3269
		   (8.0 * nbytes_out_d) / nbytes_in_d,
Packit Service 4d3269
		   100.0 * (1.0 - nbytes_out_d / nbytes_in_d),
Packit Service 4d3269
		   buf_nin,
Packit Service 4d3269
		   buf_nout
Packit Service 4d3269
		 );
Packit Service 4d3269
      }
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
   return;
Packit Service 4d3269
Packit Service 4d3269
   errhandler:
Packit Service 4d3269
   BZ2_bzWriteClose64 ( &bzerr_dummy, bzf, 1, 
Packit Service 4d3269
                        &nbytes_in_lo32, &nbytes_in_hi32,
Packit Service 4d3269
                        &nbytes_out_lo32, &nbytes_out_hi32 );
Packit Service 4d3269
   switch (bzerr) {
Packit Service 4d3269
      case BZ_CONFIG_ERROR:
Packit Service 4d3269
         configError(); break;
Packit Service 4d3269
      case BZ_MEM_ERROR:
Packit Service 4d3269
         outOfMemory (); break;
Packit Service 4d3269
      case BZ_IO_ERROR:
Packit Service 4d3269
         errhandler_io:
Packit Service 4d3269
         ioError(); break;
Packit Service 4d3269
      default:
Packit Service 4d3269
         panic ( "compress:unexpected error" );
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
   panic ( "compress:end" );
Packit Service 4d3269
   /*notreached*/
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
static 
Packit Service 4d3269
Bool uncompressStream ( FILE *zStream, FILE *stream )
Packit Service 4d3269
{
Packit Service 4d3269
   BZFILE* bzf = NULL;
Packit Service 4d3269
   Int32   bzerr, bzerr_dummy, ret, nread, streamNo, i;
Packit Service 4d3269
   UChar   obuf[5000];
Packit Service 4d3269
   UChar   unused[BZ_MAX_UNUSED];
Packit Service 4d3269
   Int32   nUnused;
Packit Service 4d3269
   void*   unusedTmpV;
Packit Service 4d3269
   UChar*  unusedTmp;
Packit Service 4d3269
Packit Service 4d3269
   nUnused = 0;
Packit Service 4d3269
   streamNo = 0;
Packit Service 4d3269
Packit Service 4d3269
   SET_BINARY_MODE(stream);
Packit Service 4d3269
   SET_BINARY_MODE(zStream);
Packit Service 4d3269
Packit Service 4d3269
   if (ferror(stream)) goto errhandler_io;
Packit Service 4d3269
   if (ferror(zStream)) goto errhandler_io;
Packit Service 4d3269
Packit Service 4d3269
   while (True) {
Packit Service 4d3269
Packit Service 4d3269
      bzf = BZ2_bzReadOpen ( 
Packit Service 4d3269
               &bzerr, zStream, verbosity, 
Packit Service 4d3269
               (int)smallMode, unused, nUnused
Packit Service 4d3269
            );
Packit Service 4d3269
      if (bzf == NULL || bzerr != BZ_OK) goto errhandler;
Packit Service 4d3269
      streamNo++;
Packit Service 4d3269
Packit Service 4d3269
      while (bzerr == BZ_OK) {
Packit Service 4d3269
         nread = BZ2_bzRead ( &bzerr, bzf, obuf, 5000 );
Packit Service 4d3269
         if (bzerr == BZ_DATA_ERROR_MAGIC) goto trycat;
Packit Service 4d3269
         if ((bzerr == BZ_OK || bzerr == BZ_STREAM_END) && nread > 0)
Packit Service 4d3269
            fwrite ( obuf, sizeof(UChar), nread, stream );
Packit Service 4d3269
         if (ferror(stream)) goto errhandler_io;
Packit Service 4d3269
      }
Packit Service 4d3269
      if (bzerr != BZ_STREAM_END) goto errhandler;
Packit Service 4d3269
Packit Service 4d3269
      BZ2_bzReadGetUnused ( &bzerr, bzf, &unusedTmpV, &nUnused );
Packit Service 4d3269
      if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" );
Packit Service 4d3269
Packit Service 4d3269
      unusedTmp = (UChar*)unusedTmpV;
Packit Service 4d3269
      for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i];
Packit Service 4d3269
Packit Service 4d3269
      BZ2_bzReadClose ( &bzerr, bzf );
Packit Service 4d3269
      if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" );
Packit Service 4d3269
Packit Service 4d3269
      if (nUnused == 0 && myfeof(zStream)) break;
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
   closeok:
Packit Service 4d3269
   if (ferror(zStream)) goto errhandler_io;
Packit Service 4d3269
   if (stream != stdout) {
Packit Service 4d3269
      Int32 fd = fileno ( stream );
Packit Service 4d3269
      if (fd < 0) goto errhandler_io;
Packit Service 4d3269
      applySavedFileAttrToOutputFile ( fd );
Packit Service 4d3269
   }
Packit Service 4d3269
   ret = fclose ( zStream );
Packit Service 4d3269
   if (ret == EOF) goto errhandler_io;
Packit Service 4d3269
Packit Service 4d3269
   if (ferror(stream)) goto errhandler_io;
Packit Service 4d3269
   ret = fflush ( stream );
Packit Service 4d3269
   if (ret != 0) goto errhandler_io;
Packit Service 4d3269
   if (stream != stdout) {
Packit Service 4d3269
      ret = fclose ( stream );
Packit Service 4d3269
      outputHandleJustInCase = NULL;
Packit Service 4d3269
      if (ret == EOF) goto errhandler_io;
Packit Service 4d3269
   }
Packit Service 4d3269
   outputHandleJustInCase = NULL;
Packit Service 4d3269
   if (verbosity >= 2) fprintf ( stderr, "\n    " );
Packit Service 4d3269
   return True;
Packit Service 4d3269
Packit Service 4d3269
   trycat: 
Packit Service 4d3269
   if (forceOverwrite) {
Packit Service 4d3269
      rewind(zStream);
Packit Service 4d3269
      while (True) {
Packit Service 4d3269
      	 if (myfeof(zStream)) break;
Packit Service 4d3269
      	 nread = fread ( obuf, sizeof(UChar), 5000, zStream );
Packit Service 4d3269
      	 if (ferror(zStream)) goto errhandler_io;
Packit Service 4d3269
      	 if (nread > 0) fwrite ( obuf, sizeof(UChar), nread, stream );
Packit Service 4d3269
      	 if (ferror(stream)) goto errhandler_io;
Packit Service 4d3269
      }
Packit Service 4d3269
      goto closeok;
Packit Service 4d3269
   }
Packit Service 4d3269
  
Packit Service 4d3269
   errhandler:
Packit Service 4d3269
   BZ2_bzReadClose ( &bzerr_dummy, bzf );
Packit Service 4d3269
   switch (bzerr) {
Packit Service 4d3269
      case BZ_CONFIG_ERROR:
Packit Service 4d3269
         configError(); break;
Packit Service 4d3269
      case BZ_IO_ERROR:
Packit Service 4d3269
         errhandler_io:
Packit Service 4d3269
         ioError(); break;
Packit Service 4d3269
      case BZ_DATA_ERROR:
Packit Service 4d3269
         crcError();
Packit Service 4d3269
      case BZ_MEM_ERROR:
Packit Service 4d3269
         outOfMemory();
Packit Service 4d3269
      case BZ_UNEXPECTED_EOF:
Packit Service 4d3269
         compressedStreamEOF();
Packit Service 4d3269
      case BZ_DATA_ERROR_MAGIC:
Packit Service 4d3269
         if (zStream != stdin) fclose(zStream);
Packit Service 4d3269
         if (stream != stdout) fclose(stream);
Packit Service 4d3269
         if (streamNo == 1) {
Packit Service 4d3269
            return False;
Packit Service 4d3269
         } else {
Packit Service 4d3269
            if (noisy)
Packit Service 4d3269
            fprintf ( stderr, 
Packit Service 4d3269
                      "\n%s: %s: trailing garbage after EOF ignored\n",
Packit Service 4d3269
                      progName, inName );
Packit Service 4d3269
            return True;       
Packit Service 4d3269
         }
Packit Service 4d3269
      default:
Packit Service 4d3269
         panic ( "decompress:unexpected error" );
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
   panic ( "decompress:end" );
Packit Service 4d3269
   return True; /*notreached*/
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
static 
Packit Service 4d3269
Bool testStream ( FILE *zStream )
Packit Service 4d3269
{
Packit Service 4d3269
   BZFILE* bzf = NULL;
Packit Service 4d3269
   Int32   bzerr, bzerr_dummy, ret, nread, streamNo, i;
Packit Service 4d3269
   UChar   obuf[5000];
Packit Service 4d3269
   UChar   unused[BZ_MAX_UNUSED];
Packit Service 4d3269
   Int32   nUnused;
Packit Service 4d3269
   void*   unusedTmpV;
Packit Service 4d3269
   UChar*  unusedTmp;
Packit Service 4d3269
Packit Service 4d3269
   nUnused = 0;
Packit Service 4d3269
   streamNo = 0;
Packit Service 4d3269
Packit Service 4d3269
   SET_BINARY_MODE(zStream);
Packit Service 4d3269
   if (ferror(zStream)) goto errhandler_io;
Packit Service 4d3269
Packit Service 4d3269
   while (True) {
Packit Service 4d3269
Packit Service 4d3269
      bzf = BZ2_bzReadOpen ( 
Packit Service 4d3269
               &bzerr, zStream, verbosity, 
Packit Service 4d3269
               (int)smallMode, unused, nUnused
Packit Service 4d3269
            );
Packit Service 4d3269
      if (bzf == NULL || bzerr != BZ_OK) goto errhandler;
Packit Service 4d3269
      streamNo++;
Packit Service 4d3269
Packit Service 4d3269
      while (bzerr == BZ_OK) {
Packit Service 4d3269
         nread = BZ2_bzRead ( &bzerr, bzf, obuf, 5000 );
Packit Service 4d3269
         if (bzerr == BZ_DATA_ERROR_MAGIC) goto errhandler;
Packit Service 4d3269
      }
Packit Service 4d3269
      if (bzerr != BZ_STREAM_END) goto errhandler;
Packit Service 4d3269
Packit Service 4d3269
      BZ2_bzReadGetUnused ( &bzerr, bzf, &unusedTmpV, &nUnused );
Packit Service 4d3269
      if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" );
Packit Service 4d3269
Packit Service 4d3269
      unusedTmp = (UChar*)unusedTmpV;
Packit Service 4d3269
      for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i];
Packit Service 4d3269
Packit Service 4d3269
      BZ2_bzReadClose ( &bzerr, bzf );
Packit Service 4d3269
      if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" );
Packit Service 4d3269
      if (nUnused == 0 && myfeof(zStream)) break;
Packit Service 4d3269
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
   if (ferror(zStream)) goto errhandler_io;
Packit Service 4d3269
   ret = fclose ( zStream );
Packit Service 4d3269
   if (ret == EOF) goto errhandler_io;
Packit Service 4d3269
Packit Service 4d3269
   if (verbosity >= 2) fprintf ( stderr, "\n    " );
Packit Service 4d3269
   return True;
Packit Service 4d3269
Packit Service 4d3269
   errhandler:
Packit Service 4d3269
   BZ2_bzReadClose ( &bzerr_dummy, bzf );
Packit Service 4d3269
   if (verbosity == 0) 
Packit Service 4d3269
      fprintf ( stderr, "%s: %s: ", progName, inName );
Packit Service 4d3269
   switch (bzerr) {
Packit Service 4d3269
      case BZ_CONFIG_ERROR:
Packit Service 4d3269
         configError(); break;
Packit Service 4d3269
      case BZ_IO_ERROR:
Packit Service 4d3269
         errhandler_io:
Packit Service 4d3269
         ioError(); break;
Packit Service 4d3269
      case BZ_DATA_ERROR:
Packit Service 4d3269
         fprintf ( stderr,
Packit Service 4d3269
                   "data integrity (CRC) error in data\n" );
Packit Service 4d3269
         return False;
Packit Service 4d3269
      case BZ_MEM_ERROR:
Packit Service 4d3269
         outOfMemory();
Packit Service 4d3269
      case BZ_UNEXPECTED_EOF:
Packit Service 4d3269
         fprintf ( stderr,
Packit Service 4d3269
                   "file ends unexpectedly\n" );
Packit Service 4d3269
         return False;
Packit Service 4d3269
      case BZ_DATA_ERROR_MAGIC:
Packit Service 4d3269
         if (zStream != stdin) fclose(zStream);
Packit Service 4d3269
         if (streamNo == 1) {
Packit Service 4d3269
          fprintf ( stderr, 
Packit Service 4d3269
                    "bad magic number (file not created by bzip2)\n" );
Packit Service 4d3269
            return False;
Packit Service 4d3269
         } else {
Packit Service 4d3269
            if (noisy)
Packit Service 4d3269
            fprintf ( stderr, 
Packit Service 4d3269
                      "trailing garbage after EOF ignored\n" );
Packit Service 4d3269
            return True;       
Packit Service 4d3269
         }
Packit Service 4d3269
      default:
Packit Service 4d3269
         panic ( "test:unexpected error" );
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
   panic ( "test:end" );
Packit Service 4d3269
   return True; /*notreached*/
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------------*/
Packit Service 4d3269
/*--- Error [non-] handling grunge                ---*/
Packit Service 4d3269
/*---------------------------------------------------*/
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
static
Packit Service 4d3269
void setExit ( Int32 v )
Packit Service 4d3269
{
Packit Service 4d3269
   if (v > exitValue) exitValue = v;
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
static 
Packit Service 4d3269
void cadvise ( void )
Packit Service 4d3269
{
Packit Service 4d3269
   if (noisy)
Packit Service 4d3269
   fprintf (
Packit Service 4d3269
      stderr,
Packit Service 4d3269
      "\nIt is possible that the compressed file(s) have become corrupted.\n"
Packit Service 4d3269
        "You can use the -tvv option to test integrity of such files.\n\n"
Packit Service 4d3269
        "You can use the `bzip2recover' program to attempt to recover\n"
Packit Service 4d3269
        "data from undamaged sections of corrupted files.\n\n"
Packit Service 4d3269
    );
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
static 
Packit Service 4d3269
void showFileNames ( void )
Packit Service 4d3269
{
Packit Service 4d3269
   if (noisy)
Packit Service 4d3269
   fprintf (
Packit Service 4d3269
      stderr,
Packit Service 4d3269
      "\tInput file = %s, output file = %s\n",
Packit Service 4d3269
      inName, outName 
Packit Service 4d3269
   );
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
static 
Packit Service 4d3269
void cleanUpAndFail ( Int32 ec )
Packit Service 4d3269
{
Packit Service 4d3269
   IntNative      retVal;
Packit Service 4d3269
   struct MY_STAT statBuf;
Packit Service 4d3269
Packit Service 4d3269
   if ( srcMode == SM_F2F 
Packit Service 4d3269
        && opMode != OM_TEST
Packit Service 4d3269
        && deleteOutputOnInterrupt ) {
Packit Service 4d3269
Packit Service 4d3269
      /* Check whether input file still exists.  Delete output file
Packit Service 4d3269
         only if input exists to avoid loss of data.  Joerg Prante, 5
Packit Service 4d3269
         January 2002.  (JRS 06-Jan-2002: other changes in 1.0.2 mean
Packit Service 4d3269
         this is less likely to happen.  But to be ultra-paranoid, we
Packit Service 4d3269
         do the check anyway.)  */
Packit Service 4d3269
      retVal = MY_STAT ( inName, &statBuf );
Packit Service 4d3269
      if (retVal == 0) {
Packit Service 4d3269
         if (noisy)
Packit Service 4d3269
            fprintf ( stderr, 
Packit Service 4d3269
                      "%s: Deleting output file %s, if it exists.\n",
Packit Service 4d3269
                      progName, outName );
Packit Service 4d3269
         if (outputHandleJustInCase != NULL)
Packit Service 4d3269
            fclose ( outputHandleJustInCase );
Packit Service 4d3269
         retVal = remove ( outName );
Packit Service 4d3269
         if (retVal != 0)
Packit Service 4d3269
            fprintf ( stderr,
Packit Service 4d3269
                      "%s: WARNING: deletion of output file "
Packit Service 4d3269
                      "(apparently) failed.\n",
Packit Service 4d3269
                      progName );
Packit Service 4d3269
      } else {
Packit Service 4d3269
         fprintf ( stderr,
Packit Service 4d3269
                   "%s: WARNING: deletion of output file suppressed\n",
Packit Service 4d3269
                    progName );
Packit Service 4d3269
         fprintf ( stderr,
Packit Service 4d3269
                   "%s:    since input file no longer exists.  Output file\n",
Packit Service 4d3269
                   progName );
Packit Service 4d3269
         fprintf ( stderr,
Packit Service 4d3269
                   "%s:    `%s' may be incomplete.\n",
Packit Service 4d3269
                   progName, outName );
Packit Service 4d3269
         fprintf ( stderr, 
Packit Service 4d3269
                   "%s:    I suggest doing an integrity test (bzip2 -tv)"
Packit Service 4d3269
                   " of it.\n",
Packit Service 4d3269
                   progName );
Packit Service 4d3269
      }
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
   if (noisy && numFileNames > 0 && numFilesProcessed < numFileNames) {
Packit Service 4d3269
      fprintf ( stderr, 
Packit Service 4d3269
                "%s: WARNING: some files have not been processed:\n"
Packit Service 4d3269
                "%s:    %d specified on command line, %d not processed yet.\n\n",
Packit Service 4d3269
                progName, progName,
Packit Service 4d3269
                numFileNames, numFileNames - numFilesProcessed );
Packit Service 4d3269
   }
Packit Service 4d3269
   setExit(ec);
Packit Service 4d3269
   exit(exitValue);
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
static 
Packit Service 4d3269
void panic ( const Char* s )
Packit Service 4d3269
{
Packit Service 4d3269
   fprintf ( stderr,
Packit Service 4d3269
             "\n%s: PANIC -- internal consistency error:\n"
Packit Service 4d3269
             "\t%s\n"
Packit Service 4d3269
             "\tThis is a BUG.  Please report it to me at:\n"
Packit Service 4d3269
             "\tjseward@bzip.org\n",
Packit Service 4d3269
             progName, s );
Packit Service 4d3269
   showFileNames();
Packit Service 4d3269
   cleanUpAndFail( 3 );
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
static 
Packit Service 4d3269
void crcError ( void )
Packit Service 4d3269
{
Packit Service 4d3269
   fprintf ( stderr,
Packit Service 4d3269
             "\n%s: Data integrity error when decompressing.\n",
Packit Service 4d3269
             progName );
Packit Service 4d3269
   showFileNames();
Packit Service 4d3269
   cadvise();
Packit Service 4d3269
   cleanUpAndFail( 2 );
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
static 
Packit Service 4d3269
void compressedStreamEOF ( void )
Packit Service 4d3269
{
Packit Service 4d3269
  if (noisy) {
Packit Service 4d3269
    fprintf ( stderr,
Packit Service 4d3269
	      "\n%s: Compressed file ends unexpectedly;\n\t"
Packit Service 4d3269
	      "perhaps it is corrupted?  *Possible* reason follows.\n",
Packit Service 4d3269
	      progName );
Packit Service 4d3269
    perror ( progName );
Packit Service 4d3269
    showFileNames();
Packit Service 4d3269
    cadvise();
Packit Service 4d3269
  }
Packit Service 4d3269
  cleanUpAndFail( 2 );
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
static 
Packit Service 4d3269
void ioError ( void )
Packit Service 4d3269
{
Packit Service 4d3269
   fprintf ( stderr,
Packit Service 4d3269
             "\n%s: I/O or other error, bailing out.  "
Packit Service 4d3269
             "Possible reason follows.\n",
Packit Service 4d3269
             progName );
Packit Service 4d3269
   perror ( progName );
Packit Service 4d3269
   showFileNames();
Packit Service 4d3269
   cleanUpAndFail( 1 );
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
static 
Packit Service 4d3269
void mySignalCatcher ( IntNative n )
Packit Service 4d3269
{
Packit Service 4d3269
   fprintf ( stderr,
Packit Service 4d3269
             "\n%s: Control-C or similar caught, quitting.\n",
Packit Service 4d3269
             progName );
Packit Service 4d3269
   cleanUpAndFail(1);
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
static 
Packit Service 4d3269
void mySIGSEGVorSIGBUScatcher ( IntNative n )
Packit Service 4d3269
{
Packit Service 4d3269
   if (opMode == OM_Z)
Packit Service 4d3269
      fprintf ( 
Packit Service 4d3269
      stderr,
Packit Service 4d3269
      "\n%s: Caught a SIGSEGV or SIGBUS whilst compressing.\n"
Packit Service 4d3269
      "\n"
Packit Service 4d3269
      "   Possible causes are (most likely first):\n"
Packit Service 4d3269
      "   (1) This computer has unreliable memory or cache hardware\n"
Packit Service 4d3269
      "       (a surprisingly common problem; try a different machine.)\n"
Packit Service 4d3269
      "   (2) A bug in the compiler used to create this executable\n"
Packit Service 4d3269
      "       (unlikely, if you didn't compile bzip2 yourself.)\n"
Packit Service 4d3269
      "   (3) A real bug in bzip2 -- I hope this should never be the case.\n"
Packit Service 4d3269
      "   The user's manual, Section 4.3, has more info on (1) and (2).\n"
Packit Service 4d3269
      "   \n"
Packit Service 4d3269
      "   If you suspect this is a bug in bzip2, or are unsure about (1)\n"
Packit Service 4d3269
      "   or (2), feel free to report it to me at: jseward@bzip.org.\n"
Packit Service 4d3269
      "   Section 4.3 of the user's manual describes the info a useful\n"
Packit Service 4d3269
      "   bug report should have.  If the manual is available on your\n"
Packit Service 4d3269
      "   system, please try and read it before mailing me.  If you don't\n"
Packit Service 4d3269
      "   have the manual or can't be bothered to read it, mail me anyway.\n"
Packit Service 4d3269
      "\n",
Packit Service 4d3269
      progName );
Packit Service 4d3269
      else
Packit Service 4d3269
      fprintf ( 
Packit Service 4d3269
      stderr,
Packit Service 4d3269
      "\n%s: Caught a SIGSEGV or SIGBUS whilst decompressing.\n"
Packit Service 4d3269
      "\n"
Packit Service 4d3269
      "   Possible causes are (most likely first):\n"
Packit Service 4d3269
      "   (1) The compressed data is corrupted, and bzip2's usual checks\n"
Packit Service 4d3269
      "       failed to detect this.  Try bzip2 -tvv my_file.bz2.\n"
Packit Service 4d3269
      "   (2) This computer has unreliable memory or cache hardware\n"
Packit Service 4d3269
      "       (a surprisingly common problem; try a different machine.)\n"
Packit Service 4d3269
      "   (3) A bug in the compiler used to create this executable\n"
Packit Service 4d3269
      "       (unlikely, if you didn't compile bzip2 yourself.)\n"
Packit Service 4d3269
      "   (4) A real bug in bzip2 -- I hope this should never be the case.\n"
Packit Service 4d3269
      "   The user's manual, Section 4.3, has more info on (2) and (3).\n"
Packit Service 4d3269
      "   \n"
Packit Service 4d3269
      "   If you suspect this is a bug in bzip2, or are unsure about (2)\n"
Packit Service 4d3269
      "   or (3), feel free to report it to me at: jseward@bzip.org.\n"
Packit Service 4d3269
      "   Section 4.3 of the user's manual describes the info a useful\n"
Packit Service 4d3269
      "   bug report should have.  If the manual is available on your\n"
Packit Service 4d3269
      "   system, please try and read it before mailing me.  If you don't\n"
Packit Service 4d3269
      "   have the manual or can't be bothered to read it, mail me anyway.\n"
Packit Service 4d3269
      "\n",
Packit Service 4d3269
      progName );
Packit Service 4d3269
Packit Service 4d3269
   showFileNames();
Packit Service 4d3269
   if (opMode == OM_Z)
Packit Service 4d3269
      cleanUpAndFail( 3 ); else
Packit Service 4d3269
      { cadvise(); cleanUpAndFail( 2 ); }
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
static 
Packit Service 4d3269
void outOfMemory ( void )
Packit Service 4d3269
{
Packit Service 4d3269
   fprintf ( stderr,
Packit Service 4d3269
             "\n%s: couldn't allocate enough memory\n",
Packit Service 4d3269
             progName );
Packit Service 4d3269
   showFileNames();
Packit Service 4d3269
   cleanUpAndFail(1);
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
static 
Packit Service 4d3269
void configError ( void )
Packit Service 4d3269
{
Packit Service 4d3269
   fprintf ( stderr,
Packit Service 4d3269
             "bzip2: I'm not configured correctly for this platform!\n"
Packit Service 4d3269
             "\tI require Int32, Int16 and Char to have sizes\n"
Packit Service 4d3269
             "\tof 4, 2 and 1 bytes to run properly, and they don't.\n"
Packit Service 4d3269
             "\tProbably you can fix this by defining them correctly,\n"
Packit Service 4d3269
             "\tand recompiling.  Bye!\n" );
Packit Service 4d3269
   setExit(3);
Packit Service 4d3269
   exit(exitValue);
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------------*/
Packit Service 4d3269
/*--- The main driver machinery                   ---*/
Packit Service 4d3269
/*---------------------------------------------------*/
Packit Service 4d3269
Packit Service 4d3269
/* All rather crufty.  The main problem is that input files
Packit Service 4d3269
   are stat()d multiple times before use.  This should be
Packit Service 4d3269
   cleaned up. 
Packit Service 4d3269
*/
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
static 
Packit Service 4d3269
void pad ( Char *s )
Packit Service 4d3269
{
Packit Service 4d3269
   Int32 i;
Packit Service 4d3269
   if ( (Int32)strlen(s) >= longestFileName ) return;
Packit Service 4d3269
   for (i = 1; i <= longestFileName - (Int32)strlen(s); i++)
Packit Service 4d3269
      fprintf ( stderr, " " );
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
static 
Packit Service 4d3269
void copyFileName ( Char* to, Char* from ) 
Packit Service 4d3269
{
Packit Service 4d3269
   if ( strlen(from) > FILE_NAME_LEN-10 )  {
Packit Service 4d3269
      fprintf (
Packit Service 4d3269
         stderr,
Packit Service 4d3269
         "bzip2: file name\n`%s'\n"
Packit Service 4d3269
         "is suspiciously (more than %d chars) long.\n"
Packit Service 4d3269
         "Try using a reasonable file name instead.  Sorry! :-)\n",
Packit Service 4d3269
         from, FILE_NAME_LEN-10
Packit Service 4d3269
      );
Packit Service 4d3269
      setExit(1);
Packit Service 4d3269
      exit(exitValue);
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
  strncpy(to,from,FILE_NAME_LEN-10);
Packit Service 4d3269
  to[FILE_NAME_LEN-10]='\0';
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
static 
Packit Service 4d3269
Bool fileExists ( Char* name )
Packit Service 4d3269
{
Packit Service 4d3269
   FILE *tmp   = fopen ( name, "rb" );
Packit Service 4d3269
   Bool exists = (tmp != NULL);
Packit Service 4d3269
   if (tmp != NULL) fclose ( tmp );
Packit Service 4d3269
   return exists;
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
/* Open an output file safely with O_EXCL and good permissions.
Packit Service 4d3269
   This avoids a race condition in versions < 1.0.2, in which
Packit Service 4d3269
   the file was first opened and then had its interim permissions
Packit Service 4d3269
   set safely.  We instead use open() to create the file with
Packit Service 4d3269
   the interim permissions required. (--- --- rw-).
Packit Service 4d3269
Packit Service 4d3269
   For non-Unix platforms, if we are not worrying about
Packit Service 4d3269
   security issues, simple this simply behaves like fopen.
Packit Service 4d3269
*/
Packit Service 4d3269
static
Packit Service 4d3269
FILE* fopen_output_safely ( Char* name, const char* mode )
Packit Service 4d3269
{
Packit Service 4d3269
#  if BZ_UNIX
Packit Service 4d3269
   FILE*     fp;
Packit Service 4d3269
   IntNative fh;
Packit Service 4d3269
   fh = open(name, O_WRONLY|O_CREAT|O_EXCL, S_IWUSR|S_IRUSR);
Packit Service 4d3269
   if (fh == -1) return NULL;
Packit Service 4d3269
   fp = fdopen(fh, mode);
Packit Service 4d3269
   if (fp == NULL) close(fh);
Packit Service 4d3269
   return fp;
Packit Service 4d3269
#  else
Packit Service 4d3269
   return fopen(name, mode);
Packit Service 4d3269
#  endif
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
/*--
Packit Service 4d3269
  if in doubt, return True
Packit Service 4d3269
--*/
Packit Service 4d3269
static 
Packit Service 4d3269
Bool notAStandardFile ( Char* name )
Packit Service 4d3269
{
Packit Service 4d3269
   IntNative      i;
Packit Service 4d3269
   struct MY_STAT statBuf;
Packit Service 4d3269
Packit Service 4d3269
   i = MY_LSTAT ( name, &statBuf );
Packit Service 4d3269
   if (i != 0) return True;
Packit Service 4d3269
   if (MY_S_ISREG(statBuf.st_mode)) return False;
Packit Service 4d3269
   return True;
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
/*--
Packit Service 4d3269
  rac 11/21/98 see if file has hard links to it
Packit Service 4d3269
--*/
Packit Service 4d3269
static 
Packit Service 4d3269
Int32 countHardLinks ( Char* name )
Packit Service 4d3269
{  
Packit Service 4d3269
   IntNative      i;
Packit Service 4d3269
   struct MY_STAT statBuf;
Packit Service 4d3269
Packit Service 4d3269
   i = MY_LSTAT ( name, &statBuf );
Packit Service 4d3269
   if (i != 0) return 0;
Packit Service 4d3269
   return (statBuf.st_nlink - 1);
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
/* Copy modification date, access date, permissions and owner from the
Packit Service 4d3269
   source to destination file.  We have to copy this meta-info off
Packit Service 4d3269
   into fileMetaInfo before starting to compress / decompress it,
Packit Service 4d3269
   because doing it afterwards means we get the wrong access time.
Packit Service 4d3269
Packit Service 4d3269
   To complicate matters, in compress() and decompress() below, the
Packit Service 4d3269
   sequence of tests preceding the call to saveInputFileMetaInfo()
Packit Service 4d3269
   involves calling fileExists(), which in turn establishes its result
Packit Service 4d3269
   by attempting to fopen() the file, and if successful, immediately
Packit Service 4d3269
   fclose()ing it again.  So we have to assume that the fopen() call
Packit Service 4d3269
   does not cause the access time field to be updated.
Packit Service 4d3269
Packit Service 4d3269
   Reading of the man page for stat() (man 2 stat) on RedHat 7.2 seems
Packit Service 4d3269
   to imply that merely doing open() will not affect the access time.
Packit Service 4d3269
   Therefore we merely need to hope that the C library only does
Packit Service 4d3269
   open() as a result of fopen(), and not any kind of read()-ahead
Packit Service 4d3269
   cleverness.
Packit Service 4d3269
Packit Service 4d3269
   It sounds pretty fragile to me.  Whether this carries across
Packit Service 4d3269
   robustly to arbitrary Unix-like platforms (or even works robustly
Packit Service 4d3269
   on this one, RedHat 7.2) is unknown to me.  Nevertheless ...  
Packit Service 4d3269
*/
Packit Service 4d3269
#if BZ_UNIX
Packit Service 4d3269
static 
Packit Service 4d3269
struct MY_STAT fileMetaInfo;
Packit Service 4d3269
#endif
Packit Service 4d3269
Packit Service 4d3269
static 
Packit Service 4d3269
void saveInputFileMetaInfo ( Char *srcName )
Packit Service 4d3269
{
Packit Service 4d3269
#  if BZ_UNIX
Packit Service 4d3269
   IntNative retVal;
Packit Service 4d3269
   /* Note use of stat here, not lstat. */
Packit Service 4d3269
   retVal = MY_STAT( srcName, &fileMetaInfo );
Packit Service 4d3269
   ERROR_IF_NOT_ZERO ( retVal );
Packit Service 4d3269
#  endif
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
static 
Packit Service 4d3269
void applySavedTimeInfoToOutputFile ( Char *dstName )
Packit Service 4d3269
{
Packit Service 4d3269
#  if BZ_UNIX
Packit Service 4d3269
   IntNative      retVal;
Packit Service 4d3269
   struct utimbuf uTimBuf;
Packit Service 4d3269
Packit Service 4d3269
   uTimBuf.actime = fileMetaInfo.st_atime;
Packit Service 4d3269
   uTimBuf.modtime = fileMetaInfo.st_mtime;
Packit Service 4d3269
Packit Service 4d3269
   retVal = utime ( dstName, &uTimBuf );
Packit Service 4d3269
   ERROR_IF_NOT_ZERO ( retVal );
Packit Service 4d3269
#  endif
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
static 
Packit Service 4d3269
void applySavedFileAttrToOutputFile ( IntNative fd )
Packit Service 4d3269
{
Packit Service 4d3269
#  if BZ_UNIX
Packit Service 4d3269
   IntNative retVal;
Packit Service 4d3269
Packit Service 4d3269
   retVal = fchmod ( fd, fileMetaInfo.st_mode );
Packit Service 4d3269
   ERROR_IF_NOT_ZERO ( retVal );
Packit Service 4d3269
Packit Service 4d3269
   (void) fchown ( fd, fileMetaInfo.st_uid, fileMetaInfo.st_gid );
Packit Service 4d3269
   /* chown() will in many cases return with EPERM, which can
Packit Service 4d3269
      be safely ignored.
Packit Service 4d3269
   */
Packit Service 4d3269
#  endif
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
static 
Packit Service 4d3269
Bool containsDubiousChars ( Char* name )
Packit Service 4d3269
{
Packit Service 4d3269
#  if BZ_UNIX
Packit Service 4d3269
   /* On unix, files can contain any characters and the file expansion
Packit Service 4d3269
    * is performed by the shell.
Packit Service 4d3269
    */
Packit Service 4d3269
   return False;
Packit Service 4d3269
#  else /* ! BZ_UNIX */
Packit Service 4d3269
   /* On non-unix (Win* platforms), wildcard characters are not allowed in 
Packit Service 4d3269
    * filenames.
Packit Service 4d3269
    */
Packit Service 4d3269
   for (; *name != '\0'; name++)
Packit Service 4d3269
      if (*name == '?' || *name == '*') return True;
Packit Service 4d3269
   return False;
Packit Service 4d3269
#  endif /* BZ_UNIX */
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
#define BZ_N_SUFFIX_PAIRS 4
Packit Service 4d3269
Packit Service 4d3269
const Char* zSuffix[BZ_N_SUFFIX_PAIRS] 
Packit Service 4d3269
   = { ".bz2", ".bz", ".tbz2", ".tbz" };
Packit Service 4d3269
const Char* unzSuffix[BZ_N_SUFFIX_PAIRS] 
Packit Service 4d3269
   = { "", "", ".tar", ".tar" };
Packit Service 4d3269
Packit Service 4d3269
static 
Packit Service 4d3269
Bool hasSuffix ( Char* s, const Char* suffix )
Packit Service 4d3269
{
Packit Service 4d3269
   Int32 ns = strlen(s);
Packit Service 4d3269
   Int32 nx = strlen(suffix);
Packit Service 4d3269
   if (ns < nx) return False;
Packit Service 4d3269
   if (strcmp(s + ns - nx, suffix) == 0) return True;
Packit Service 4d3269
   return False;
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
static 
Packit Service 4d3269
Bool mapSuffix ( Char* name, 
Packit Service 4d3269
                 const Char* oldSuffix, 
Packit Service 4d3269
                 const Char* newSuffix )
Packit Service 4d3269
{
Packit Service 4d3269
   if (!hasSuffix(name,oldSuffix)) return False;
Packit Service 4d3269
   name[strlen(name)-strlen(oldSuffix)] = 0;
Packit Service 4d3269
   strcat ( name, newSuffix );
Packit Service 4d3269
   return True;
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
static 
Packit Service 4d3269
void compress ( Char *name )
Packit Service 4d3269
{
Packit Service 4d3269
   FILE  *inStr;
Packit Service 4d3269
   FILE  *outStr;
Packit Service 4d3269
   Int32 n, i;
Packit Service 4d3269
   struct MY_STAT statBuf;
Packit Service 4d3269
Packit Service 4d3269
   deleteOutputOnInterrupt = False;
Packit Service 4d3269
Packit Service 4d3269
   if (name == NULL && srcMode != SM_I2O)
Packit Service 4d3269
      panic ( "compress: bad modes\n" );
Packit Service 4d3269
Packit Service 4d3269
   switch (srcMode) {
Packit Service 4d3269
      case SM_I2O: 
Packit Service 4d3269
         copyFileName ( inName, (Char*)"(stdin)" );
Packit Service 4d3269
         copyFileName ( outName, (Char*)"(stdout)" ); 
Packit Service 4d3269
         break;
Packit Service 4d3269
      case SM_F2F: 
Packit Service 4d3269
         copyFileName ( inName, name );
Packit Service 4d3269
         copyFileName ( outName, name );
Packit Service 4d3269
         strcat ( outName, ".bz2" ); 
Packit Service 4d3269
         break;
Packit Service 4d3269
      case SM_F2O: 
Packit Service 4d3269
         copyFileName ( inName, name );
Packit Service 4d3269
         copyFileName ( outName, (Char*)"(stdout)" ); 
Packit Service 4d3269
         break;
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
   if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
Packit Service 4d3269
      if (noisy)
Packit Service 4d3269
      fprintf ( stderr, "%s: There are no files matching `%s'.\n",
Packit Service 4d3269
                progName, inName );
Packit Service 4d3269
      setExit(1);
Packit Service 4d3269
      return;
Packit Service 4d3269
   }
Packit Service 4d3269
   if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
Packit Service 4d3269
      fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
Packit Service 4d3269
                progName, inName, strerror(errno) );
Packit Service 4d3269
      setExit(1);
Packit Service 4d3269
      return;
Packit Service 4d3269
   }
Packit Service 4d3269
   for (i = 0; i < BZ_N_SUFFIX_PAIRS; i++) {
Packit Service 4d3269
      if (hasSuffix(inName, zSuffix[i])) {
Packit Service 4d3269
         if (noisy)
Packit Service 4d3269
         fprintf ( stderr, 
Packit Service 4d3269
                   "%s: Input file %s already has %s suffix.\n",
Packit Service 4d3269
                   progName, inName, zSuffix[i] );
Packit Service 4d3269
         setExit(1);
Packit Service 4d3269
         return;
Packit Service 4d3269
      }
Packit Service 4d3269
   }
Packit Service 4d3269
   if ( srcMode == SM_F2F || srcMode == SM_F2O ) {
Packit Service 4d3269
      MY_STAT(inName, &statBuf);
Packit Service 4d3269
      if ( MY_S_ISDIR(statBuf.st_mode) ) {
Packit Service 4d3269
         fprintf( stderr,
Packit Service 4d3269
                  "%s: Input file %s is a directory.\n",
Packit Service 4d3269
                  progName,inName);
Packit Service 4d3269
         setExit(1);
Packit Service 4d3269
         return;
Packit Service 4d3269
      }
Packit Service 4d3269
   }
Packit Service 4d3269
   if ( srcMode == SM_F2F && !forceOverwrite && notAStandardFile ( inName )) {
Packit Service 4d3269
      if (noisy)
Packit Service 4d3269
      fprintf ( stderr, "%s: Input file %s is not a normal file.\n",
Packit Service 4d3269
                progName, inName );
Packit Service 4d3269
      setExit(1);
Packit Service 4d3269
      return;
Packit Service 4d3269
   }
Packit Service 4d3269
   if ( srcMode == SM_F2F && fileExists ( outName ) ) {
Packit Service 4d3269
      if (forceOverwrite) {
Packit Service 4d3269
	 remove(outName);
Packit Service 4d3269
      } else {
Packit Service 4d3269
	 fprintf ( stderr, "%s: Output file %s already exists.\n",
Packit Service 4d3269
		   progName, outName );
Packit Service 4d3269
	 setExit(1);
Packit Service 4d3269
	 return;
Packit Service 4d3269
      }
Packit Service 4d3269
   }
Packit Service 4d3269
   if ( srcMode == SM_F2F && !forceOverwrite &&
Packit Service 4d3269
        (n=countHardLinks ( inName )) > 0) {
Packit Service 4d3269
      fprintf ( stderr, "%s: Input file %s has %d other link%s.\n",
Packit Service 4d3269
                progName, inName, n, n > 1 ? "s" : "" );
Packit Service 4d3269
      setExit(1);
Packit Service 4d3269
      return;
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
   if ( srcMode == SM_F2F ) {
Packit Service 4d3269
      /* Save the file's meta-info before we open it.  Doing it later
Packit Service 4d3269
         means we mess up the access times. */
Packit Service 4d3269
      saveInputFileMetaInfo ( inName );
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
   switch ( srcMode ) {
Packit Service 4d3269
Packit Service 4d3269
      case SM_I2O:
Packit Service 4d3269
         inStr = stdin;
Packit Service 4d3269
         outStr = stdout;
Packit Service 4d3269
         if ( isatty ( fileno ( stdout ) ) ) {
Packit Service 4d3269
            fprintf ( stderr,
Packit Service 4d3269
                      "%s: I won't write compressed data to a terminal.\n",
Packit Service 4d3269
                      progName );
Packit Service 4d3269
            fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
Packit Service 4d3269
                              progName, progName );
Packit Service 4d3269
            setExit(1);
Packit Service 4d3269
            return;
Packit Service 4d3269
         };
Packit Service 4d3269
         break;
Packit Service 4d3269
Packit Service 4d3269
      case SM_F2O:
Packit Service 4d3269
         inStr = fopen ( inName, "rb" );
Packit Service 4d3269
         outStr = stdout;
Packit Service 4d3269
         if ( isatty ( fileno ( stdout ) ) ) {
Packit Service 4d3269
            fprintf ( stderr,
Packit Service 4d3269
                      "%s: I won't write compressed data to a terminal.\n",
Packit Service 4d3269
                      progName );
Packit Service 4d3269
            fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
Packit Service 4d3269
                              progName, progName );
Packit Service 4d3269
            if ( inStr != NULL ) fclose ( inStr );
Packit Service 4d3269
            setExit(1);
Packit Service 4d3269
            return;
Packit Service 4d3269
         };
Packit Service 4d3269
         if ( inStr == NULL ) {
Packit Service 4d3269
            fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
Packit Service 4d3269
                      progName, inName, strerror(errno) );
Packit Service 4d3269
            setExit(1);
Packit Service 4d3269
            return;
Packit Service 4d3269
         };
Packit Service 4d3269
         break;
Packit Service 4d3269
Packit Service 4d3269
      case SM_F2F:
Packit Service 4d3269
         inStr = fopen ( inName, "rb" );
Packit Service 4d3269
         outStr = fopen_output_safely ( outName, "wb" );
Packit Service 4d3269
         if ( outStr == NULL) {
Packit Service 4d3269
            fprintf ( stderr, "%s: Can't create output file %s: %s.\n",
Packit Service 4d3269
                      progName, outName, strerror(errno) );
Packit Service 4d3269
            if ( inStr != NULL ) fclose ( inStr );
Packit Service 4d3269
            setExit(1);
Packit Service 4d3269
            return;
Packit Service 4d3269
         }
Packit Service 4d3269
         if ( inStr == NULL ) {
Packit Service 4d3269
            fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
Packit Service 4d3269
                      progName, inName, strerror(errno) );
Packit Service 4d3269
            if ( outStr != NULL ) fclose ( outStr );
Packit Service 4d3269
            setExit(1);
Packit Service 4d3269
            return;
Packit Service 4d3269
         };
Packit Service 4d3269
         break;
Packit Service 4d3269
Packit Service 4d3269
      default:
Packit Service 4d3269
         panic ( "compress: bad srcMode" );
Packit Service 4d3269
         break;
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
   if (verbosity >= 1) {
Packit Service 4d3269
      fprintf ( stderr,  "  %s: ", inName );
Packit Service 4d3269
      pad ( inName );
Packit Service 4d3269
      fflush ( stderr );
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
   /*--- Now the input and output handles are sane.  Do the Biz. ---*/
Packit Service 4d3269
   outputHandleJustInCase = outStr;
Packit Service 4d3269
   deleteOutputOnInterrupt = True;
Packit Service 4d3269
   compressStream ( inStr, outStr );
Packit Service 4d3269
   outputHandleJustInCase = NULL;
Packit Service 4d3269
Packit Service 4d3269
   /*--- If there was an I/O error, we won't get here. ---*/
Packit Service 4d3269
   if ( srcMode == SM_F2F ) {
Packit Service 4d3269
      applySavedTimeInfoToOutputFile ( outName );
Packit Service 4d3269
      deleteOutputOnInterrupt = False;
Packit Service 4d3269
      if ( !keepInputFiles ) {
Packit Service 4d3269
         IntNative retVal = remove ( inName );
Packit Service 4d3269
         ERROR_IF_NOT_ZERO ( retVal );
Packit Service 4d3269
      }
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
   deleteOutputOnInterrupt = False;
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
static 
Packit Service 4d3269
void uncompress ( Char *name )
Packit Service 4d3269
{
Packit Service 4d3269
   FILE  *inStr;
Packit Service 4d3269
   FILE  *outStr;
Packit Service 4d3269
   Int32 n, i;
Packit Service 4d3269
   Bool  magicNumberOK;
Packit Service 4d3269
   Bool  cantGuess;
Packit Service 4d3269
   struct MY_STAT statBuf;
Packit Service 4d3269
Packit Service 4d3269
   deleteOutputOnInterrupt = False;
Packit Service 4d3269
Packit Service 4d3269
   if (name == NULL && srcMode != SM_I2O)
Packit Service 4d3269
      panic ( "uncompress: bad modes\n" );
Packit Service 4d3269
Packit Service 4d3269
   cantGuess = False;
Packit Service 4d3269
   switch (srcMode) {
Packit Service 4d3269
      case SM_I2O: 
Packit Service 4d3269
         copyFileName ( inName, (Char*)"(stdin)" );
Packit Service 4d3269
         copyFileName ( outName, (Char*)"(stdout)" ); 
Packit Service 4d3269
         break;
Packit Service 4d3269
      case SM_F2F: 
Packit Service 4d3269
         copyFileName ( inName, name );
Packit Service 4d3269
         copyFileName ( outName, name );
Packit Service 4d3269
         for (i = 0; i < BZ_N_SUFFIX_PAIRS; i++)
Packit Service 4d3269
            if (mapSuffix(outName,zSuffix[i],unzSuffix[i]))
Packit Service 4d3269
               goto zzz; 
Packit Service 4d3269
         cantGuess = True;
Packit Service 4d3269
         strcat ( outName, ".out" );
Packit Service 4d3269
         break;
Packit Service 4d3269
      case SM_F2O: 
Packit Service 4d3269
         copyFileName ( inName, name );
Packit Service 4d3269
         copyFileName ( outName, (Char*)"(stdout)" ); 
Packit Service 4d3269
         break;
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
   zzz:
Packit Service 4d3269
   if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
Packit Service 4d3269
      if (noisy)
Packit Service 4d3269
      fprintf ( stderr, "%s: There are no files matching `%s'.\n",
Packit Service 4d3269
                progName, inName );
Packit Service 4d3269
      setExit(1);
Packit Service 4d3269
      return;
Packit Service 4d3269
   }
Packit Service 4d3269
   if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
Packit Service 4d3269
      fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
Packit Service 4d3269
                progName, inName, strerror(errno) );
Packit Service 4d3269
      setExit(1);
Packit Service 4d3269
      return;
Packit Service 4d3269
   }
Packit Service 4d3269
   if ( srcMode == SM_F2F || srcMode == SM_F2O ) {
Packit Service 4d3269
      MY_STAT(inName, &statBuf);
Packit Service 4d3269
      if ( MY_S_ISDIR(statBuf.st_mode) ) {
Packit Service 4d3269
         fprintf( stderr,
Packit Service 4d3269
                  "%s: Input file %s is a directory.\n",
Packit Service 4d3269
                  progName,inName);
Packit Service 4d3269
         setExit(1);
Packit Service 4d3269
         return;
Packit Service 4d3269
      }
Packit Service 4d3269
   }
Packit Service 4d3269
   if ( srcMode == SM_F2F && !forceOverwrite && notAStandardFile ( inName )) {
Packit Service 4d3269
      if (noisy)
Packit Service 4d3269
      fprintf ( stderr, "%s: Input file %s is not a normal file.\n",
Packit Service 4d3269
                progName, inName );
Packit Service 4d3269
      setExit(1);
Packit Service 4d3269
      return;
Packit Service 4d3269
   }
Packit Service 4d3269
   if ( /* srcMode == SM_F2F implied && */ cantGuess ) {
Packit Service 4d3269
      if (noisy)
Packit Service 4d3269
      fprintf ( stderr, 
Packit Service 4d3269
                "%s: Can't guess original name for %s -- using %s\n",
Packit Service 4d3269
                progName, inName, outName );
Packit Service 4d3269
      /* just a warning, no return */
Packit Service 4d3269
   }   
Packit Service 4d3269
   if ( srcMode == SM_F2F && fileExists ( outName ) ) {
Packit Service 4d3269
      if (forceOverwrite) {
Packit Service 4d3269
	remove(outName);
Packit Service 4d3269
      } else {
Packit Service 4d3269
        fprintf ( stderr, "%s: Output file %s already exists.\n",
Packit Service 4d3269
                  progName, outName );
Packit Service 4d3269
        setExit(1);
Packit Service 4d3269
        return;
Packit Service 4d3269
      }
Packit Service 4d3269
   }
Packit Service 4d3269
   if ( srcMode == SM_F2F && !forceOverwrite &&
Packit Service 4d3269
        (n=countHardLinks ( inName ) ) > 0) {
Packit Service 4d3269
      fprintf ( stderr, "%s: Input file %s has %d other link%s.\n",
Packit Service 4d3269
                progName, inName, n, n > 1 ? "s" : "" );
Packit Service 4d3269
      setExit(1);
Packit Service 4d3269
      return;
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
   if ( srcMode == SM_F2F ) {
Packit Service 4d3269
      /* Save the file's meta-info before we open it.  Doing it later
Packit Service 4d3269
         means we mess up the access times. */
Packit Service 4d3269
      saveInputFileMetaInfo ( inName );
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
   switch ( srcMode ) {
Packit Service 4d3269
Packit Service 4d3269
      case SM_I2O:
Packit Service 4d3269
         inStr = stdin;
Packit Service 4d3269
         outStr = stdout;
Packit Service 4d3269
         if ( isatty ( fileno ( stdin ) ) ) {
Packit Service 4d3269
            fprintf ( stderr,
Packit Service 4d3269
                      "%s: I won't read compressed data from a terminal.\n",
Packit Service 4d3269
                      progName );
Packit Service 4d3269
            fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
Packit Service 4d3269
                              progName, progName );
Packit Service 4d3269
            setExit(1);
Packit Service 4d3269
            return;
Packit Service 4d3269
         };
Packit Service 4d3269
         break;
Packit Service 4d3269
Packit Service 4d3269
      case SM_F2O:
Packit Service 4d3269
         inStr = fopen ( inName, "rb" );
Packit Service 4d3269
         outStr = stdout;
Packit Service 4d3269
         if ( inStr == NULL ) {
Packit Service 4d3269
            fprintf ( stderr, "%s: Can't open input file %s:%s.\n",
Packit Service 4d3269
                      progName, inName, strerror(errno) );
Packit Service 4d3269
            if ( inStr != NULL ) fclose ( inStr );
Packit Service 4d3269
            setExit(1);
Packit Service 4d3269
            return;
Packit Service 4d3269
         };
Packit Service 4d3269
         break;
Packit Service 4d3269
Packit Service 4d3269
      case SM_F2F:
Packit Service 4d3269
         inStr = fopen ( inName, "rb" );
Packit Service 4d3269
         outStr = fopen_output_safely ( outName, "wb" );
Packit Service 4d3269
         if ( outStr == NULL) {
Packit Service 4d3269
            fprintf ( stderr, "%s: Can't create output file %s: %s.\n",
Packit Service 4d3269
                      progName, outName, strerror(errno) );
Packit Service 4d3269
            if ( inStr != NULL ) fclose ( inStr );
Packit Service 4d3269
            setExit(1);
Packit Service 4d3269
            return;
Packit Service 4d3269
         }
Packit Service 4d3269
         if ( inStr == NULL ) {
Packit Service 4d3269
            fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
Packit Service 4d3269
                      progName, inName, strerror(errno) );
Packit Service 4d3269
            if ( outStr != NULL ) fclose ( outStr );
Packit Service 4d3269
            setExit(1);
Packit Service 4d3269
            return;
Packit Service 4d3269
         };
Packit Service 4d3269
         break;
Packit Service 4d3269
Packit Service 4d3269
      default:
Packit Service 4d3269
         panic ( "uncompress: bad srcMode" );
Packit Service 4d3269
         break;
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
   if (verbosity >= 1) {
Packit Service 4d3269
      fprintf ( stderr, "  %s: ", inName );
Packit Service 4d3269
      pad ( inName );
Packit Service 4d3269
      fflush ( stderr );
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
   /*--- Now the input and output handles are sane.  Do the Biz. ---*/
Packit Service 4d3269
   outputHandleJustInCase = outStr;
Packit Service 4d3269
   deleteOutputOnInterrupt = True;
Packit Service 4d3269
   magicNumberOK = uncompressStream ( inStr, outStr );
Packit Service 4d3269
   outputHandleJustInCase = NULL;
Packit Service 4d3269
Packit Service 4d3269
   /*--- If there was an I/O error, we won't get here. ---*/
Packit Service 4d3269
   if ( magicNumberOK ) {
Packit Service 4d3269
      if ( srcMode == SM_F2F ) {
Packit Service 4d3269
         applySavedTimeInfoToOutputFile ( outName );
Packit Service 4d3269
         deleteOutputOnInterrupt = False;
Packit Service 4d3269
         if ( !keepInputFiles ) {
Packit Service 4d3269
            IntNative retVal = remove ( inName );
Packit Service 4d3269
            ERROR_IF_NOT_ZERO ( retVal );
Packit Service 4d3269
         }
Packit Service 4d3269
      }
Packit Service 4d3269
   } else {
Packit Service 4d3269
      unzFailsExist = True;
Packit Service 4d3269
      deleteOutputOnInterrupt = False;
Packit Service 4d3269
      if ( srcMode == SM_F2F ) {
Packit Service 4d3269
         IntNative retVal = remove ( outName );
Packit Service 4d3269
         ERROR_IF_NOT_ZERO ( retVal );
Packit Service 4d3269
      }
Packit Service 4d3269
   }
Packit Service 4d3269
   deleteOutputOnInterrupt = False;
Packit Service 4d3269
Packit Service 4d3269
   if ( magicNumberOK ) {
Packit Service 4d3269
      if (verbosity >= 1)
Packit Service 4d3269
         fprintf ( stderr, "done\n" );
Packit Service 4d3269
   } else {
Packit Service 4d3269
      setExit(2);
Packit Service 4d3269
      if (verbosity >= 1)
Packit Service 4d3269
         fprintf ( stderr, "not a bzip2 file.\n" ); else
Packit Service 4d3269
         fprintf ( stderr,
Packit Service 4d3269
                   "%s: %s is not a bzip2 file.\n",
Packit Service 4d3269
                   progName, inName );
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
static 
Packit Service 4d3269
void testf ( Char *name )
Packit Service 4d3269
{
Packit Service 4d3269
   FILE *inStr;
Packit Service 4d3269
   Bool allOK;
Packit Service 4d3269
   struct MY_STAT statBuf;
Packit Service 4d3269
Packit Service 4d3269
   deleteOutputOnInterrupt = False;
Packit Service 4d3269
Packit Service 4d3269
   if (name == NULL && srcMode != SM_I2O)
Packit Service 4d3269
      panic ( "testf: bad modes\n" );
Packit Service 4d3269
Packit Service 4d3269
   copyFileName ( outName, (Char*)"(none)" );
Packit Service 4d3269
   switch (srcMode) {
Packit Service 4d3269
      case SM_I2O: copyFileName ( inName, (Char*)"(stdin)" ); break;
Packit Service 4d3269
      case SM_F2F: copyFileName ( inName, name ); break;
Packit Service 4d3269
      case SM_F2O: copyFileName ( inName, name ); break;
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
   if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
Packit Service 4d3269
      if (noisy)
Packit Service 4d3269
      fprintf ( stderr, "%s: There are no files matching `%s'.\n",
Packit Service 4d3269
                progName, inName );
Packit Service 4d3269
      setExit(1);
Packit Service 4d3269
      return;
Packit Service 4d3269
   }
Packit Service 4d3269
   if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
Packit Service 4d3269
      fprintf ( stderr, "%s: Can't open input %s: %s.\n",
Packit Service 4d3269
                progName, inName, strerror(errno) );
Packit Service 4d3269
      setExit(1);
Packit Service 4d3269
      return;
Packit Service 4d3269
   }
Packit Service 4d3269
   if ( srcMode != SM_I2O ) {
Packit Service 4d3269
      MY_STAT(inName, &statBuf);
Packit Service 4d3269
      if ( MY_S_ISDIR(statBuf.st_mode) ) {
Packit Service 4d3269
         fprintf( stderr,
Packit Service 4d3269
                  "%s: Input file %s is a directory.\n",
Packit Service 4d3269
                  progName,inName);
Packit Service 4d3269
         setExit(1);
Packit Service 4d3269
         return;
Packit Service 4d3269
      }
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
   switch ( srcMode ) {
Packit Service 4d3269
Packit Service 4d3269
      case SM_I2O:
Packit Service 4d3269
         if ( isatty ( fileno ( stdin ) ) ) {
Packit Service 4d3269
            fprintf ( stderr,
Packit Service 4d3269
                      "%s: I won't read compressed data from a terminal.\n",
Packit Service 4d3269
                      progName );
Packit Service 4d3269
            fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
Packit Service 4d3269
                              progName, progName );
Packit Service 4d3269
            setExit(1);
Packit Service 4d3269
            return;
Packit Service 4d3269
         };
Packit Service 4d3269
         inStr = stdin;
Packit Service 4d3269
         break;
Packit Service 4d3269
Packit Service 4d3269
      case SM_F2O: case SM_F2F:
Packit Service 4d3269
         inStr = fopen ( inName, "rb" );
Packit Service 4d3269
         if ( inStr == NULL ) {
Packit Service 4d3269
            fprintf ( stderr, "%s: Can't open input file %s:%s.\n",
Packit Service 4d3269
                      progName, inName, strerror(errno) );
Packit Service 4d3269
            setExit(1);
Packit Service 4d3269
            return;
Packit Service 4d3269
         };
Packit Service 4d3269
         break;
Packit Service 4d3269
Packit Service 4d3269
      default:
Packit Service 4d3269
         panic ( "testf: bad srcMode" );
Packit Service 4d3269
         break;
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
   if (verbosity >= 1) {
Packit Service 4d3269
      fprintf ( stderr, "  %s: ", inName );
Packit Service 4d3269
      pad ( inName );
Packit Service 4d3269
      fflush ( stderr );
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
   /*--- Now the input handle is sane.  Do the Biz. ---*/
Packit Service 4d3269
   outputHandleJustInCase = NULL;
Packit Service 4d3269
   allOK = testStream ( inStr );
Packit Service 4d3269
Packit Service 4d3269
   if (allOK && verbosity >= 1) fprintf ( stderr, "ok\n" );
Packit Service 4d3269
   if (!allOK) testFailsExist = True;
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
static 
Packit Service 4d3269
void license ( void )
Packit Service 4d3269
{
Packit Service 4d3269
   fprintf ( stderr,
Packit Service 4d3269
Packit Service 4d3269
    "bzip2, a block-sorting file compressor.  "
Packit Service 4d3269
    "Version %s.\n"
Packit Service 4d3269
    "   \n"
Packit Service 4d3269
    "   Copyright (C) 1996-2010 by Julian Seward.\n"
Packit Service 4d3269
    "   \n"
Packit Service 4d3269
    "   This program is free software; you can redistribute it and/or modify\n"
Packit Service 4d3269
    "   it under the terms set out in the LICENSE file, which is included\n"
Packit Service 4d3269
    "   in the bzip2-1.0.6 source distribution.\n"
Packit Service 4d3269
    "   \n"
Packit Service 4d3269
    "   This program is distributed in the hope that it will be useful,\n"
Packit Service 4d3269
    "   but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
Packit Service 4d3269
    "   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
Packit Service 4d3269
    "   LICENSE file for more details.\n"
Packit Service 4d3269
    "   \n",
Packit Service 4d3269
    BZ2_bzlibVersion()
Packit Service 4d3269
   );
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
static 
Packit Service 4d3269
void usage ( Char *fullProgName )
Packit Service 4d3269
{
Packit Service 4d3269
   fprintf (
Packit Service 4d3269
      stderr,
Packit Service 4d3269
      "bzip2, a block-sorting file compressor.  "
Packit Service 4d3269
      "Version %s.\n"
Packit Service 4d3269
      "\n   usage: %s [flags and input files in any order]\n"
Packit Service 4d3269
      "\n"
Packit Service 4d3269
      "   -h --help           print this message\n"
Packit Service 4d3269
      "   -d --decompress     force decompression\n"
Packit Service 4d3269
      "   -z --compress       force compression\n"
Packit Service 4d3269
      "   -k --keep           keep (don't delete) input files\n"
Packit Service 4d3269
      "   -f --force          overwrite existing output files\n"
Packit Service 4d3269
      "   -t --test           test compressed file integrity\n"
Packit Service 4d3269
      "   -c --stdout         output to standard out\n"
Packit Service 4d3269
      "   -q --quiet          suppress noncritical error messages\n"
Packit Service 4d3269
      "   -v --verbose        be verbose (a 2nd -v gives more)\n"
Packit Service 4d3269
      "   -L --license        display software version & license\n"
Packit Service 4d3269
      "   -V --version        display software version & license\n"
Packit Service 4d3269
      "   -s --small          use less memory (at most 2500k)\n"
Packit Service 4d3269
      "   -1 .. -9            set block size to 100k .. 900k\n"
Packit Service 4d3269
      "   --fast              alias for -1\n"
Packit Service 4d3269
      "   --best              alias for -9\n"
Packit Service 4d3269
      "\n"
Packit Service 4d3269
      "   If invoked as `bzip2', default action is to compress.\n"
Packit Service 4d3269
      "              as `bunzip2',  default action is to decompress.\n"
Packit Service 4d3269
      "              as `bzcat', default action is to decompress to stdout.\n"
Packit Service 4d3269
      "\n"
Packit Service 4d3269
      "   If no file names are given, bzip2 compresses or decompresses\n"
Packit Service 4d3269
      "   from standard input to standard output.  You can combine\n"
Packit Service 4d3269
      "   short flags, so `-v -4' means the same as -v4 or -4v, &c.\n"
Packit Service 4d3269
#     if BZ_UNIX
Packit Service 4d3269
      "\n"
Packit Service 4d3269
#     endif
Packit Service 4d3269
      ,
Packit Service 4d3269
Packit Service 4d3269
      BZ2_bzlibVersion(),
Packit Service 4d3269
      fullProgName
Packit Service 4d3269
   );
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
static 
Packit Service 4d3269
void redundant ( Char* flag )
Packit Service 4d3269
{
Packit Service 4d3269
   fprintf ( 
Packit Service 4d3269
      stderr, 
Packit Service 4d3269
      "%s: %s is redundant in versions 0.9.5 and above\n",
Packit Service 4d3269
      progName, flag );
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
/*--
Packit Service 4d3269
  All the garbage from here to main() is purely to
Packit Service 4d3269
  implement a linked list of command-line arguments,
Packit Service 4d3269
  into which main() copies argv[1 .. argc-1].
Packit Service 4d3269
Packit Service 4d3269
  The purpose of this exercise is to facilitate 
Packit Service 4d3269
  the expansion of wildcard characters * and ? in 
Packit Service 4d3269
  filenames for OSs which don't know how to do it
Packit Service 4d3269
  themselves, like MSDOS, Windows 95 and NT.
Packit Service 4d3269
Packit Service 4d3269
  The actual Dirty Work is done by the platform-
Packit Service 4d3269
  specific macro APPEND_FILESPEC.
Packit Service 4d3269
--*/
Packit Service 4d3269
Packit Service 4d3269
typedef
Packit Service 4d3269
   struct zzzz {
Packit Service 4d3269
      Char        *name;
Packit Service 4d3269
      struct zzzz *link;
Packit Service 4d3269
   }
Packit Service 4d3269
   Cell;
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
static 
Packit Service 4d3269
void *myMalloc ( Int32 n )
Packit Service 4d3269
{
Packit Service 4d3269
   void* p;
Packit Service 4d3269
Packit Service 4d3269
   p = malloc ( (size_t)n );
Packit Service 4d3269
   if (p == NULL) outOfMemory ();
Packit Service 4d3269
   return p;
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
static 
Packit Service 4d3269
Cell *mkCell ( void )
Packit Service 4d3269
{
Packit Service 4d3269
   Cell *c;
Packit Service 4d3269
Packit Service 4d3269
   c = (Cell*) myMalloc ( sizeof ( Cell ) );
Packit Service 4d3269
   c->name = NULL;
Packit Service 4d3269
   c->link = NULL;
Packit Service 4d3269
   return c;
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
static 
Packit Service 4d3269
Cell *snocString ( Cell *root, Char *name )
Packit Service 4d3269
{
Packit Service 4d3269
   if (root == NULL) {
Packit Service 4d3269
      Cell *tmp = mkCell();
Packit Service 4d3269
      tmp->name = (Char*) myMalloc ( 5 + strlen(name) );
Packit Service 4d3269
      strcpy ( tmp->name, name );
Packit Service 4d3269
      return tmp;
Packit Service 4d3269
   } else {
Packit Service 4d3269
      Cell *tmp = root;
Packit Service 4d3269
      while (tmp->link != NULL) tmp = tmp->link;
Packit Service 4d3269
      tmp->link = snocString ( tmp->link, name );
Packit Service 4d3269
      return root;
Packit Service 4d3269
   }
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
static 
Packit Service 4d3269
void addFlagsFromEnvVar ( Cell** argList, Char* varName ) 
Packit Service 4d3269
{
Packit Service 4d3269
   Int32 i, j, k;
Packit Service 4d3269
   Char *envbase, *p;
Packit Service 4d3269
Packit Service 4d3269
   envbase = getenv(varName);
Packit Service 4d3269
   if (envbase != NULL) {
Packit Service 4d3269
      p = envbase;
Packit Service 4d3269
      i = 0;
Packit Service 4d3269
      while (True) {
Packit Service 4d3269
         if (p[i] == 0) break;
Packit Service 4d3269
         p += i;
Packit Service 4d3269
         i = 0;
Packit Service 4d3269
         while (isspace((Int32)(p[0]))) p++;
Packit Service 4d3269
         while (p[i] != 0 && !isspace((Int32)(p[i]))) i++;
Packit Service 4d3269
         if (i > 0) {
Packit Service 4d3269
            k = i; if (k > FILE_NAME_LEN-10) k = FILE_NAME_LEN-10;
Packit Service 4d3269
            for (j = 0; j < k; j++) tmpName[j] = p[j];
Packit Service 4d3269
            tmpName[k] = 0;
Packit Service 4d3269
            APPEND_FLAG(*argList, tmpName);
Packit Service 4d3269
         }
Packit Service 4d3269
      }
Packit Service 4d3269
   }
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*---------------------------------------------*/
Packit Service 4d3269
#define ISFLAG(s) (strcmp(aa->name, (s))==0)
Packit Service 4d3269
Packit Service 4d3269
IntNative main ( IntNative argc, Char *argv[] )
Packit Service 4d3269
{
Packit Service 4d3269
   Int32  i, j;
Packit Service 4d3269
   Char   *tmp;
Packit Service 4d3269
   Cell   *argList;
Packit Service 4d3269
   Cell   *aa;
Packit Service 4d3269
   Bool   decode;
Packit Service 4d3269
Packit Service 4d3269
   /*-- Be really really really paranoid :-) --*/
Packit Service 4d3269
   if (sizeof(Int32) != 4 || sizeof(UInt32) != 4  ||
Packit Service 4d3269
       sizeof(Int16) != 2 || sizeof(UInt16) != 2  ||
Packit Service 4d3269
       sizeof(Char)  != 1 || sizeof(UChar)  != 1)
Packit Service 4d3269
      configError();
Packit Service 4d3269
Packit Service 4d3269
   /*-- Initialise --*/
Packit Service 4d3269
   outputHandleJustInCase  = NULL;
Packit Service 4d3269
   smallMode               = False;
Packit Service 4d3269
   keepInputFiles          = False;
Packit Service 4d3269
   forceOverwrite          = False;
Packit Service 4d3269
   noisy                   = True;
Packit Service 4d3269
   verbosity               = 0;
Packit Service 4d3269
   blockSize100k           = 9;
Packit Service 4d3269
   testFailsExist          = False;
Packit Service 4d3269
   unzFailsExist           = False;
Packit Service 4d3269
   numFileNames            = 0;
Packit Service 4d3269
   numFilesProcessed       = 0;
Packit Service 4d3269
   workFactor              = 30;
Packit Service 4d3269
   deleteOutputOnInterrupt = False;
Packit Service 4d3269
   exitValue               = 0;
Packit Service 4d3269
   i = j = 0; /* avoid bogus warning from egcs-1.1.X */
Packit Service 4d3269
Packit Service 4d3269
   /*-- Set up signal handlers for mem access errors --*/
Packit Service 4d3269
   signal (SIGSEGV, mySIGSEGVorSIGBUScatcher);
Packit Service 4d3269
#  if BZ_UNIX
Packit Service 4d3269
#  ifndef __DJGPP__
Packit Service 4d3269
   signal (SIGBUS,  mySIGSEGVorSIGBUScatcher);
Packit Service 4d3269
#  endif
Packit Service 4d3269
#  endif
Packit Service 4d3269
Packit Service 4d3269
   copyFileName ( inName,  (Char*)"(none)" );
Packit Service 4d3269
   copyFileName ( outName, (Char*)"(none)" );
Packit Service 4d3269
Packit Service 4d3269
   copyFileName ( progNameReally, argv[0] );
Packit Service 4d3269
   progName = &progNameReally[0];
Packit Service 4d3269
   for (tmp = &progNameReally[0]; *tmp != '\0'; tmp++)
Packit Service 4d3269
      if (*tmp == PATH_SEP) progName = tmp + 1;
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
   /*-- Copy flags from env var BZIP2, and 
Packit Service 4d3269
        expand filename wildcards in arg list.
Packit Service 4d3269
   --*/
Packit Service 4d3269
   argList = NULL;
Packit Service 4d3269
   addFlagsFromEnvVar ( &argList,  (Char*)"BZIP2" );
Packit Service 4d3269
   addFlagsFromEnvVar ( &argList,  (Char*)"BZIP" );
Packit Service 4d3269
   for (i = 1; i <= argc-1; i++)
Packit Service 4d3269
      APPEND_FILESPEC(argList, argv[i]);
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
   /*-- Find the length of the longest filename --*/
Packit Service 4d3269
   longestFileName = 7;
Packit Service 4d3269
   numFileNames    = 0;
Packit Service 4d3269
   decode          = True;
Packit Service 4d3269
   for (aa = argList; aa != NULL; aa = aa->link) {
Packit Service 4d3269
      if (ISFLAG("--")) { decode = False; continue; }
Packit Service 4d3269
      if (aa->name[0] == '-' && decode) continue;
Packit Service 4d3269
      numFileNames++;
Packit Service 4d3269
      if (longestFileName < (Int32)strlen(aa->name) )
Packit Service 4d3269
         longestFileName = (Int32)strlen(aa->name);
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
   /*-- Determine source modes; flag handling may change this too. --*/
Packit Service 4d3269
   if (numFileNames == 0)
Packit Service 4d3269
      srcMode = SM_I2O; else srcMode = SM_F2F;
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
   /*-- Determine what to do (compress/uncompress/test/cat). --*/
Packit Service 4d3269
   /*-- Note that subsequent flag handling may change this. --*/
Packit Service 4d3269
   opMode = OM_Z;
Packit Service 4d3269
Packit Service 4d3269
   if ( (strstr ( progName, "unzip" ) != 0) ||
Packit Service 4d3269
        (strstr ( progName, "UNZIP" ) != 0) )
Packit Service 4d3269
      opMode = OM_UNZ;
Packit Service 4d3269
Packit Service 4d3269
   if ( (strstr ( progName, "z2cat" ) != 0) ||
Packit Service 4d3269
        (strstr ( progName, "Z2CAT" ) != 0) ||
Packit Service 4d3269
        (strstr ( progName, "zcat" ) != 0)  ||
Packit Service 4d3269
        (strstr ( progName, "ZCAT" ) != 0) )  {
Packit Service 4d3269
      opMode = OM_UNZ;
Packit Service 4d3269
      srcMode = (numFileNames == 0) ? SM_I2O : SM_F2O;
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
   /*-- Look at the flags. --*/
Packit Service 4d3269
   for (aa = argList; aa != NULL; aa = aa->link) {
Packit Service 4d3269
      if (ISFLAG("--")) break;
Packit Service 4d3269
      if (aa->name[0] == '-' && aa->name[1] != '-') {
Packit Service 4d3269
         for (j = 1; aa->name[j] != '\0'; j++) {
Packit Service 4d3269
            switch (aa->name[j]) {
Packit Service 4d3269
               case 'c': srcMode          = SM_F2O; break;
Packit Service 4d3269
               case 'd': opMode           = OM_UNZ; break;
Packit Service 4d3269
               case 'z': opMode           = OM_Z; break;
Packit Service 4d3269
               case 'f': forceOverwrite   = True; break;
Packit Service 4d3269
               case 't': opMode           = OM_TEST; break;
Packit Service 4d3269
               case 'k': keepInputFiles   = True; break;
Packit Service 4d3269
               case 's': smallMode        = True; break;
Packit Service 4d3269
               case 'q': noisy            = False; break;
Packit Service 4d3269
               case '1': blockSize100k    = 1; break;
Packit Service 4d3269
               case '2': blockSize100k    = 2; break;
Packit Service 4d3269
               case '3': blockSize100k    = 3; break;
Packit Service 4d3269
               case '4': blockSize100k    = 4; break;
Packit Service 4d3269
               case '5': blockSize100k    = 5; break;
Packit Service 4d3269
               case '6': blockSize100k    = 6; break;
Packit Service 4d3269
               case '7': blockSize100k    = 7; break;
Packit Service 4d3269
               case '8': blockSize100k    = 8; break;
Packit Service 4d3269
               case '9': blockSize100k    = 9; break;
Packit Service 4d3269
               case 'V':
Packit Service 4d3269
               case 'L': license();            break;
Packit Service 4d3269
               case 'v': verbosity++; break;
Packit Service 4d3269
               case 'h': usage ( progName );
Packit Service 4d3269
                         exit ( 0 );
Packit Service 4d3269
                         break;
Packit Service 4d3269
               default:  fprintf ( stderr, "%s: Bad flag `%s'\n",
Packit Service 4d3269
                                   progName, aa->name );
Packit Service 4d3269
                         usage ( progName );
Packit Service 4d3269
                         exit ( 1 );
Packit Service 4d3269
                         break;
Packit Service 4d3269
            }
Packit Service 4d3269
         }
Packit Service 4d3269
      }
Packit Service 4d3269
   }
Packit Service 4d3269
   
Packit Service 4d3269
   /*-- And again ... --*/
Packit Service 4d3269
   for (aa = argList; aa != NULL; aa = aa->link) {
Packit Service 4d3269
      if (ISFLAG("--")) break;
Packit Service 4d3269
      if (ISFLAG("--stdout"))            srcMode          = SM_F2O;  else
Packit Service 4d3269
      if (ISFLAG("--decompress"))        opMode           = OM_UNZ;  else
Packit Service 4d3269
      if (ISFLAG("--compress"))          opMode           = OM_Z;    else
Packit Service 4d3269
      if (ISFLAG("--force"))             forceOverwrite   = True;    else
Packit Service 4d3269
      if (ISFLAG("--test"))              opMode           = OM_TEST; else
Packit Service 4d3269
      if (ISFLAG("--keep"))              keepInputFiles   = True;    else
Packit Service 4d3269
      if (ISFLAG("--small"))             smallMode        = True;    else
Packit Service 4d3269
      if (ISFLAG("--quiet"))             noisy            = False;   else
Packit Service 4d3269
      if (ISFLAG("--version"))           license();                  else
Packit Service 4d3269
      if (ISFLAG("--license"))           license();                  else
Packit Service 4d3269
      if (ISFLAG("--exponential"))       workFactor = 1;             else 
Packit Service 4d3269
      if (ISFLAG("--repetitive-best"))   redundant(aa->name);        else
Packit Service 4d3269
      if (ISFLAG("--repetitive-fast"))   redundant(aa->name);        else
Packit Service 4d3269
      if (ISFLAG("--fast"))              blockSize100k = 1;          else
Packit Service 4d3269
      if (ISFLAG("--best"))              blockSize100k = 9;          else
Packit Service 4d3269
      if (ISFLAG("--verbose"))           verbosity++;                else
Packit Service 4d3269
      if (ISFLAG("--help"))              { usage ( progName ); exit ( 0 ); }
Packit Service 4d3269
         else
Packit Service 4d3269
         if (strncmp ( aa->name, "--", 2) == 0) {
Packit Service 4d3269
            fprintf ( stderr, "%s: Bad flag `%s'\n", progName, aa->name );
Packit Service 4d3269
            usage ( progName );
Packit Service 4d3269
            exit ( 1 );
Packit Service 4d3269
         }
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
   if (verbosity > 4) verbosity = 4;
Packit Service 4d3269
   if (opMode == OM_Z && smallMode && blockSize100k > 2) 
Packit Service 4d3269
      blockSize100k = 2;
Packit Service 4d3269
Packit Service 4d3269
   if (opMode == OM_TEST && srcMode == SM_F2O) {
Packit Service 4d3269
      fprintf ( stderr, "%s: -c and -t cannot be used together.\n",
Packit Service 4d3269
                progName );
Packit Service 4d3269
      exit ( 1 );
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
   if (srcMode == SM_F2O && numFileNames == 0)
Packit Service 4d3269
      srcMode = SM_I2O;
Packit Service 4d3269
Packit Service 4d3269
   if (opMode != OM_Z) blockSize100k = 0;
Packit Service 4d3269
Packit Service 4d3269
   if (srcMode == SM_F2F) {
Packit Service 4d3269
      signal (SIGINT,  mySignalCatcher);
Packit Service 4d3269
      signal (SIGTERM, mySignalCatcher);
Packit Service 4d3269
#     if BZ_UNIX
Packit Service 4d3269
      signal (SIGHUP,  mySignalCatcher);
Packit Service 4d3269
#     endif
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
   if (opMode == OM_Z) {
Packit Service 4d3269
     if (srcMode == SM_I2O) {
Packit Service 4d3269
        compress ( NULL );
Packit Service 4d3269
     } else {
Packit Service 4d3269
        decode = True;
Packit Service 4d3269
        for (aa = argList; aa != NULL; aa = aa->link) {
Packit Service 4d3269
           if (ISFLAG("--")) { decode = False; continue; }
Packit Service 4d3269
           if (aa->name[0] == '-' && decode) continue;
Packit Service 4d3269
           numFilesProcessed++;
Packit Service 4d3269
           compress ( aa->name );
Packit Service 4d3269
        }
Packit Service 4d3269
     }
Packit Service 4d3269
   } 
Packit Service 4d3269
   else
Packit Service 4d3269
Packit Service 4d3269
   if (opMode == OM_UNZ) {
Packit Service 4d3269
      unzFailsExist = False;
Packit Service 4d3269
      if (srcMode == SM_I2O) {
Packit Service 4d3269
         uncompress ( NULL );
Packit Service 4d3269
      } else {
Packit Service 4d3269
         decode = True;
Packit Service 4d3269
         for (aa = argList; aa != NULL; aa = aa->link) {
Packit Service 4d3269
            if (ISFLAG("--")) { decode = False; continue; }
Packit Service 4d3269
            if (aa->name[0] == '-' && decode) continue;
Packit Service 4d3269
            numFilesProcessed++;
Packit Service 4d3269
            uncompress ( aa->name );
Packit Service 4d3269
         }      
Packit Service 4d3269
      }
Packit Service 4d3269
      if (unzFailsExist) { 
Packit Service 4d3269
         setExit(2); 
Packit Service 4d3269
         exit(exitValue);
Packit Service 4d3269
      }
Packit Service 4d3269
   } 
Packit Service 4d3269
Packit Service 4d3269
   else {
Packit Service 4d3269
      testFailsExist = False;
Packit Service 4d3269
      if (srcMode == SM_I2O) {
Packit Service 4d3269
         testf ( NULL );
Packit Service 4d3269
      } else {
Packit Service 4d3269
         decode = True;
Packit Service 4d3269
         for (aa = argList; aa != NULL; aa = aa->link) {
Packit Service 4d3269
	    if (ISFLAG("--")) { decode = False; continue; }
Packit Service 4d3269
            if (aa->name[0] == '-' && decode) continue;
Packit Service 4d3269
            numFilesProcessed++;
Packit Service 4d3269
            testf ( aa->name );
Packit Service 4d3269
	 }
Packit Service 4d3269
      }
Packit Service 4d3269
      if (testFailsExist && noisy) {
Packit Service 4d3269
         fprintf ( stderr,
Packit Service 4d3269
           "\n"
Packit Service 4d3269
           "You can use the `bzip2recover' program to attempt to recover\n"
Packit Service 4d3269
           "data from undamaged sections of corrupted files.\n\n"
Packit Service 4d3269
         );
Packit Service 4d3269
         setExit(2);
Packit Service 4d3269
         exit(exitValue);
Packit Service 4d3269
      }
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
   /* Free the argument list memory to mollify leak detectors 
Packit Service 4d3269
      (eg) Purify, Checker.  Serves no other useful purpose.
Packit Service 4d3269
   */
Packit Service 4d3269
   aa = argList;
Packit Service 4d3269
   while (aa != NULL) {
Packit Service 4d3269
      Cell* aa2 = aa->link;
Packit Service 4d3269
      if (aa->name != NULL) free(aa->name);
Packit Service 4d3269
      free(aa);
Packit Service 4d3269
      aa = aa2;
Packit Service 4d3269
   }
Packit Service 4d3269
Packit Service 4d3269
   return exitValue;
Packit Service 4d3269
}
Packit Service 4d3269
Packit Service 4d3269
Packit Service 4d3269
/*-----------------------------------------------------------*/
Packit Service 4d3269
/*--- end                                         bzip2.c ---*/
Packit Service 4d3269
/*-----------------------------------------------------------*/