diff -acrpNC5 bzp2-100.gnu/bzip2.1 bzp2-100.djg/bzip2.1
*** bzp2-100.gnu/bzip2.1	Thu Mar 23 23:13:08 2000
--- bzp2-100.djg/bzip2.1	Thu May 18 09:00:28 2000
*************** bzcat \- decompresses files to stdout
*** 8,25 ****
  bzip2recover \- recovers data from damaged bzip2 files
  
  .SH SYNOPSIS
  .ll +8
  .B bzip2
! .RB [ " \-cdfkqstvzVL123456789 " ]
  [
  .I "filenames \&..."
  ]
  .ll -8
  .br
  .B bunzip2
! .RB [ " \-fkvsVL " ]
  [ 
  .I "filenames \&..."
  ]
  .br
  .B bzcat
--- 8,25 ----
  bzip2recover \- recovers data from damaged bzip2 files
  
  .SH SYNOPSIS
  .ll +8
  .B bzip2
! .RB [ " \-cdfknqstvzVL123456789 " ]
  [
  .I "filenames \&..."
  ]
  .ll -8
  .br
  .B bunzip2
! .RB [ " \-fknvsVL " ]
  [ 
  .I "filenames \&..."
  ]
  .br
  .B bzcat
*************** complains that it cannot
*** 100,109 ****
--- 100,171 ----
  guess the name of the original file, and uses the original name
  with
  .I .out
  appended.
  
+ The above applies also to the MSDOS port of
+ .I bzip2
+ when LFN support is avaliable.
+ If LFN support is not available (plain DOS and WIN9X with LFN=n) the file name
+ and the extension will not be properly preserved at the same time.
+ This port offers the user the choice between two rules to create the name of the
+ compressed file. The first rule (default) will preserve the extension at the cost
+ of truncating the file name. The second rule will preserve the file name and truncate
+ the extension. The different rules are selected by omitting or setting the
+ .I \-n
+ flag.
+ 
+ Rule 1: file name truncating and extension preserving.
+ This is the default rule. If the
+ .I \-n
+ flag is omitted then this rule will be used.
+ This guarantees compatibility with other MSDOS ports of
+ .I bzip2
+ .
+ With this rule the following types of file names will be created:
+ 
+ When compressing:
+        filename       becomes   filename.bz2
+        filename.e     becomes   filena_e.bz2
+        filename.ex    becomes   filen_ex.bz2
+        filename.ext   becomes   file_ext.bz2
+        filename.tar   becomes   filename.tbz
+ 
+ When decompressing:
+        filename.bz2   becomes   filename
+        filena_e.bz2   becomes   filena.e
+        filen_ex.bz2   becomes   filen.ex
+        file_ext.bz2   becomes   file.ext
+        filename.tbz   becomes   filename.tar
+        anyothername   becomes   anyothername.out
+ 
+ Rule 2: file name preserving and extension truncating.
+ This rule must be explicity enabled by setting the
+ .I \-n
+ flag.
+ With this rule the following types of file names will be created:
+ 
+ When compressing:
+        filename       becomes   filename.bz2
+        filename.e     becomes   filename.eb
+        filename.ex    becomes   filename.exb
+        filename.ext   becomes   filename.exb
+        filename.tar   becomes   filename.tbz
+ 
+ When decompressing:
+        filename.bz2   becomes   filename
+        filename.b     becomes   filename
+        filename.eb    becomes   filename.e
+        filename.exb   becomes   filename.ex
+        filename.tbz   becomes   filename.tar
+        anyothername   becomes   anyothername.out
+ 
+ The same rule must be used for compression and decompression.
+ The
+ .I \-n
+ flag is ignored on WIN9X with LFN=y.
+ 
  As with compression, supplying no
  filenames causes decompression from 
  standard input to standard output.
  
  .I bunzip2 
*************** with a dash, for example: bzip2 \-- \-my
*** 251,260 ****
--- 313,338 ----
  .B \--repetitive-fast --repetitive-best
  These flags are redundant in versions 0.9.5 and above.  They provided
  some coarse control over the behaviour of the sorting algorithm in
  earlier versions, which was sometimes useful.  0.9.5 and above have an
  improved algorithm which renders these flags irrelevant.
+ .TP
+ .B \-n
+ This flag is only available on plain DOS and WIN9X with LFN=n
+ and is ignored on WIN9X with LFN=y.
+ This flag selects one of two rules to create the name of the compressed
+ file. If this flag is omitted then rule 1 will be used. Rule 1 stores
+ the extension truncating the original file name.
+ If the flag is set then rule 2 will be used. Rule 2 preserves the original
+ file name and truncates the extension. If the extension has the length of
+ one or two characters a
+ .I b
+ character will be added to the extension
+ else the third character of the extension will be overwritten with a
+ .I b
+ character.
+ The same rule must be used for compression and decompression.
  
  .SH MEMORY MANAGEMENT
  .I bzip2 
  compresses large files in blocks.  The block size affects
  both the compression ratio achieved, and the amount of memory needed for
*************** futile to use it on damaged single-block
*** 366,375 ****
--- 444,461 ----
  damaged  block  cannot  be recovered.  If you wish to minimise 
  any potential data loss through media  or  transmission errors, 
  you might consider compressing with a smaller
  block size.
  
+ For the MSDOS port of
+ .I bzip2recover
+ the following applies:
+ If LFN support is available the output file names will be of the same form
+ as above described. If LFN support is not available then "rec0001file" will
+ become "r0001file", etc. If the file has no extension then an ".bz2" extension
+ will be added, else the original extension will be retained.
+ 
  .SH PERFORMANCE NOTES
  The sorting phase of compression gathers together similar strings in the
  file.  Because of this, files containing very long runs of repeated
  symbols, like "aabaabaabaab ..."  (repeated several hundred times) may
  compress more slowly than normal.  Versions 0.9.5 and above fare much
diff -acrpNC5 bzp2-100.gnu/bzip2.c bzp2-100.djg/bzip2.c
*** bzp2-100.gnu/bzip2.c	Tue Apr 25 21:34:06 2000
--- bzp2-100.djg/bzip2.c	Thu May 18 09:00:28 2000
***************
*** 160,173 ****
  #   include <utime.h>
  #   include <unistd.h>
  #   include <sys/stat.h>
  #   include <sys/times.h>
  
! #   define PATH_SEP    '/'
! #   define MY_LSTAT    lstat
! #   define MY_S_IFREG  S_ISREG
! #   define MY_STAT     stat
  
  #   define APPEND_FILESPEC(root, name) \
        root=snocString((root), (name))
  
  #   define APPEND_FLAG(root, name) \
--- 160,175 ----
  #   include <utime.h>
  #   include <unistd.h>
  #   include <sys/stat.h>
  #   include <sys/times.h>
  
! #   define IS_PATH_SEP(filename) ((filename) == '/')
! #   define MY_LSTAT              lstat
! #   define MY_S_IFREG            S_ISREG
! #   define MY_STAT               stat
! 
! #   define OUTPUT_HANDLE         stderr
  
  #   define APPEND_FILESPEC(root, name) \
        root=snocString((root), (name))
  
  #   define APPEND_FLAG(root, name) \
***************
*** 179,199 ****
  #      define NORETURN __attribute__ ((noreturn))
  #   else
  #      define NORETURN /**/
  #   endif
  #   ifdef __DJGPP__
  #     include <io.h>
  #     include <fcntl.h>
! #     undef MY_LSTAT
! #     define MY_LSTAT stat
! #     undef SET_BINARY_MODE
! #     define SET_BINARY_MODE(fd)                        \
          do {                                            \
!            int retVal = setmode ( fileno ( fd ),        \
!                                  O_BINARY );            \
!            ERROR_IF_MINUS_ONE ( retVal );               \
          } while ( 0 )
  #   endif
  #   ifdef __CYGWIN__
  #     include <io.h>
  #     include <fcntl.h>
  #     undef SET_BINARY_MODE
--- 181,216 ----
  #      define NORETURN __attribute__ ((noreturn))
  #   else
  #      define NORETURN /**/
  #   endif
  #   ifdef __DJGPP__
+ #     define BZ_MSDOS
  #     include <io.h>
  #     include <fcntl.h>
! #     undef  IS_PATH_SEP(filename)
! #     define IS_PATH_SEP(filename)      ((filename) == '/' || (filename) == '\\' || (filename) == ':')
! #     define IS_EXTENSION(filename)     (strchr ((filename), '.') != NULL)
! #     define IS_TAR_EXTENSION(filename) (strstr ((filename), ".tar") != NULL)
! #     define NO_LFN_SUPPORT(filename)   (pathconf ((filename), _PC_NAME_MAX) <= 12)
! #     ifndef S_ISLNK
! #       undef  MY_LSTAT
! #       define MY_LSTAT     stat
! #     endif
! #     undef  OUTPUT_HANDLE
! #     define OUTPUT_HANDLE  stdout
! #     if (defined(O_BINARY) != 0)
! #       undef  SET_BINARY_MODE
! #       define SET_BINARY_MODE(fd)                      \
          do {                                            \
!            if ( !isatty ( fileno ( fd ) ) )             \
!            {                                            \
!              int retVal = setmode ( fileno ( fd ),      \
!                                    O_BINARY );          \
!              ERROR_IF_MINUS_ONE ( retVal );             \
!            }                                            \
          } while ( 0 )
+ #     endif
  #   endif
  #   ifdef __CYGWIN__
  #     include <io.h>
  #     include <fcntl.h>
  #     undef SET_BINARY_MODE
***************
*** 212,225 ****
  #   include <io.h>
  #   include <fcntl.h>
  #   include <sys\stat.h>
  
  #   define NORETURN       /**/
! #   define PATH_SEP       '\\'
! #   define MY_LSTAT       _stat
! #   define MY_STAT        _stat
! #   define MY_S_IFREG(x)  ((x) & _S_IFREG)
  
  #   define APPEND_FLAG(root, name) \
        root=snocString((root), (name))
  
  #   if 0
--- 229,244 ----
  #   include <io.h>
  #   include <fcntl.h>
  #   include <sys\stat.h>
  
  #   define NORETURN       /**/
! #   define IS_PATH_SEP(filename) ((filename) == '\\')
! #   define MY_LSTAT              _stat
! #   define MY_STAT               _stat
! #   define MY_S_IFREG(x)         ((x) & _S_IFREG)
! 
! #   define OUTPUT_HANDLE  stderr
  
  #   define APPEND_FLAG(root, name) \
        root=snocString((root), (name))
  
  #   if 0
*************** Char    outName[FILE_NAME_LEN];
*** 313,322 ****
--- 332,344 ----
  Char    tmpName[FILE_NAME_LEN];
  Char    *progName;
  Char    progNameReally[FILE_NAME_LEN];
  FILE    *outputHandleJustInCase;
  Int32   workFactor;
+ #ifdef BZ_MSDOS
+ Bool    dosFileNameRule2;
+ #endif
  
  static void    panic                 ( Char* )   NORETURN;
  static void    ioError               ( void )    NORETURN;
  static void    outOfMemory           ( void )    NORETURN;
  static void    configError           ( void )    NORETURN;
*************** void copyDatePermissionsAndOwner ( Char 
*** 1126,1136 ****
--- 1148,1162 ----
     retVal = MY_LSTAT ( srcName, &statBuf );
     ERROR_IF_NOT_ZERO ( retVal );
     uTimBuf.actime = statBuf.st_atime;
     uTimBuf.modtime = statBuf.st_mtime;
  
+ #ifdef BZ_MSDOS
+    retVal = _chmod ( dstName, 1, _chmod ( srcName, 0, 0 ) & 0xffe7 ) == -1;
+ #else
     retVal = chmod ( dstName, statBuf.st_mode );
+ #endif
     ERROR_IF_NOT_ZERO ( retVal );
  
     retVal = utime ( dstName, &uTimBuf );
     ERROR_IF_NOT_ZERO ( retVal );
  
*************** void copyDatePermissionsAndOwner ( Char 
*** 1144,1154 ****
  
  /*---------------------------------------------*/
  static 
  void setInterimPermissions ( Char *dstName )
  {
! #if BZ_UNIX
     IntNative      retVal;
     retVal = chmod ( dstName, S_IRUSR | S_IWUSR );
     ERROR_IF_NOT_ZERO ( retVal );
  #endif
  }
--- 1170,1180 ----
  
  /*---------------------------------------------*/
  static 
  void setInterimPermissions ( Char *dstName )
  {
! #if defined(BZ_UNIX) && !defined(BZ_MSDOS)
     IntNative      retVal;
     retVal = chmod ( dstName, S_IRUSR | S_IWUSR );
     ERROR_IF_NOT_ZERO ( retVal );
  #endif
  }
*************** void compress ( Char *name )
*** 1213,1223 ****
           copyFileName ( outName, "(stdout)" ); 
           break;
        case SM_F2F: 
           copyFileName ( inName, name );
           copyFileName ( outName, name );
!          strcat ( outName, ".bz2" ); 
           break;
        case SM_F2O: 
           copyFileName ( inName, name );
           copyFileName ( outName, "(stdout)" ); 
           break;
--- 1239,1291 ----
           copyFileName ( outName, "(stdout)" ); 
           break;
        case SM_F2F: 
           copyFileName ( inName, name );
           copyFileName ( outName, name );
!          if (NO_LFN_SUPPORT ( outName ))  /* MSDOS 8.3 filename restriction. */
!          {
!            Char* fileName = basename ( outName );
!            if (IS_EXTENSION ( fileName ))
!            {
!              register IntNative extStart = (IntNative)( strchr ( fileName, '.' ) - fileName );
!              if (IS_TAR_EXTENSION ( fileName ))
!                strcpy ( &fileName[extStart], ".tbz" );
!              else /* File has extension but not tar extension. */
!              {
!                register IntNative extLen = strlen ( &fileName[extStart] );
!                if (dosFileNameRule2 == False)
!                {
!                  /*----------------------------------------------*/
!                  /*---   Output file name rule 1 (default):   ---*/
!                  /*---   filename.ext -> file_ext.bz2         ---*/
!                  /*----------------------------------------------*/
! 
!                  IntNative fileNameLen = extStart;
!                  fileName[extStart] = '_';
!                  if (fileNameLen + extLen > 8)
!                    strcpy ( &fileName[8 - extLen], &fileName[extStart] );
!                  strcat ( fileName, ".bz2" );
!                }
!                else
!                {
!                  /*-------------------------------------------------------------*/
!                  /*---   Output file name rule 2 (selected with flag: -n):   ---*/
!                  /*---   filename.ext -> filename.exb                        ---*/
!                  /*-------------------------------------------------------------*/
! 
!                  if (extLen <= 2)             /* one or two character extension. */
!                    strcat ( fileName, "b" );
!                  else                         /* three character extension. */
!                    fileName[extStart + 3] = 'b';
!                }
!              }
!            }
!            else                             /* no extension at all. */
!              strcat ( fileName, ".bz2" );
!          }
!          else                               /* no filename restriction. */
!            strcat ( outName, ".bz2" );
           break;
        case SM_F2O: 
           copyFileName ( inName, name );
           copyFileName ( outName, "(stdout)" ); 
           break;
*************** void uncompress ( Char *name )
*** 1378,1389 ****
           break;
        case SM_F2F: 
           copyFileName ( inName, name );
           copyFileName ( outName, name );
           for (i = 0; i < BZ_N_SUFFIX_PAIRS; i++)
!             if (mapSuffix(outName,zSuffix[i],unzSuffix[i]))
!                goto zzz; 
           cantGuess = True;
           strcat ( outName, ".out" );
           break;
        case SM_F2O: 
           copyFileName ( inName, name );
--- 1446,1503 ----
           break;
        case SM_F2F: 
           copyFileName ( inName, name );
           copyFileName ( outName, name );
           for (i = 0; i < BZ_N_SUFFIX_PAIRS; i++)
!          {
!            if (mapSuffix ( outName,zSuffix[i], unzSuffix[i] )) /* Test for extensions: .bz2, .tbz2, .bz, .tbz */
!            {
!              if (NO_LFN_SUPPORT ( outName ))  /* MSDOS 8.3 filename restriction */
!              {
!                if (dosFileNameRule2 == False)
!                {
!                  /*----------------------------------------------*/
!                  /*---   Output file name rule 1 (default):   ---*/
!                  /*---   file_ext.bz2 -> file.ext             ---*/
!                  /*----------------------------------------------*/
! 
!                  Char* fileName = basename ( outName );
!                  if (!IS_EXTENSION ( fileName ))
!                  {
!                    Char* dot = strchr (fileName, '_');
!                    if (dot)
!                      *dot = '.';
!                  }
!                }
!              }
!              goto zzz;
!            }
!            else /* If and only if DOS or WIN9X(LFN=n) is used, test for extensions: .b, .xb, .xxb. x= any character. */
!            {
!              if (NO_LFN_SUPPORT ( outName ))  /* MSDOS 8.3 filename restriction */
!              {
!                if (dosFileNameRule2 == True)
!                {
!                  /*-------------------------------------------------------------*/
!                  /*---   Output file name rule 2 (selected with flag: -n):   ---*/
!                  /*---   filename.exb -> filename.ex                         ---*/
!                  /*-------------------------------------------------------------*/
! 
!                  Char* fileName = basename ( outName );
!                  if (IS_EXTENSION ( fileName ))
!                  {
!                    IntNative extEnd = strlen ( fileName );
!                    if (fileName[--extEnd] == 'b')
!                    {
!                      fileName[extEnd] = '\0';
!                      goto zzz;
!                    }
!                  }
!                }
!              }
!            }
!          }
           cantGuess = True;
           strcat ( outName, ".out" );
           break;
        case SM_F2O: 
           copyFileName ( inName, name );
*************** void testf ( Char *name )
*** 1612,1622 ****
  
  /*---------------------------------------------*/
  static 
  void license ( void )
  {
!    fprintf ( stderr,
  
      "bzip2, a block-sorting file compressor.  "
      "Version %s.\n"
      "   \n"
      "   Copyright (C) 1996-2000 by Julian Seward.\n"
--- 1726,1736 ----
  
  /*---------------------------------------------*/
  static 
  void license ( void )
  {
!    fprintf ( OUTPUT_HANDLE,
  
      "bzip2, a block-sorting file compressor.  "
      "Version %s.\n"
      "   \n"
      "   Copyright (C) 1996-2000 by Julian Seward.\n"
*************** void license ( void )
*** 1638,1648 ****
  /*---------------------------------------------*/
  static 
  void usage ( Char *fullProgName )
  {
     fprintf (
!       stderr,
        "bzip2, a block-sorting file compressor.  "
        "Version %s.\n"
        "\n   usage: %s [flags and input files in any order]\n"
        "\n"
        "   -h --help           print this message\n"
--- 1752,1762 ----
  /*---------------------------------------------*/
  static 
  void usage ( Char *fullProgName )
  {
     fprintf (
!       OUTPUT_HANDLE,
        "bzip2, a block-sorting file compressor.  "
        "Version %s.\n"
        "\n   usage: %s [flags and input files in any order]\n"
        "\n"
        "   -h --help           print this message\n"
*************** void usage ( Char *fullProgName )
*** 1656,1665 ****
--- 1770,1787 ----
        "   -v --verbose        be verbose (a 2nd -v gives more)\n"
        "   -L --license        display software version & license\n"
        "   -V --version        display software version & license\n"
        "   -s --small          use less memory (at most 2500k)\n"
        "   -1 .. -9            set block size to 100k .. 900k\n"
+ #ifdef BZ_MSDOS
+       "   -n                  select output file name rule 2.\n"
+       "                       rule 2: filename preserved, extension truncated.\n"
+       "                       default is output file name rule 1.\n"
+       "                       rule 1: filename truncated, extension preserved.\n"
+       "                       this flag is only available on plain DOS\n"
+       "                       and WIN9X with LFN=n.\n"
+ #endif
        "\n"
        "   If invoked as `bzip2', default action is to compress.\n"
        "              as `bunzip2',  default action is to decompress.\n"
        "              as `bzcat', default action is to decompress to stdout.\n"
        "\n"
*************** IntNative main ( IntNative argc, Char *a
*** 1812,1838 ****
     numFileNames            = 0;
     numFilesProcessed       = 0;
     workFactor              = 30;
     deleteOutputOnInterrupt = False;
     exitValue               = 0;
     i = j = 0; /* avoid bogus warning from egcs-1.1.X */
  
     /*-- Set up signal handlers for mem access errors --*/
     signal (SIGSEGV, mySIGSEGVorSIGBUScatcher);
  #if BZ_UNIX
! #ifndef __DJGPP__
     signal (SIGBUS,  mySIGSEGVorSIGBUScatcher);
  #endif
  #endif
  
     copyFileName ( inName,  "(none)" );
     copyFileName ( outName, "(none)" );
  
     copyFileName ( progNameReally, argv[0] );
     progName = &progNameReally[0];
     for (tmp = &progNameReally[0]; *tmp != '\0'; tmp++)
!       if (*tmp == PATH_SEP) progName = tmp + 1;
  
  
     /*-- Copy flags from env var BZIP2, and 
          expand filename wildcards in arg list.
     --*/
--- 1934,1963 ----
     numFileNames            = 0;
     numFilesProcessed       = 0;
     workFactor              = 30;
     deleteOutputOnInterrupt = False;
     exitValue               = 0;
+ #ifdef BZ_MSDOS
+    dosFileNameRule2        = False; /* On MSDOS default to output file name rule 1. */
+ #endif
     i = j = 0; /* avoid bogus warning from egcs-1.1.X */
  
     /*-- Set up signal handlers for mem access errors --*/
     signal (SIGSEGV, mySIGSEGVorSIGBUScatcher);
  #if BZ_UNIX
! #ifdef SIGBUS
     signal (SIGBUS,  mySIGSEGVorSIGBUScatcher);
  #endif
  #endif
  
     copyFileName ( inName,  "(none)" );
     copyFileName ( outName, "(none)" );
  
     copyFileName ( progNameReally, argv[0] );
     progName = &progNameReally[0];
     for (tmp = &progNameReally[0]; *tmp != '\0'; tmp++)
!       if (IS_PATH_SEP ( *tmp )) progName = tmp + 1;
  
  
     /*-- Copy flags from env var BZIP2, and 
          expand filename wildcards in arg list.
     --*/
*************** IntNative main ( IntNative argc, Char *a
*** 1899,1908 ****
--- 2024,2036 ----
                 case '5': blockSize100k    = 5; break;
                 case '6': blockSize100k    = 6; break;
                 case '7': blockSize100k    = 7; break;
                 case '8': blockSize100k    = 8; break;
                 case '9': blockSize100k    = 9; break;
+ #ifdef BZ_MSDOS
+                case 'n': dosFileNameRule2 = True; break;
+ #endif
                 case 'V':
                 case 'L': license();            break;
                 case 'v': verbosity++; break;
                 case 'h': usage ( progName );
                           exit ( 0 );
diff -acrpNC5 bzp2-100.gnu/bzip2recover.c bzp2-100.djg/bzip2recover.c
*** bzp2-100.gnu/bzip2recover.c	Wed Apr  5 23:24:40 2000
--- bzp2-100.djg/bzip2recover.c	Thu May 18 09:00:28 2000
***************
*** 54,63 ****
--- 54,66 ----
  
  #include <stdio.h>
  #include <errno.h>
  #include <stdlib.h>
  #include <string.h>
+ #ifdef __DJGPP__
+ #include <unistd.h>
+ #endif
  
  typedef  unsigned int   UInt32;
  typedef  int            Int32;
  typedef  unsigned char  UChar;
  typedef  char           Char;
*************** Char outFileName[2000];
*** 71,80 ****
--- 74,91 ----
  Char progName[2000];
  
  UInt32 bytesOut = 0;
  UInt32 bytesIn  = 0;
  
+ #define IS_DIR_SEPARATOR(filename) ((filename) == '/')
+ #ifdef __DJGPP__
+ #undef  IS_DIR_SEPARATOR(filename)
+ #define IS_DIR_SEPARATOR(filename) ((filename) == '/' || (filename) == '\\' || (filename) == ':')
+ #define NO_LFN_SUPPORT(filename)   (pathconf ((filename), _PC_NAME_MAX) <= 12)
+ #define HAS_NO_EXTENSION(filename) (strchr ((filename), '.') == NULL)
+ #endif
+ 
  
  /*---------------------------------------------------*/
  /*--- I/O errors                                  ---*/
  /*---------------------------------------------------*/
  
*************** Int32 bsGetBit ( BitStream* bs )
*** 180,190 ****
  {
     if (bs->buffLive > 0) {
        bs->buffLive --;
        return ( ((bs->buffer) >> (bs->buffLive)) & 0x1 );
     } else {
!       Int32 retVal = getc ( bs->handle );
        if ( retVal == EOF ) {
           if (errno != 0) readError();
           return 2;
        }
        bs->buffLive = 7;
--- 191,204 ----
  {
     if (bs->buffLive > 0) {
        bs->buffLive --;
        return ( ((bs->buffer) >> (bs->buffLive)) & 0x1 );
     } else {
!       Int32 retVal;
!       errno = 0; /* to avoid program abort with (ENOENT).
!                     errno=22 is set in main by fopen.     */
!       retVal = getc ( bs->handle );
        if ( retVal == EOF ) {
           if (errno != 0) readError();
           return 2;
        }
        bs->buffLive = 7;
*************** Int32 main ( Int32 argc, Char** argv )
*** 277,286 ****
--- 291,303 ----
  
  
     UInt32      buffHi, buffLo, blockCRC;
     Char*       p;
  
+    Int32       pathLen;    /* Path length in inFileName including last slash. */
+    Char*       fileName;   /* Pointer to file name in inFileName. */
+ 
     strcpy ( progName, argv[0] );
     inFileName[0] = outFileName[0] = 0;
  
     fprintf ( stderr, "bzip2recover 1.0: extracts blocks from damaged .bz2 files.\n" );
  
*************** Int32 main ( Int32 argc, Char** argv )
*** 290,299 ****
--- 307,330 ----
        exit(1);
     }
  
     strcpy ( inFileName, argv[1] );
  
+    /*--
+      Make a pointer to the file name in inFileName
+      and compute the length of the path string without
+      the file name part but including the last slash.
+    --*/
+    fileName = inFileName;
+    for (pathLen = strlen ( inFileName ) - 1; pathLen > -1; --pathLen)
+      if (IS_DIR_SEPARATOR ( inFileName[pathLen] ))
+      {
+        fileName = &inFileName[++pathLen];
+        break;
+      }
+    if (pathLen == -1) pathLen++;
+ 
     inFile = fopen ( inFileName, "rb" );
     if (inFile == NULL) {
        fprintf ( stderr, "%s: can't read `%s'\n", progName, inFileName );
        exit(1);
     }
*************** Int32 main ( Int32 argc, Char** argv )
*** 398,412 ****
           }
           if (wrBlock >= rbCtr) break;
           wrBlock++;
        } else
        if (bitsRead == rbStart[wrBlock]) {
!          outFileName[0] = 0;
!          sprintf ( outFileName, "rec%4d", wrBlock+1 );
           for (p = outFileName; *p != 0; p++) if (*p == ' ') *p = '0';
!          strcat ( outFileName, inFileName );
!          if ( !endsInBz2(outFileName)) strcat ( outFileName, ".bz2" );
  
           fprintf ( stderr, "   writing block %d to `%s' ...\n",
                             wrBlock+1, outFileName );
  
           outFile = fopen ( outFileName, "wb" );
--- 429,458 ----
           }
           if (wrBlock >= rbCtr) break;
           wrBlock++;
        } else
        if (bitsRead == rbStart[wrBlock]) {
!          if (pathLen > 0) /* Account for a possible path in inFileName. */
!            strncpy ( outFileName, inFileName, pathLen );
!          else
!            outFileName[0] = 0;
! 
!          if (NO_LFN_SUPPORT ( inFileName )) /* There are only 8 characters available. */
!            sprintf ( &outFileName[pathLen], "r%4d", wrBlock+1 );
!          else
!            sprintf ( &outFileName[pathLen], "rec%4d", wrBlock+1 );
! 
           for (p = outFileName; *p != 0; p++) if (*p == ' ') *p = '0';
!          strcat ( outFileName, fileName );
! 
!          if (NO_LFN_SUPPORT ( outFileName )) /* MSDOS 8.3 file name restriction. */
!          {
!            if (HAS_NO_EXTENSION ( fileName ))
!              strcat ( outFileName, ".bz2" );
!          }
!          else  /* Only if LFN support is available, append an extra extension. */
!            if (!endsInBz2 ( outFileName )) strcat ( outFileName, ".bz2" );
  
           fprintf ( stderr, "   writing block %d to `%s' ...\n",
                             wrBlock+1, outFileName );
  
           outFile = fopen ( outFileName, "wb" );
diff -acrpNC5 bzp2-100.gnu/Makefile bzp2-100.djg/Makefile
*** bzp2-100.gnu/Makefile	Tue May 16 21:31:04 2000
--- bzp2-100.djg/Makefile	Thu May 18 09:04:26 2000
***************
*** 1,35 ****
  
  SHELL=/bin/sh
  CC=gcc
  BIGFILES=-D_FILE_OFFSET_BITS=64
! CFLAGS=-Wall -Winline -O2 -fomit-frame-pointer -fno-strength-reduce $(BIGFILES)
  
  OBJS= blocksort.o  \
        huffman.o    \
        crctable.o   \
        randtable.o  \
        compress.o   \
        decompress.o \
        bzlib.o
  
! all: libbz2.a bzip2 bzip2recover test
  
  bzip2: libbz2.a bzip2.o
  	$(CC) $(CFLAGS) -o bzip2 bzip2.o -L. -lbz2
  
  bzip2recover: bzip2recover.o
  	$(CC) $(CFLAGS) -o bzip2recover bzip2recover.o
  
  libbz2.a: $(OBJS)
  	rm -f libbz2.a
! 	ar cq libbz2.a $(OBJS)
! 	@if ( test -f /usr/bin/ranlib -o -f /bin/ranlib -o \
! 		-f /usr/ccs/bin/ranlib ) ; then \
! 		echo ranlib libbz2.a ; \
! 		ranlib libbz2.a ; \
! 	fi
  
  test: bzip2
  	@cat words1
  	./bzip2 -1  < sample1.ref > sample1.rb2
  	./bzip2 -2  < sample2.ref > sample2.rb2
--- 1,36 ----
  
  SHELL=/bin/sh
  CC=gcc
  BIGFILES=-D_FILE_OFFSET_BITS=64
! CFLAGS=-g -Wall -Winline -O2 -fomit-frame-pointer -fno-strength-reduce $(BIGFILES)
! E=.exe
! MAKEINFO=makeinfo
! MAKEINFOFLAGS=--no-split
  
  OBJS= blocksort.o  \
        huffman.o    \
        crctable.o   \
        randtable.o  \
        compress.o   \
        decompress.o \
        bzlib.o
  
! all: bzip2.info libbz2.a bzip2 bzip2recover test
! 
! bzip2.info: manual.texi
! 	$(MAKEINFO) $(MAKEINFOFLAGS) $< -o $@
  
  bzip2: libbz2.a bzip2.o
  	$(CC) $(CFLAGS) -o bzip2 bzip2.o -L. -lbz2
  
  bzip2recover: bzip2recover.o
  	$(CC) $(CFLAGS) -o bzip2recover bzip2recover.o
  
  libbz2.a: $(OBJS)
  	rm -f libbz2.a
! 	ar cqs libbz2.a $(OBJS)
  
  test: bzip2
  	@cat words1
  	./bzip2 -1  < sample1.ref > sample1.rb2
  	./bzip2 -2  < sample2.ref > sample2.rb2
*************** test: bzip2
*** 43,77 ****
  	cmp sample1.tst sample1.ref
  	cmp sample2.tst sample2.ref
  	cmp sample3.tst sample3.ref
  	@cat words3
  
! PREFIX=/usr
  
  install: bzip2 bzip2recover
! 	if ( test ! -d $(PREFIX)/bin ) ; then mkdir $(PREFIX)/bin ; fi
! 	if ( test ! -d $(PREFIX)/lib ) ; then mkdir $(PREFIX)/lib ; fi
! 	if ( test ! -d $(PREFIX)/man ) ; then mkdir $(PREFIX)/man ; fi
! 	if ( test ! -d $(PREFIX)/man/man1 ) ; then mkdir $(PREFIX)/man/man1 ; fi
! 	if ( test ! -d $(PREFIX)/include ) ; then mkdir $(PREFIX)/include ; fi
! 	cp -f bzip2 $(PREFIX)/bin/bzip2
! 	cp -f bzip2 $(PREFIX)/bin/bunzip2
! 	cp -f bzip2 $(PREFIX)/bin/bzcat
! 	cp -f bzip2recover $(PREFIX)/bin/bzip2recover
! 	chmod a+x $(PREFIX)/bin/bzip2
! 	chmod a+x $(PREFIX)/bin/bunzip2
! 	chmod a+x $(PREFIX)/bin/bzcat
! 	chmod a+x $(PREFIX)/bin/bzip2recover
  	cp -f bzip2.1 $(PREFIX)/man/man1
  	chmod a+r $(PREFIX)/man/man1/bzip2.1
  	cp -f bzlib.h $(PREFIX)/include
  	chmod a+r $(PREFIX)/include/bzlib.h
  	cp -f libbz2.a $(PREFIX)/lib
  	chmod a+r $(PREFIX)/lib/libbz2.a
  
  clean: 
! 	rm -f *.o libbz2.a bzip2 bzip2recover \
  	sample1.rb2 sample2.rb2 sample3.rb2 \
  	sample1.tst sample2.tst sample3.tst
  
  blocksort.o: blocksort.c
  	@cat words0
--- 44,81 ----
  	cmp sample1.tst sample1.ref
  	cmp sample2.tst sample2.ref
  	cmp sample3.tst sample3.ref
  	@cat words3
  
! PREFIX=${DJDIR}
  
  install: bzip2 bzip2recover
! 	if ( test ! -d $(PREFIX)/bin ) ; then mkdir -p $(PREFIX)/bin ; fi
! 	if ( test ! -d $(PREFIX)/lib ) ; then mkdir -p $(PREFIX)/lib ; fi
! 	if ( test ! -d $(PREFIX)/info ) ; then mkdir -p $(PREFIX)/info ; fi
! 	if ( test ! -d $(PREFIX)/man ) ; then mkdir -p $(PREFIX)/man ; fi
! 	if ( test ! -d $(PREFIX)/man/man1 ) ; then mkdir -p $(PREFIX)/man/man1 ; fi
! 	if ( test ! -d $(PREFIX)/include ) ; then mkdir -p $(PREFIX)/include ; fi
! 	cp -f bzip2$E $(PREFIX)/bin/bzip2$E
! 	ln -s $(PREFIX)/bin/bzip2$E $(PREFIX)/bin/bunzip2$E
! 	ln -s $(PREFIX)/bin/bzip2$E $(PREFIX)/bin/bzcat$E
! 	cp -f bzip2recover$E $(PREFIX)/bin/bzip2recover$E
! 	chmod a+x $(PREFIX)/bin/bzip2$E
! 	chmod a+x $(PREFIX)/bin/bunzip2$E
! 	chmod a+x $(PREFIX)/bin/bzcat$E
! 	chmod a+x $(PREFIX)/bin/bzip2recover$E
  	cp -f bzip2.1 $(PREFIX)/man/man1
  	chmod a+r $(PREFIX)/man/man1/bzip2.1
  	cp -f bzlib.h $(PREFIX)/include
  	chmod a+r $(PREFIX)/include/bzlib.h
  	cp -f libbz2.a $(PREFIX)/lib
  	chmod a+r $(PREFIX)/lib/libbz2.a
+ 	cp -f bzip2.info $(PREFIX)/info/bzip2.info
+ 	install-info --info-dir=$(PREFIX)/info $(PREFIX)/info/bzip2.info
  
  clean: 
! 	rm -f *.o libbz2.a bzip2 bzip2recover *.$E\
  	sample1.rb2 sample2.rb2 sample3.rb2 \
  	sample1.tst sample2.tst sample3.tst
  
  blocksort.o: blocksort.c
  	@cat words0
diff -acrpNC5 bzp2-100.gnu/manual.texi bzp2-100.djg/manual.texi
*** bzp2-100.gnu/manual.texi	Thu Mar 23 23:43:32 2000
--- bzp2-100.djg/manual.texi	Thu May 18 09:00:28 2000
*************** above statement.
*** 99,109 ****
  
  
  
  
  
! @node Overview, Implementation, Top, Top
  @chapter Introduction
  
  @code{bzip2}  compresses  files  using the Burrows-Wheeler 
  block-sorting text compression algorithm,  and  Huffman  coding.
  Compression  is  generally  considerably  better than that
--- 99,109 ----
  
  
  
  
  
! @node Overview, , Top, (dir)
  @chapter Introduction
  
  @code{bzip2}  compresses  files  using the Burrows-Wheeler 
  block-sorting text compression algorithm,  and  Huffman  coding.
  Compression  is  generally  considerably  better than that
*************** This chapter contains a copy of the @cod
*** 130,152 ****
  and nothing else.
  
  @quotation
  
  @unnumberedsubsubsec NAME
! @itemize
  @item @code{bzip2}, @code{bunzip2}
! - a block-sorting file compressor, v1.0
  @item @code{bzcat} 
! - decompresses files to stdout
  @item @code{bzip2recover}
! - recovers data from damaged bzip2 files
  @end itemize
  
  @unnumberedsubsubsec SYNOPSIS
! @itemize
! @item @code{bzip2} [ -cdfkqstvzVL123456789 ] [ filenames ...  ]
! @item @code{bunzip2} [ -fkvsVL ] [ filenames ...  ]
  @item @code{bzcat} [ -s ] [ filenames ...  ]
  @item @code{bzip2recover} filename
  @end itemize
  
  @unnumberedsubsubsec DESCRIPTION
--- 130,152 ----
  and nothing else.
  
  @quotation
  
  @unnumberedsubsubsec NAME
! @itemize @minus
  @item @code{bzip2}, @code{bunzip2}
! a block-sorting file compressor, v1.0
  @item @code{bzcat} 
! decompresses files to stdout
  @item @code{bzip2recover}
! recovers data from damaged bzip2 files
  @end itemize
  
  @unnumberedsubsubsec SYNOPSIS
! @itemize @minus
! @item @code{bzip2} [ -cdfknqstvzVL123456789 ] [ filenames ...  ]
! @item @code{bunzip2} [ -fknvsVL ] [ filenames ...  ]
  @item @code{bzcat} [ -s ] [ filenames ...  ]
  @item @code{bzip2recover} filename
  @end itemize
  
  @unnumberedsubsubsec DESCRIPTION
*************** incomprehensible and therefore pointless
*** 181,203 ****
  @code{bunzip2} (or @code{bzip2 -d}) decompresses all
  specified files.  Files which were not created by @code{bzip2}
  will be detected and ignored, and a warning issued.  
  @code{bzip2} attempts to guess the filename for the decompressed file 
  from that of the compressed file as follows:
! @itemize
  @item @code{filename.bz2 } becomes @code{filename}
  @item @code{filename.bz  } becomes @code{filename}
  @item @code{filename.tbz2} becomes @code{filename.tar}
  @item @code{filename.tbz } becomes @code{filename.tar}
  @item @code{anyothername } becomes @code{anyothername.out}
  @end itemize
  If the file does not end in one of the recognised endings, 
  @code{.bz2}, @code{.bz}, 
  @code{.tbz2} or @code{.tbz}, @code{bzip2} complains that it cannot
  guess the name of the original file, and uses the original name
  with @code{.out} appended.
  
  As with compression, supplying no
  filenames causes decompression from standard input to standard output.
  
  @code{bunzip2} will correctly decompress a file which is the
  concatenation of two or more compressed files.  The result is the
--- 181,263 ----
  @code{bunzip2} (or @code{bzip2 -d}) decompresses all
  specified files.  Files which were not created by @code{bzip2}
  will be detected and ignored, and a warning issued.  
  @code{bzip2} attempts to guess the filename for the decompressed file 
  from that of the compressed file as follows:
! @itemize @bullet
  @item @code{filename.bz2 } becomes @code{filename}
  @item @code{filename.bz  } becomes @code{filename}
  @item @code{filename.tbz2} becomes @code{filename.tar}
  @item @code{filename.tbz } becomes @code{filename.tar}
  @item @code{anyothername } becomes @code{anyothername.out}
  @end itemize
+ 
  If the file does not end in one of the recognised endings, 
  @code{.bz2}, @code{.bz}, 
  @code{.tbz2} or @code{.tbz}, @code{bzip2} complains that it cannot
  guess the name of the original file, and uses the original name
  with @code{.out} appended.
  
+ The above applies also to the MSDOS port of @code{bzip2} when LFN support is avaliable.
+ If LFN support is not available (plain DOS and WIN9X with @code{LFN=n}) the file name
+ and the extension will not be properly preserved at the same time.
+ This port offers the user the choice between two rules to create the name of the
+ compressed file. The first rule (default) will preserve the extension at the cost
+ of truncating the file name. The second rule will preserve the file name and truncate
+ the extension. The different rules are selected by omitting or setting the @code{-n} flag.
+ 
+ Rule 1: file name truncating and extension preserving.
+ This is the default rule. If the @code{-n} flag is omitted then this rule will be used.
+ This guarantees compatibility with other MSDOS ports of @code{bzip2}.
+ With this rule the following types of file names will be created:
+ 
+ When compressing:
+ @itemize @bullet
+ @item @code{filename    } becomes @code{filename.bz2}
+ @item @code{filename.e  } becomes @code{filena_e.bz2}
+ @item @code{filename.ex } becomes @code{filen_ex.bz2}
+ @item @code{filename.ext} becomes @code{file_ext.bz2}
+ @item @code{filename.tar} becomes @code{filename.tbz}
+ @end itemize
+ 
+ When decompressing:
+ @itemize @bullet
+ @item @code{filename.bz2} becomes @code{filename}
+ @item @code{filena_e.bz2} becomes @code{filena.e}
+ @item @code{filen_ex.bz2} becomes @code{filen.ex}
+ @item @code{file_ext.bz2} becomes @code{file.ext}
+ @item @code{filename.tbz} becomes @code{filename.tar}
+ @item @code{anyothername} becomes @code{anyothername.out}
+ @end itemize
+ 
+ 
+ Rule 2: file name preserving and extension truncating.
+ This rule must be explicity enabled by setting the @code{-n} flag.
+ With this rule the following types of file names will be created:
+ 
+ When compressing:
+ @itemize @bullet
+ @item @code{filename    } becomes @code{filename.bz2}
+ @item @code{filename.e  } becomes @code{filename.eb}
+ @item @code{filename.ex } becomes @code{filename.exb}
+ @item @code{filename.ext} becomes @code{filename.exb}
+ @item @code{filename.tar} becomes @code{filename.tbz}
+ @end itemize
+ 
+ When decompressing:
+ @itemize @bullet
+ @item @code{filename.bz2} becomes @code{filename}
+ @item @code{filename.b  } becomes @code{filename}
+ @item @code{filename.eb } becomes @code{filename.e}
+ @item @code{filename.exb} becomes @code{filename.ex}
+ @item @code{filename.tbz} becomes @code{filename.tar}
+ @item @code{anyothername} becomes @code{anyothername.out}
+ @end itemize
+ 
+ The same rule must be used for compression and decompression.
+ The @code{-n} flag is ignored on WIN9X with @code{LFN=y}.
+ 
  As with compression, supplying no
  filenames causes decompression from standard input to standard output.
  
  @code{bunzip2} will correctly decompress a file which is the
  concatenation of two or more compressed files.  The result is the
*************** with a dash, for example: @code{bzip2 --
*** 297,306 ****
--- 357,378 ----
  @item --repetitive-best
  These flags are redundant in versions 0.9.5 and above.  They provided
  some coarse control over the behaviour of the sorting algorithm in
  earlier versions, which was sometimes useful.  0.9.5 and above have an
  improved algorithm which renders these flags irrelevant.
+ @item -n
+ This flag is only available on plain DOS and WIN9X with @code{LFN=n}
+ and is ignored on WIN9X with @code{LFN=y}.
+ This flag selects one of two rules to create the name of the compressed
+ file. If this flag is omitted then rule 1 will be used. Rule 1 stores
+ the extension truncating the original file name.
+ If the flag is set then rule 2 will be used. Rule 2 preserves the original
+ file name and truncates the extension. If the extension has the length of
+ one or two characters a @code{b} character will be added to the extension
+ else the third character of the extension will be overwritten with a
+ @code{b} character.
+ The same rule must be used for compression and decompression.
  @end table
  
  
  @unnumberedsubsubsec MEMORY MANAGEMENT
  
*************** and writes a number of files @code{rec00
*** 403,412 ****
--- 475,491 ----
         damaged  block  cannot  be recovered.  If you wish to minimise 
  any potential data loss through media  or  transmission errors, 
  you might consider compressing with a smaller
         block size.
  
+ For the MSDOS port of @code{bzip2recover} the following applies:
+ 
+ If LFN support is available the output file names will be of the same form as
+ above described. If LFN support is not available then @code{rec0001file} will
+ become @code{r0001file}, etc. If the file has no extension then an @code{.bz2} extension
+ will be added, else the original extension will be preserved.
+ 
  
  @unnumberedsubsubsec PERFORMANCE NOTES
  
  The sorting phase of compression gathers together similar strings in the
  file.  Because of this, files containing very long runs of repeated
*************** This interface provides functions for re
*** 1171,1181 ****
  @subsection @code{BZ2_bzReadOpen}
  @example
     typedef void BZFILE;
  
     BZFILE *BZ2_bzReadOpen ( int *bzerror, FILE *f, 
!                             int small, int verbosity,
                              void *unused, int nUnused );
  @end example
  Prepare to read compressed data from file handle @code{f}.  @code{f}
  should refer to a file which has been opened for reading, and for which
  the error indicator (@code{ferror(f)})is not set.  If @code{small} is 1,
--- 1250,1260 ----
  @subsection @code{BZ2_bzReadOpen}
  @example
     typedef void BZFILE;
  
     BZFILE *BZ2_bzReadOpen ( int *bzerror, FILE *f, 
!                             int verbosity, int small,
                              void *unused, int nUnused );
  @end example
  Prepare to read compressed data from file handle @code{f}.  @code{f}
  should refer to a file which has been opened for reading, and for which
  the error indicator (@code{ferror(f)})is not set.  If @code{small} is 1,
*************** int     nWritten;
*** 1567,1577 ****
  
  f = fopen ( "myfile.bz2", "r" );
  if (!f) @{
     /* handle error */
  @}
! b = BZ2_bzReadOpen ( &bzerror, f, 0, NULL, 0 );
  if (bzerror != BZ_OK) @{
     BZ2_bzReadClose ( &bzerror, b );
     /* handle error */
  @}
  
--- 1646,1656 ----
  
  f = fopen ( "myfile.bz2", "r" );
  if (!f) @{
     /* handle error */
  @}
! b = BZ2_bzReadOpen ( &bzerror, f, 0, 0, NULL, 0 );
  if (bzerror != BZ_OK) @{
     BZ2_bzReadClose ( &bzerror, b );
     /* handle error */
  @}
  
*************** if (bzerror != BZ_STREAM_END) @{
*** 1587,1596 ****
--- 1666,1677 ----
     /* handle error */
  @} else @{
     BZ2_bzReadClose ( &bzerror );
  @}
  @end example
+ On MS-DOS/WIN9X systems all fopen calls must be done in binary mode,
+ so substitute the "r" and "w" parameter in the examples above by "rb" and "wb" accordingly.
  
  
  
  @section Utility functions
  @subsection @code{BZ2_bzBuffToBuffCompress}
diff -acrpNC5 bzp2-100.gnu/words3 bzp2-100.djg/words3
*** bzp2-100.gnu/words3	Mon Jun  7 23:19:06 1999
--- bzp2-100.djg/words3	Thu May 18 09:00:28 2000
*************** To install somewhere else, eg, /xxx/yyy/
*** 9,23 ****
  If you are (justifiably) paranoid and want to see what 'make install'
  is going to do, you can first do
     make -n install                      or
     make -n install PREFIX=/xxx/yyy      respectively.
  The -n instructs make to show the commands it would execute, but
! not actually execute them.
  
  Instructions for use are in the preformatted manual page, in the file
  bzip2.txt.  For more detailed documentation, read the full manual.  
! It is available in Postscript form (manual.ps) and HTML form
! (manual_toc.html).
  
  You can also do "bzip2 --help" to see some helpful information. 
  "bzip2 -L" displays the software license.
  
--- 9,23 ----
  If you are (justifiably) paranoid and want to see what 'make install'
  is going to do, you can first do
     make -n install                      or
     make -n install PREFIX=/xxx/yyy      respectively.
  The -n instructs make to show the commands it would execute, but
! does not actually execute them.
  
  Instructions for use are in the preformatted manual page, in the file
  bzip2.txt.  For more detailed documentation, read the full manual.  
! It is available in Postscript form (bzip2.ps) and HTML form
! (bzip2.html).
  
  You can also do "bzip2 --help" to see some helpful information. 
  "bzip2 -L" displays the software license.
  
