diff -ru bzip2-1.0.2/Makefile bzip2-1.0.2-progress/Makefile
--- bzip2-1.0.2/Makefile	Fri Jan 25 15:34:53 2002
+++ bzip2-1.0.2-progress/Makefile	Sat Jun 29 14:55:40 2002
@@ -8,7 +8,7 @@
 LDFLAGS=
 
 # Suitably paranoid flags to avoid bugs in gcc-2.7
-BIGFILES=-D_FILE_OFFSET_BITS=64
+BIGFILES=-D_FILE_OFFSET_BITS=64 -D__USE_LARGEFILE64=1
 CFLAGS=-Wall -Winline -O2 -fomit-frame-pointer -fno-strength-reduce $(BIGFILES)
 
 # Where you want it installed when you do 'make install'
diff -ru bzip2-1.0.2/bzip2.c bzip2-1.0.2-progress/bzip2.c
--- bzip2-1.0.2/bzip2.c	Thu Jan 24 17:38:36 2002
+++ bzip2-1.0.2-progress/bzip2.c	Thu Aug  8 16:45:12 2002
@@ -1,4 +1,5 @@
 
+
 /*-----------------------------------------------------------*/
 /*--- A block-sorting, lossless compressor        bzip2.c ---*/
 /*-----------------------------------------------------------*/
@@ -146,6 +147,8 @@
 #include <math.h>
 #include <errno.h>
 #include <ctype.h>
+#include <sys/ioctl.h>
+
 #include "bzlib.h"
 
 #define ERROR_IF_EOF(i)       { if ((i) == EOF)  ioError(); }
@@ -273,7 +276,7 @@
 /*---------------------------------------------------*/
 
 Int32   verbosity;
-Bool    keepInputFiles, smallMode, deleteOutputOnInterrupt;
+Bool    keepInputFiles, smallMode, deleteOutputOnInterrupt, showProgress;
 Bool    forceOverwrite, testFailsExist, unzFailsExist, noisy;
 Int32   numFileNames, numFilesProcessed, blockSize100k;
 Int32   exitValue;
@@ -416,8 +419,34 @@
 
 
 /*---------------------------------------------*/
+static
+void displayProgress( const char *name, unsigned short ws_col, unsigned long long cur, unsigned long long end ) 
+{
+    float percentage = (float)cur / (float)end;
+    unsigned int barsize = ws_col - 11 - strlen(name);
+    unsigned int barlen = barsize * percentage;
+    char *bar;
+    static unsigned int oldbarlen;  // spinner to prevent excessive writes
+
+    if (oldbarlen == barlen) 
+	return;
+
+    oldbarlen = barlen;
+    bar = myMalloc(barsize+1);
+
+    memset(bar, ' ', barsize);
+    memset(bar, '*', barlen);
+    bar[barsize] = 0;
+
+    printf("%s: |%s| (%u%%)\r", name, bar, (unsigned)(percentage * 100));
+    fflush(stdout);
+    
+    free(bar);
+}
+
+/*---------------------------------------------*/
 static 
-void compressStream ( FILE *stream, FILE *zStream )
+void compressStream ( const char *s_stream, FILE *stream, FILE *zStream )
 {
    BZFILE* bzf = NULL;
    UChar   ibuf[5000];
@@ -425,6 +454,10 @@
    UInt32  nbytes_in_lo32, nbytes_in_hi32;
    UInt32  nbytes_out_lo32, nbytes_out_hi32;
    Int32   bzerr, bzerr_dummy, ret;
+   UInt32  ws_col = 0;
+   u_int64_t  targetSize;
+   targetSize = 0;
+
 
    SET_BINARY_MODE(stream);
    SET_BINARY_MODE(zStream);
@@ -438,16 +471,57 @@
 
    if (verbosity >= 2) fprintf ( stderr, "\n" );
 
+   // need to find what the outer bound is.  showProgress should be
+   // turned off elsewhere if it's unrealistic (stdin/stdout type of
+   // stuff), but the logic shouldn't be in here.
+   if (showProgress) {
+       struct winsize ws;
+
+       // get target size first
+#ifdef __USE_LARGEFILE64
+       struct stat64 s;
+       fstat64(stream->_fileno, &s);
+#else
+       struct stat s;
+       fstat(stream->_fileno, &s);
+#endif
+       targetSize = s.st_size;
+
+       // then get screen size, so we know where to print the bar
+       if (!ioctl(0, TIOCGWINSZ, &ws)) 
+	   ws_col = ws.ws_col;
+       else ws_col = 80;
+       
+       displayProgress(s_stream, ws_col, 0, targetSize);
+   }
+
    while (True) {
 
       if (myfeof(stream)) break;
       nIbuf = fread ( ibuf, sizeof(UChar), 5000, stream );
       if (ferror(stream)) goto errhandler_io;
       if (nIbuf > 0) BZ2_bzWrite ( &bzerr, bzf, (void*)ibuf, nIbuf );
+
+      if (showProgress) {
+#ifdef __USE_LARGEFILE64
+	  fpos64_t p;
+	  fgetpos64(stream, &p);
+#else
+	  fpos_t p;
+	  fgetpos(stream, &p);
+#endif
+	  displayProgress(s_stream, ws_col, p.__pos, targetSize);
+      }
+
       if (bzerr != BZ_OK) goto errhandler;
 
    }
 
+   if (showProgress) {  // final output
+       displayProgress(s_stream, ws_col, targetSize, targetSize);
+       printf("\n");
+   }
+
    BZ2_bzWriteClose64 ( &bzerr, bzf, 0, 
                         &nbytes_in_lo32, &nbytes_in_hi32,
                         &nbytes_out_lo32, &nbytes_out_hi32 );
@@ -518,7 +592,7 @@
 
 /*---------------------------------------------*/
 static 
-Bool uncompressStream ( FILE *zStream, FILE *stream )
+Bool uncompressStream ( const char *s_zStream, FILE *zStream, FILE *stream )
 {
    BZFILE* bzf = NULL;
    Int32   bzerr, bzerr_dummy, ret, nread, streamNo, i;
@@ -526,6 +600,8 @@
    UChar   unused[BZ_MAX_UNUSED];
    Int32   nUnused;
    UChar*  unusedTmp;
+   UInt32  ws_col = 0;
+   u_int64_t  targetSize = 0;
 
    nUnused = 0;
    streamNo = 0;
@@ -536,6 +612,30 @@
    if (ferror(stream)) goto errhandler_io;
    if (ferror(zStream)) goto errhandler_io;
 
+   // need to find what the outer bound is.  showProgress should be
+   // turned off elsewhere if it's unrealistic (stdin/stdout type of
+   // stuff), but the logic shouldn't be in here.
+   if (showProgress) {
+       struct winsize ws;
+
+       // get target size first
+#ifdef __USE_LARGEFILE64
+       struct stat64 s;
+       fstat64(zStream->_fileno, &s);
+#else
+       struct stat s;
+       fstat(zStream->_fileno, &s);
+#endif
+       targetSize = s.st_size;
+
+       // then get screen size, so we know where to print the bar
+       if (!ioctl(0, TIOCGWINSZ, &ws)) 
+	   ws_col = ws.ws_col;
+       else ws_col = 80;
+
+       displayProgress(s_zStream, ws_col, 0, targetSize);
+   }
+
    while (True) {
 
       bzf = BZ2_bzReadOpen ( 
@@ -550,10 +650,28 @@
          if (bzerr == BZ_DATA_ERROR_MAGIC) goto trycat;
          if ((bzerr == BZ_OK || bzerr == BZ_STREAM_END) && nread > 0)
             fwrite ( obuf, sizeof(UChar), nread, stream );
+
+	 if (showProgress) {
+#ifdef __USE_LARGEFILE64
+	     fpos64_t p;
+	     fgetpos64(zStream, &p);
+#else
+	     fpos_t p;
+	     fgetpos(zStream, &p);
+#endif
+	     displayProgress(s_zStream, ws_col, p.__pos, targetSize);
+	 }
+
          if (ferror(stream)) goto errhandler_io;
       }
+
       if (bzerr != BZ_STREAM_END) goto errhandler;
 
+      if (showProgress) {  // final output
+	  displayProgress(s_zStream, ws_col, targetSize, targetSize);
+	  printf("\n");
+      }
+
       BZ2_bzReadGetUnused ( &bzerr, bzf, (void**)(&unusedTmp), &nUnused );
       if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" );
 
@@ -1294,6 +1412,7 @@
    switch ( srcMode ) {
 
       case SM_I2O:
+         showProgress = False;
          inStr = stdin;
          outStr = stdout;
          if ( isatty ( fileno ( stdout ) ) ) {
@@ -1308,6 +1427,7 @@
          break;
 
       case SM_F2O:
+	 showProgress = False;
          inStr = fopen ( inName, "rb" );
          outStr = stdout;
          if ( isatty ( fileno ( stdout ) ) ) {
@@ -1361,7 +1481,7 @@
    /*--- Now the input and output handles are sane.  Do the Biz. ---*/
    outputHandleJustInCase = outStr;
    deleteOutputOnInterrupt = True;
-   compressStream ( inStr, outStr );
+   compressStream ( name, inStr, outStr );
    outputHandleJustInCase = NULL;
 
    /*--- If there was an I/O error, we won't get here. ---*/
@@ -1480,7 +1600,8 @@
    switch ( srcMode ) {
 
       case SM_I2O:
-         inStr = stdin;
+	 showProgress = False;
+	 inStr = stdin;
          outStr = stdout;
          if ( isatty ( fileno ( stdin ) ) ) {
             fprintf ( stderr,
@@ -1494,6 +1615,7 @@
          break;
 
       case SM_F2O:
+	 showProgress = False;
          inStr = fopen ( inName, "rb" );
          outStr = stdout;
          if ( inStr == NULL ) {
@@ -1535,10 +1657,9 @@
       fflush ( stderr );
    }
 
-   /*--- Now the input and output handles are sane.  Do the Biz. ---*/
    outputHandleJustInCase = outStr;
    deleteOutputOnInterrupt = True;
-   magicNumberOK = uncompressStream ( inStr, outStr );
+   magicNumberOK = uncompressStream ( name, inStr, outStr );
    outputHandleJustInCase = NULL;
 
    /*--- If there was an I/O error, we won't get here. ---*/
@@ -1704,6 +1825,7 @@
       "   -d --decompress     force decompression\n"
       "   -z --compress       force compression\n"
       "   -k --keep           keep (don't delete) input files\n"
+      "   -p --progress       show a progress bar\n"
       "   -f --force          overwrite existing output files\n"
       "   -t --test           test compressed file integrity\n"
       "   -c --stdout         output to standard out\n"
@@ -1860,6 +1982,7 @@
    outputHandleJustInCase  = NULL;
    smallMode               = False;
    keepInputFiles          = False;
+   showProgress            = False;
    forceOverwrite          = False;
    noisy                   = True;
    verbosity               = 0;
@@ -1947,6 +2070,7 @@
                case 'f': forceOverwrite   = True; break;
                case 't': opMode           = OM_TEST; break;
                case 'k': keepInputFiles   = True; break;
+ 	       case 'p': showProgress     = True; break;
                case 's': smallMode        = True; break;
                case 'q': noisy            = False; break;
                case '1': blockSize100k    = 1; break;
@@ -1983,6 +2107,7 @@
       if (ISFLAG("--force"))             forceOverwrite   = True;    else
       if (ISFLAG("--test"))              opMode           = OM_TEST; else
       if (ISFLAG("--keep"))              keepInputFiles   = True;    else
+      if (ISFLAG("--progress"))          showProgress     = True;    else
       if (ISFLAG("--small"))             smallMode        = True;    else
       if (ISFLAG("--quiet"))             noisy            = False;   else
       if (ISFLAG("--version"))           license();                  else
