aboutsummaryrefslogtreecommitdiff
path: root/bzip2.c
diff options
context:
space:
mode:
authorJulian Seward <jseward@acm.org>2000-06-24 22:13:13 +0200
committerJulian Seward <jseward@acm.org>2000-06-24 22:13:13 +0200
commit795b859eee96c700e8f3c3fe68e6a9a39d95797c (patch)
tree48f8a731cd5ec2f5f15c6d99f2207ebf4a1f35f6 /bzip2.c
parentf93cd82a9a7094ad90fd19bbc6ccf6f4627f8060 (diff)
downloadbzip2-795b859eee96c700e8f3c3fe68e6a9a39d95797c.tar.gz
bzip2-795b859eee96c700e8f3c3fe68e6a9a39d95797c.tar.bz2
bzip2-795b859eee96c700e8f3c3fe68e6a9a39d95797c.zip
bzip2-1.0.1bzip2-1.0.1
Diffstat (limited to 'bzip2.c')
-rw-r--r--bzip2.c508
1 files changed, 430 insertions, 78 deletions
diff --git a/bzip2.c b/bzip2.c
index abb9530..56adfdc 100644
--- a/bzip2.c
+++ b/bzip2.c
@@ -7,7 +7,7 @@
7 This file is a part of bzip2 and/or libbzip2, a program and 7 This file is a part of bzip2 and/or libbzip2, a program and
8 library for lossless, block-sorting data compression. 8 library for lossless, block-sorting data compression.
9 9
10 Copyright (C) 1996-1999 Julian R Seward. All rights reserved. 10 Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
11 11
12 Redistribution and use in source and binary forms, with or without 12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions 13 modification, are permitted provided that the following conditions
@@ -42,7 +42,7 @@
42 42
43 Julian Seward, Cambridge, UK. 43 Julian Seward, Cambridge, UK.
44 jseward@acm.org 44 jseward@acm.org
45 bzip2/libbzip2 version 0.9.5 of 24 May 1999 45 bzip2/libbzip2 version 1.0 of 21 March 2000
46 46
47 This program is based on (at least) the work of: 47 This program is based on (at least) the work of:
48 Mike Burrows 48 Mike Burrows
@@ -123,10 +123,10 @@
123--*/ 123--*/
124#define BZ_LCCWIN32 0 124#define BZ_LCCWIN32 0
125 125
126#if defined(_WIN32) && !defined(__CYGWIN32__) 126#if defined(_WIN32) && !defined(__CYGWIN__)
127#undef BZ_LCCWIN32 127#undef BZ_LCCWIN32
128#define BZ_LCCWIN32 1 128#define BZ_LCCWIN32 1
129#undef BZ_UNIX 129#undef BZ_UNIX
130#define BZ_UNIX 0 130#define BZ_UNIX 0
131#endif 131#endif
132 132
@@ -193,6 +193,17 @@
193 ERROR_IF_MINUS_ONE ( retVal ); \ 193 ERROR_IF_MINUS_ONE ( retVal ); \
194 } while ( 0 ) 194 } while ( 0 )
195# endif 195# endif
196# ifdef __CYGWIN__
197# include <io.h>
198# include <fcntl.h>
199# undef SET_BINARY_MODE
200# define SET_BINARY_MODE(fd) \
201 do { \
202 int retVal = setmode ( fileno ( fd ), \
203 O_BINARY ); \
204 ERROR_IF_MINUS_ONE ( retVal ); \
205 } while ( 0 )
206# endif
196#endif 207#endif
197 208
198 209
@@ -276,10 +287,10 @@ typedef int IntNative;
276/*---------------------------------------------------*/ 287/*---------------------------------------------------*/
277 288
278Int32 verbosity; 289Int32 verbosity;
279Bool keepInputFiles, smallMode; 290Bool keepInputFiles, smallMode, deleteOutputOnInterrupt;
280Bool forceOverwrite, testFailsExist, noisy; 291Bool forceOverwrite, testFailsExist, unzFailsExist, noisy;
281Int32 numFileNames, numFilesProcessed, blockSize100k; 292Int32 numFileNames, numFilesProcessed, blockSize100k;
282 293Int32 exitValue;
283 294
284/*-- source modes; F==file, I==stdin, O==stdout --*/ 295/*-- source modes; F==file, I==stdin, O==stdout --*/
285#define SM_I2O 1 296#define SM_I2O 1
@@ -305,27 +316,204 @@ Char progNameReally[FILE_NAME_LEN];
305FILE *outputHandleJustInCase; 316FILE *outputHandleJustInCase;
306Int32 workFactor; 317Int32 workFactor;
307 318
308void panic ( Char* ) NORETURN; 319static void panic ( Char* ) NORETURN;
309void ioError ( void ) NORETURN; 320static void ioError ( void ) NORETURN;
310void outOfMemory ( void ) NORETURN; 321static void outOfMemory ( void ) NORETURN;
311void blockOverrun ( void ) NORETURN; 322static void configError ( void ) NORETURN;
312void badBlockHeader ( void ) NORETURN; 323static void crcError ( void ) NORETURN;
313void badBGLengths ( void ) NORETURN; 324static void cleanUpAndFail ( Int32 ) NORETURN;
314void crcError ( void ) NORETURN; 325static void compressedStreamEOF ( void ) NORETURN;
315void bitStreamEOF ( void ) NORETURN;
316void cleanUpAndFail ( Int32 ) NORETURN;
317void compressedStreamEOF ( void ) NORETURN;
318 326
319void copyFileName ( Char*, Char* ); 327static void copyFileName ( Char*, Char* );
320void* myMalloc ( Int32 ); 328static void* myMalloc ( Int32 );
321 329
322 330
323 331
324/*---------------------------------------------------*/ 332/*---------------------------------------------------*/
333/*--- An implementation of 64-bit ints. Sigh. ---*/
334/*--- Roll on widespread deployment of ANSI C9X ! ---*/
335/*---------------------------------------------------*/
336
337typedef
338 struct { UChar b[8]; }
339 UInt64;
340
341static
342void uInt64_from_UInt32s ( UInt64* n, UInt32 lo32, UInt32 hi32 )
343{
344 n->b[7] = (UChar)((hi32 >> 24) & 0xFF);
345 n->b[6] = (UChar)((hi32 >> 16) & 0xFF);
346 n->b[5] = (UChar)((hi32 >> 8) & 0xFF);
347 n->b[4] = (UChar) (hi32 & 0xFF);
348 n->b[3] = (UChar)((lo32 >> 24) & 0xFF);
349 n->b[2] = (UChar)((lo32 >> 16) & 0xFF);
350 n->b[1] = (UChar)((lo32 >> 8) & 0xFF);
351 n->b[0] = (UChar) (lo32 & 0xFF);
352}
353
354static
355double uInt64_to_double ( UInt64* n )
356{
357 Int32 i;
358 double base = 1.0;
359 double sum = 0.0;
360 for (i = 0; i < 8; i++) {
361 sum += base * (double)(n->b[i]);
362 base *= 256.0;
363 }
364 return sum;
365}
366
367static
368void uInt64_add ( UInt64* src, UInt64* dst )
369{
370 Int32 i;
371 Int32 carry = 0;
372 for (i = 0; i < 8; i++) {
373 carry += ( ((Int32)src->b[i]) + ((Int32)dst->b[i]) );
374 dst->b[i] = (UChar)(carry & 0xFF);
375 carry >>= 8;
376 }
377}
378
379static
380void uInt64_sub ( UInt64* src, UInt64* dst )
381{
382 Int32 t, i;
383 Int32 borrow = 0;
384 for (i = 0; i < 8; i++) {
385 t = ((Int32)dst->b[i]) - ((Int32)src->b[i]) - borrow;
386 if (t < 0) {
387 dst->b[i] = (UChar)(t + 256);
388 borrow = 1;
389 } else {
390 dst->b[i] = (UChar)t;
391 borrow = 0;
392 }
393 }
394}
395
396static
397void uInt64_mul ( UInt64* a, UInt64* b, UInt64* r_hi, UInt64* r_lo )
398{
399 UChar sum[16];
400 Int32 ia, ib, carry;
401 for (ia = 0; ia < 16; ia++) sum[ia] = 0;
402 for (ia = 0; ia < 8; ia++) {
403 carry = 0;
404 for (ib = 0; ib < 8; ib++) {
405 carry += ( ((Int32)sum[ia+ib])
406 + ((Int32)a->b[ia]) * ((Int32)b->b[ib]) );
407 sum[ia+ib] = (UChar)(carry & 0xFF);
408 carry >>= 8;
409 }
410 sum[ia+8] = (UChar)(carry & 0xFF);
411 if ((carry >>= 8) != 0) panic ( "uInt64_mul" );
412 }
413
414 for (ia = 0; ia < 8; ia++) r_hi->b[ia] = sum[ia+8];
415 for (ia = 0; ia < 8; ia++) r_lo->b[ia] = sum[ia];
416}
417
418
419static
420void uInt64_shr1 ( UInt64* n )
421{
422 Int32 i;
423 for (i = 0; i < 8; i++) {
424 n->b[i] >>= 1;
425 if (i < 7 && (n->b[i+1] & 1)) n->b[i] |= 0x80;
426 }
427}
428
429static
430void uInt64_shl1 ( UInt64* n )
431{
432 Int32 i;
433 for (i = 7; i >= 0; i--) {
434 n->b[i] <<= 1;
435 if (i > 0 && (n->b[i-1] & 0x80)) n->b[i]++;
436 }
437}
438
439static
440Bool uInt64_isZero ( UInt64* n )
441{
442 Int32 i;
443 for (i = 0; i < 8; i++)
444 if (n->b[i] != 0) return 0;
445 return 1;
446}
447
448static
449Int32 uInt64_qrm10 ( UInt64* n )
450{
451 /* Divide *n by 10, and return the remainder. Long division
452 is difficult, so we cheat and instead multiply by
453 0xCCCC CCCC CCCC CCCD, which is 0.8 (viz, 0.1 << 3).
454 */
455 Int32 i;
456 UInt64 tmp1, tmp2, n_orig, zero_point_eight;
457
458 zero_point_eight.b[1] = zero_point_eight.b[2] =
459 zero_point_eight.b[3] = zero_point_eight.b[4] =
460 zero_point_eight.b[5] = zero_point_eight.b[6] =
461 zero_point_eight.b[7] = 0xCC;
462 zero_point_eight.b[0] = 0xCD;
463
464 n_orig = *n;
465
466 /* divide n by 10,
467 by multiplying by 0.8 and then shifting right 3 times */
468 uInt64_mul ( n, &zero_point_eight, &tmp1, &tmp2 );
469 uInt64_shr1(&tmp1); uInt64_shr1(&tmp1); uInt64_shr1(&tmp1);
470 *n = tmp1;
471
472 /* tmp1 = 8*n, tmp2 = 2*n */
473 uInt64_shl1(&tmp1); uInt64_shl1(&tmp1); uInt64_shl1(&tmp1);
474 tmp2 = *n; uInt64_shl1(&tmp2);
475
476 /* tmp1 = 10*n */
477 uInt64_add ( &tmp2, &tmp1 );
478
479 /* n_orig = n_orig - 10*n */
480 uInt64_sub ( &tmp1, &n_orig );
481
482 /* n_orig should now hold quotient, in range 0 .. 9 */
483 for (i = 7; i >= 1; i--)
484 if (n_orig.b[i] != 0) panic ( "uInt64_qrm10(1)" );
485 if (n_orig.b[0] > 9)
486 panic ( "uInt64_qrm10(2)" );
487
488 return (int)n_orig.b[0];
489}
490
491/* ... and the Whole Entire Point of all this UInt64 stuff is
492 so that we can supply the following function.
493*/
494static
495void uInt64_toAscii ( char* outbuf, UInt64* n )
496{
497 Int32 i, q;
498 UChar buf[32];
499 Int32 nBuf = 0;
500 UInt64 n_copy = *n;
501 do {
502 q = uInt64_qrm10 ( &n_copy );
503 buf[nBuf] = q + '0';
504 nBuf++;
505 } while (!uInt64_isZero(&n_copy));
506 outbuf[nBuf] = 0;
507 for (i = 0; i < nBuf; i++) outbuf[i] = buf[nBuf-i-1];
508}
509
510
511/*---------------------------------------------------*/
325/*--- Processing of complete files and streams ---*/ 512/*--- Processing of complete files and streams ---*/
326/*---------------------------------------------------*/ 513/*---------------------------------------------------*/
327 514
328/*---------------------------------------------*/ 515/*---------------------------------------------*/
516static
329Bool myfeof ( FILE* f ) 517Bool myfeof ( FILE* f )
330{ 518{
331 Int32 c = fgetc ( f ); 519 Int32 c = fgetc ( f );
@@ -336,12 +524,14 @@ Bool myfeof ( FILE* f )
336 524
337 525
338/*---------------------------------------------*/ 526/*---------------------------------------------*/
527static
339void compressStream ( FILE *stream, FILE *zStream ) 528void compressStream ( FILE *stream, FILE *zStream )
340{ 529{
341 BZFILE* bzf = NULL; 530 BZFILE* bzf = NULL;
342 UChar ibuf[5000]; 531 UChar ibuf[5000];
343 Int32 nIbuf; 532 Int32 nIbuf;
344 UInt32 nbytes_in, nbytes_out; 533 UInt32 nbytes_in_lo32, nbytes_in_hi32;
534 UInt32 nbytes_out_lo32, nbytes_out_hi32;
345 Int32 bzerr, bzerr_dummy, ret; 535 Int32 bzerr, bzerr_dummy, ret;
346 536
347 SET_BINARY_MODE(stream); 537 SET_BINARY_MODE(stream);
@@ -350,8 +540,8 @@ void compressStream ( FILE *stream, FILE *zStream )
350 if (ferror(stream)) goto errhandler_io; 540 if (ferror(stream)) goto errhandler_io;
351 if (ferror(zStream)) goto errhandler_io; 541 if (ferror(zStream)) goto errhandler_io;
352 542
353 bzf = bzWriteOpen ( &bzerr, zStream, 543 bzf = BZ2_bzWriteOpen ( &bzerr, zStream,
354 blockSize100k, verbosity, workFactor ); 544 blockSize100k, verbosity, workFactor );
355 if (bzerr != BZ_OK) goto errhandler; 545 if (bzerr != BZ_OK) goto errhandler;
356 546
357 if (verbosity >= 2) fprintf ( stderr, "\n" ); 547 if (verbosity >= 2) fprintf ( stderr, "\n" );
@@ -361,12 +551,14 @@ void compressStream ( FILE *stream, FILE *zStream )
361 if (myfeof(stream)) break; 551 if (myfeof(stream)) break;
362 nIbuf = fread ( ibuf, sizeof(UChar), 5000, stream ); 552 nIbuf = fread ( ibuf, sizeof(UChar), 5000, stream );
363 if (ferror(stream)) goto errhandler_io; 553 if (ferror(stream)) goto errhandler_io;
364 if (nIbuf > 0) bzWrite ( &bzerr, bzf, (void*)ibuf, nIbuf ); 554 if (nIbuf > 0) BZ2_bzWrite ( &bzerr, bzf, (void*)ibuf, nIbuf );
365 if (bzerr != BZ_OK) goto errhandler; 555 if (bzerr != BZ_OK) goto errhandler;
366 556
367 } 557 }
368 558
369 bzWriteClose ( &bzerr, bzf, 0, &nbytes_in, &nbytes_out ); 559 BZ2_bzWriteClose64 ( &bzerr, bzf, 0,
560 &nbytes_in_lo32, &nbytes_in_hi32,
561 &nbytes_out_lo32, &nbytes_out_hi32 );
370 if (bzerr != BZ_OK) goto errhandler; 562 if (bzerr != BZ_OK) goto errhandler;
371 563
372 if (ferror(zStream)) goto errhandler_io; 564 if (ferror(zStream)) goto errhandler_io;
@@ -380,25 +572,42 @@ void compressStream ( FILE *stream, FILE *zStream )
380 ret = fclose ( stream ); 572 ret = fclose ( stream );
381 if (ret == EOF) goto errhandler_io; 573 if (ret == EOF) goto errhandler_io;
382 574
383 if (nbytes_in == 0) nbytes_in = 1; 575 if (nbytes_in_lo32 == 0 && nbytes_in_hi32 == 0)
576 nbytes_in_lo32 = 1;
384 577
385 if (verbosity >= 1) 578 if (verbosity >= 1) {
579 Char buf_nin[32], buf_nout[32];
580 UInt64 nbytes_in, nbytes_out;
581 double nbytes_in_d, nbytes_out_d;
582 uInt64_from_UInt32s ( &nbytes_in,
583 nbytes_in_lo32, nbytes_in_hi32 );
584 uInt64_from_UInt32s ( &nbytes_out,
585 nbytes_out_lo32, nbytes_out_hi32 );
586 nbytes_in_d = uInt64_to_double ( &nbytes_in );
587 nbytes_out_d = uInt64_to_double ( &nbytes_out );
588 uInt64_toAscii ( buf_nin, &nbytes_in );
589 uInt64_toAscii ( buf_nout, &nbytes_out );
386 fprintf ( stderr, "%6.3f:1, %6.3f bits/byte, " 590 fprintf ( stderr, "%6.3f:1, %6.3f bits/byte, "
387 "%5.2f%% saved, %d in, %d out.\n", 591 "%5.2f%% saved, %s in, %s out.\n",
388 (float)nbytes_in / (float)nbytes_out, 592 nbytes_in_d / nbytes_out_d,
389 (8.0 * (float)nbytes_out) / (float)nbytes_in, 593 (8.0 * nbytes_out_d) / nbytes_in_d,
390 100.0 * (1.0 - (float)nbytes_out / (float)nbytes_in), 594 100.0 * (1.0 - nbytes_out_d / nbytes_in_d),
391 nbytes_in, 595 buf_nin,
392 nbytes_out 596 buf_nout
393 ); 597 );
598 }
394 599
395 return; 600 return;
396 601
397 errhandler: 602 errhandler:
398 bzWriteClose ( &bzerr_dummy, bzf, 1, &nbytes_in, &nbytes_out ); 603 BZ2_bzWriteClose64 ( &bzerr_dummy, bzf, 1,
604 &nbytes_in_lo32, &nbytes_in_hi32,
605 &nbytes_out_lo32, &nbytes_out_hi32 );
399 switch (bzerr) { 606 switch (bzerr) {
607 case BZ_CONFIG_ERROR:
608 configError(); break;
400 case BZ_MEM_ERROR: 609 case BZ_MEM_ERROR:
401 outOfMemory (); 610 outOfMemory (); break;
402 case BZ_IO_ERROR: 611 case BZ_IO_ERROR:
403 errhandler_io: 612 errhandler_io:
404 ioError(); break; 613 ioError(); break;
@@ -413,6 +622,7 @@ void compressStream ( FILE *stream, FILE *zStream )
413 622
414 623
415/*---------------------------------------------*/ 624/*---------------------------------------------*/
625static
416Bool uncompressStream ( FILE *zStream, FILE *stream ) 626Bool uncompressStream ( FILE *zStream, FILE *stream )
417{ 627{
418 BZFILE* bzf = NULL; 628 BZFILE* bzf = NULL;
@@ -433,7 +643,7 @@ Bool uncompressStream ( FILE *zStream, FILE *stream )
433 643
434 while (True) { 644 while (True) {
435 645
436 bzf = bzReadOpen ( 646 bzf = BZ2_bzReadOpen (
437 &bzerr, zStream, verbosity, 647 &bzerr, zStream, verbosity,
438 (int)smallMode, unused, nUnused 648 (int)smallMode, unused, nUnused
439 ); 649 );
@@ -441,7 +651,7 @@ Bool uncompressStream ( FILE *zStream, FILE *stream )
441 streamNo++; 651 streamNo++;
442 652
443 while (bzerr == BZ_OK) { 653 while (bzerr == BZ_OK) {
444 nread = bzRead ( &bzerr, bzf, obuf, 5000 ); 654 nread = BZ2_bzRead ( &bzerr, bzf, obuf, 5000 );
445 if (bzerr == BZ_DATA_ERROR_MAGIC) goto errhandler; 655 if (bzerr == BZ_DATA_ERROR_MAGIC) goto errhandler;
446 if ((bzerr == BZ_OK || bzerr == BZ_STREAM_END) && nread > 0) 656 if ((bzerr == BZ_OK || bzerr == BZ_STREAM_END) && nread > 0)
447 fwrite ( obuf, sizeof(UChar), nread, stream ); 657 fwrite ( obuf, sizeof(UChar), nread, stream );
@@ -449,12 +659,12 @@ Bool uncompressStream ( FILE *zStream, FILE *stream )
449 } 659 }
450 if (bzerr != BZ_STREAM_END) goto errhandler; 660 if (bzerr != BZ_STREAM_END) goto errhandler;
451 661
452 bzReadGetUnused ( &bzerr, bzf, (void**)(&unusedTmp), &nUnused ); 662 BZ2_bzReadGetUnused ( &bzerr, bzf, (void**)(&unusedTmp), &nUnused );
453 if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" ); 663 if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" );
454 664
455 for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i]; 665 for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i];
456 666
457 bzReadClose ( &bzerr, bzf ); 667 BZ2_bzReadClose ( &bzerr, bzf );
458 if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" ); 668 if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" );
459 669
460 if (nUnused == 0 && myfeof(zStream)) break; 670 if (nUnused == 0 && myfeof(zStream)) break;
@@ -476,8 +686,10 @@ Bool uncompressStream ( FILE *zStream, FILE *stream )
476 return True; 686 return True;
477 687
478 errhandler: 688 errhandler:
479 bzReadClose ( &bzerr_dummy, bzf ); 689 BZ2_bzReadClose ( &bzerr_dummy, bzf );
480 switch (bzerr) { 690 switch (bzerr) {
691 case BZ_CONFIG_ERROR:
692 configError(); break;
481 case BZ_IO_ERROR: 693 case BZ_IO_ERROR:
482 errhandler_io: 694 errhandler_io:
483 ioError(); break; 695 ioError(); break;
@@ -488,6 +700,8 @@ Bool uncompressStream ( FILE *zStream, FILE *stream )
488 case BZ_UNEXPECTED_EOF: 700 case BZ_UNEXPECTED_EOF:
489 compressedStreamEOF(); 701 compressedStreamEOF();
490 case BZ_DATA_ERROR_MAGIC: 702 case BZ_DATA_ERROR_MAGIC:
703 if (zStream != stdin) fclose(zStream);
704 if (stream != stdout) fclose(stream);
491 if (streamNo == 1) { 705 if (streamNo == 1) {
492 return False; 706 return False;
493 } else { 707 } else {
@@ -507,6 +721,7 @@ Bool uncompressStream ( FILE *zStream, FILE *stream )
507 721
508 722
509/*---------------------------------------------*/ 723/*---------------------------------------------*/
724static
510Bool testStream ( FILE *zStream ) 725Bool testStream ( FILE *zStream )
511{ 726{
512 BZFILE* bzf = NULL; 727 BZFILE* bzf = NULL;
@@ -524,7 +739,7 @@ Bool testStream ( FILE *zStream )
524 739
525 while (True) { 740 while (True) {
526 741
527 bzf = bzReadOpen ( 742 bzf = BZ2_bzReadOpen (
528 &bzerr, zStream, verbosity, 743 &bzerr, zStream, verbosity,
529 (int)smallMode, unused, nUnused 744 (int)smallMode, unused, nUnused
530 ); 745 );
@@ -532,17 +747,17 @@ Bool testStream ( FILE *zStream )
532 streamNo++; 747 streamNo++;
533 748
534 while (bzerr == BZ_OK) { 749 while (bzerr == BZ_OK) {
535 nread = bzRead ( &bzerr, bzf, obuf, 5000 ); 750 nread = BZ2_bzRead ( &bzerr, bzf, obuf, 5000 );
536 if (bzerr == BZ_DATA_ERROR_MAGIC) goto errhandler; 751 if (bzerr == BZ_DATA_ERROR_MAGIC) goto errhandler;
537 } 752 }
538 if (bzerr != BZ_STREAM_END) goto errhandler; 753 if (bzerr != BZ_STREAM_END) goto errhandler;
539 754
540 bzReadGetUnused ( &bzerr, bzf, (void**)(&unusedTmp), &nUnused ); 755 BZ2_bzReadGetUnused ( &bzerr, bzf, (void**)(&unusedTmp), &nUnused );
541 if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" ); 756 if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" );
542 757
543 for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i]; 758 for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i];
544 759
545 bzReadClose ( &bzerr, bzf ); 760 BZ2_bzReadClose ( &bzerr, bzf );
546 if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" ); 761 if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" );
547 if (nUnused == 0 && myfeof(zStream)) break; 762 if (nUnused == 0 && myfeof(zStream)) break;
548 763
@@ -556,10 +771,12 @@ Bool testStream ( FILE *zStream )
556 return True; 771 return True;
557 772
558 errhandler: 773 errhandler:
559 bzReadClose ( &bzerr_dummy, bzf ); 774 BZ2_bzReadClose ( &bzerr_dummy, bzf );
560 if (verbosity == 0) 775 if (verbosity == 0)
561 fprintf ( stderr, "%s: %s: ", progName, inName ); 776 fprintf ( stderr, "%s: %s: ", progName, inName );
562 switch (bzerr) { 777 switch (bzerr) {
778 case BZ_CONFIG_ERROR:
779 configError(); break;
563 case BZ_IO_ERROR: 780 case BZ_IO_ERROR:
564 errhandler_io: 781 errhandler_io:
565 ioError(); break; 782 ioError(); break;
@@ -574,6 +791,7 @@ Bool testStream ( FILE *zStream )
574 "file ends unexpectedly\n" ); 791 "file ends unexpectedly\n" );
575 return False; 792 return False;
576 case BZ_DATA_ERROR_MAGIC: 793 case BZ_DATA_ERROR_MAGIC:
794 if (zStream != stdin) fclose(zStream);
577 if (streamNo == 1) { 795 if (streamNo == 1) {
578 fprintf ( stderr, 796 fprintf ( stderr,
579 "bad magic number (file not created by bzip2)\n" ); 797 "bad magic number (file not created by bzip2)\n" );
@@ -598,6 +816,15 @@ Bool testStream ( FILE *zStream )
598/*---------------------------------------------------*/ 816/*---------------------------------------------------*/
599 817
600/*---------------------------------------------*/ 818/*---------------------------------------------*/
819static
820void setExit ( Int32 v )
821{
822 if (v > exitValue) exitValue = v;
823}
824
825
826/*---------------------------------------------*/
827static
601void cadvise ( void ) 828void cadvise ( void )
602{ 829{
603 if (noisy) 830 if (noisy)
@@ -612,6 +839,7 @@ void cadvise ( void )
612 839
613 840
614/*---------------------------------------------*/ 841/*---------------------------------------------*/
842static
615void showFileNames ( void ) 843void showFileNames ( void )
616{ 844{
617 if (noisy) 845 if (noisy)
@@ -624,11 +852,14 @@ void showFileNames ( void )
624 852
625 853
626/*---------------------------------------------*/ 854/*---------------------------------------------*/
855static
627void cleanUpAndFail ( Int32 ec ) 856void cleanUpAndFail ( Int32 ec )
628{ 857{
629 IntNative retVal; 858 IntNative retVal;
630 859
631 if ( srcMode == SM_F2F && opMode != OM_TEST ) { 860 if ( srcMode == SM_F2F
861 && opMode != OM_TEST
862 && deleteOutputOnInterrupt ) {
632 if (noisy) 863 if (noisy)
633 fprintf ( stderr, "%s: Deleting output file %s, if it exists.\n", 864 fprintf ( stderr, "%s: Deleting output file %s, if it exists.\n",
634 progName, outName ); 865 progName, outName );
@@ -647,11 +878,13 @@ void cleanUpAndFail ( Int32 ec )
647 progName, numFileNames, 878 progName, numFileNames,
648 numFileNames - numFilesProcessed ); 879 numFileNames - numFilesProcessed );
649 } 880 }
650 exit ( ec ); 881 setExit(ec);
882 exit(exitValue);
651} 883}
652 884
653 885
654/*---------------------------------------------*/ 886/*---------------------------------------------*/
887static
655void panic ( Char* s ) 888void panic ( Char* s )
656{ 889{
657 fprintf ( stderr, 890 fprintf ( stderr,
@@ -666,6 +899,7 @@ void panic ( Char* s )
666 899
667 900
668/*---------------------------------------------*/ 901/*---------------------------------------------*/
902static
669void crcError ( void ) 903void crcError ( void )
670{ 904{
671 fprintf ( stderr, 905 fprintf ( stderr,
@@ -678,6 +912,7 @@ void crcError ( void )
678 912
679 913
680/*---------------------------------------------*/ 914/*---------------------------------------------*/
915static
681void compressedStreamEOF ( void ) 916void compressedStreamEOF ( void )
682{ 917{
683 fprintf ( stderr, 918 fprintf ( stderr,
@@ -692,10 +927,12 @@ void compressedStreamEOF ( void )
692 927
693 928
694/*---------------------------------------------*/ 929/*---------------------------------------------*/
930static
695void ioError ( void ) 931void ioError ( void )
696{ 932{
697 fprintf ( stderr, 933 fprintf ( stderr,
698 "\n%s: I/O or other error, bailing out. Possible reason follows.\n", 934 "\n%s: I/O or other error, bailing out. "
935 "Possible reason follows.\n",
699 progName ); 936 progName );
700 perror ( progName ); 937 perror ( progName );
701 showFileNames(); 938 showFileNames();
@@ -704,6 +941,7 @@ void ioError ( void )
704 941
705 942
706/*---------------------------------------------*/ 943/*---------------------------------------------*/
944static
707void mySignalCatcher ( IntNative n ) 945void mySignalCatcher ( IntNative n )
708{ 946{
709 fprintf ( stderr, 947 fprintf ( stderr,
@@ -714,20 +952,53 @@ void mySignalCatcher ( IntNative n )
714 952
715 953
716/*---------------------------------------------*/ 954/*---------------------------------------------*/
955static
717void mySIGSEGVorSIGBUScatcher ( IntNative n ) 956void mySIGSEGVorSIGBUScatcher ( IntNative n )
718{ 957{
719 if (opMode == OM_Z) 958 if (opMode == OM_Z)
720 fprintf ( stderr, 959 fprintf (
721 "\n%s: Caught a SIGSEGV or SIGBUS whilst compressing,\n" 960 stderr,
722 "\twhich probably indicates a bug in bzip2. Please\n" 961 "\n%s: Caught a SIGSEGV or SIGBUS whilst compressing.\n"
723 "\treport it to me at: jseward@acm.org\n", 962 "\n"
724 progName ); 963 " Possible causes are (most likely first):\n"
964 " (1) This computer has unreliable memory or cache hardware\n"
965 " (a surprisingly common problem; try a different machine.)\n"
966 " (2) A bug in the compiler used to create this executable\n"
967 " (unlikely, if you didn't compile bzip2 yourself.)\n"
968 " (3) A real bug in bzip2 -- I hope this should never be the case.\n"
969 " The user's manual, Section 4.3, has more info on (1) and (2).\n"
970 " \n"
971 " If you suspect this is a bug in bzip2, or are unsure about (1)\n"
972 " or (2), feel free to report it to me at: jseward@acm.org.\n"
973 " Section 4.3 of the user's manual describes the info a useful\n"
974 " bug report should have. If the manual is available on your\n"
975 " system, please try and read it before mailing me. If you don't\n"
976 " have the manual or can't be bothered to read it, mail me anyway.\n"
977 "\n",
978 progName );
725 else 979 else
726 fprintf ( stderr, 980 fprintf (
727 "\n%s: Caught a SIGSEGV or SIGBUS whilst decompressing,\n" 981 stderr,
728 "\twhich probably indicates that the compressed data\n" 982 "\n%s: Caught a SIGSEGV or SIGBUS whilst decompressing.\n"
729 "\tis corrupted.\n", 983 "\n"
730 progName ); 984 " Possible causes are (most likely first):\n"
985 " (1) The compressed data is corrupted, and bzip2's usual checks\n"
986 " failed to detect this. Try bzip2 -tvv my_file.bz2.\n"
987 " (2) This computer has unreliable memory or cache hardware\n"
988 " (a surprisingly common problem; try a different machine.)\n"
989 " (3) A bug in the compiler used to create this executable\n"
990 " (unlikely, if you didn't compile bzip2 yourself.)\n"
991 " (4) A real bug in bzip2 -- I hope this should never be the case.\n"
992 " The user's manual, Section 4.3, has more info on (2) and (3).\n"
993 " \n"
994 " If you suspect this is a bug in bzip2, or are unsure about (2)\n"
995 " or (3), feel free to report it to me at: jseward@acm.org.\n"
996 " Section 4.3 of the user's manual describes the info a useful\n"
997 " bug report should have. If the manual is available on your\n"
998 " system, please try and read it before mailing me. If you don't\n"
999 " have the manual or can't be bothered to read it, mail me anyway.\n"
1000 "\n",
1001 progName );
731 1002
732 showFileNames(); 1003 showFileNames();
733 if (opMode == OM_Z) 1004 if (opMode == OM_Z)
@@ -737,6 +1008,7 @@ void mySIGSEGVorSIGBUScatcher ( IntNative n )
737 1008
738 1009
739/*---------------------------------------------*/ 1010/*---------------------------------------------*/
1011static
740void outOfMemory ( void ) 1012void outOfMemory ( void )
741{ 1013{
742 fprintf ( stderr, 1014 fprintf ( stderr,
@@ -747,11 +1019,27 @@ void outOfMemory ( void )
747} 1019}
748 1020
749 1021
1022/*---------------------------------------------*/
1023static
1024void configError ( void )
1025{
1026 fprintf ( stderr,
1027 "bzip2: I'm not configured correctly for this platform!\n"
1028 "\tI require Int32, Int16 and Char to have sizes\n"
1029 "\tof 4, 2 and 1 bytes to run properly, and they don't.\n"
1030 "\tProbably you can fix this by defining them correctly,\n"
1031 "\tand recompiling. Bye!\n" );
1032 setExit(3);
1033 exit(exitValue);
1034}
1035
1036
750/*---------------------------------------------------*/ 1037/*---------------------------------------------------*/
751/*--- The main driver machinery ---*/ 1038/*--- The main driver machinery ---*/
752/*---------------------------------------------------*/ 1039/*---------------------------------------------------*/
753 1040
754/*---------------------------------------------*/ 1041/*---------------------------------------------*/
1042static
755void pad ( Char *s ) 1043void pad ( Char *s )
756{ 1044{
757 Int32 i; 1045 Int32 i;
@@ -762,6 +1050,7 @@ void pad ( Char *s )
762 1050
763 1051
764/*---------------------------------------------*/ 1052/*---------------------------------------------*/
1053static
765void copyFileName ( Char* to, Char* from ) 1054void copyFileName ( Char* to, Char* from )
766{ 1055{
767 if ( strlen(from) > FILE_NAME_LEN-10 ) { 1056 if ( strlen(from) > FILE_NAME_LEN-10 ) {
@@ -772,7 +1061,8 @@ void copyFileName ( Char* to, Char* from )
772 "Try using a reasonable file name instead. Sorry! :-)\n", 1061 "Try using a reasonable file name instead. Sorry! :-)\n",
773 from, FILE_NAME_LEN-10 1062 from, FILE_NAME_LEN-10
774 ); 1063 );
775 exit(1); 1064 setExit(1);
1065 exit(exitValue);
776 } 1066 }
777 1067
778 strncpy(to,from,FILE_NAME_LEN-10); 1068 strncpy(to,from,FILE_NAME_LEN-10);
@@ -781,6 +1071,7 @@ void copyFileName ( Char* to, Char* from )
781 1071
782 1072
783/*---------------------------------------------*/ 1073/*---------------------------------------------*/
1074static
784Bool fileExists ( Char* name ) 1075Bool fileExists ( Char* name )
785{ 1076{
786 FILE *tmp = fopen ( name, "rb" ); 1077 FILE *tmp = fopen ( name, "rb" );
@@ -794,6 +1085,7 @@ Bool fileExists ( Char* name )
794/*-- 1085/*--
795 if in doubt, return True 1086 if in doubt, return True
796--*/ 1087--*/
1088static
797Bool notAStandardFile ( Char* name ) 1089Bool notAStandardFile ( Char* name )
798{ 1090{
799 IntNative i; 1091 IntNative i;
@@ -810,6 +1102,7 @@ Bool notAStandardFile ( Char* name )
810/*-- 1102/*--
811 rac 11/21/98 see if file has hard links to it 1103 rac 11/21/98 see if file has hard links to it
812--*/ 1104--*/
1105static
813Int32 countHardLinks ( Char* name ) 1106Int32 countHardLinks ( Char* name )
814{ 1107{
815 IntNative i; 1108 IntNative i;
@@ -822,6 +1115,7 @@ Int32 countHardLinks ( Char* name )
822 1115
823 1116
824/*---------------------------------------------*/ 1117/*---------------------------------------------*/
1118static
825void copyDatePermissionsAndOwner ( Char *srcName, Char *dstName ) 1119void copyDatePermissionsAndOwner ( Char *srcName, Char *dstName )
826{ 1120{
827#if BZ_UNIX 1121#if BZ_UNIX
@@ -849,6 +1143,7 @@ void copyDatePermissionsAndOwner ( Char *srcName, Char *dstName )
849 1143
850 1144
851/*---------------------------------------------*/ 1145/*---------------------------------------------*/
1146static
852void setInterimPermissions ( Char *dstName ) 1147void setInterimPermissions ( Char *dstName )
853{ 1148{
854#if BZ_UNIX 1149#if BZ_UNIX
@@ -860,6 +1155,7 @@ void setInterimPermissions ( Char *dstName )
860 1155
861 1156
862/*---------------------------------------------*/ 1157/*---------------------------------------------*/
1158static
863Bool containsDubiousChars ( Char* name ) 1159Bool containsDubiousChars ( Char* name )
864{ 1160{
865 Bool cdc = False; 1161 Bool cdc = False;
@@ -877,6 +1173,7 @@ Char* zSuffix[BZ_N_SUFFIX_PAIRS]
877Char* unzSuffix[BZ_N_SUFFIX_PAIRS] 1173Char* unzSuffix[BZ_N_SUFFIX_PAIRS]
878 = { "", "", ".tar", ".tar" }; 1174 = { "", "", ".tar", ".tar" };
879 1175
1176static
880Bool hasSuffix ( Char* s, Char* suffix ) 1177Bool hasSuffix ( Char* s, Char* suffix )
881{ 1178{
882 Int32 ns = strlen(s); 1179 Int32 ns = strlen(s);
@@ -886,6 +1183,7 @@ Bool hasSuffix ( Char* s, Char* suffix )
886 return False; 1183 return False;
887} 1184}
888 1185
1186static
889Bool mapSuffix ( Char* name, 1187Bool mapSuffix ( Char* name,
890 Char* oldSuffix, Char* newSuffix ) 1188 Char* oldSuffix, Char* newSuffix )
891{ 1189{
@@ -897,11 +1195,15 @@ Bool mapSuffix ( Char* name,
897 1195
898 1196
899/*---------------------------------------------*/ 1197/*---------------------------------------------*/
1198static
900void compress ( Char *name ) 1199void compress ( Char *name )
901{ 1200{
902 FILE *inStr; 1201 FILE *inStr;
903 FILE *outStr; 1202 FILE *outStr;
904 Int32 n, i; 1203 Int32 n, i;
1204
1205 deleteOutputOnInterrupt = False;
1206
905 if (name == NULL && srcMode != SM_I2O) 1207 if (name == NULL && srcMode != SM_I2O)
906 panic ( "compress: bad modes\n" ); 1208 panic ( "compress: bad modes\n" );
907 1209
@@ -924,12 +1226,14 @@ void compress ( Char *name )
924 if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) { 1226 if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
925 if (noisy) 1227 if (noisy)
926 fprintf ( stderr, "%s: There are no files matching `%s'.\n", 1228 fprintf ( stderr, "%s: There are no files matching `%s'.\n",
927 progName, inName ); 1229 progName, inName );
1230 setExit(1);
928 return; 1231 return;
929 } 1232 }
930 if ( srcMode != SM_I2O && !fileExists ( inName ) ) { 1233 if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
931 fprintf ( stderr, "%s: Can't open input file %s: %s.\n", 1234 fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
932 progName, inName, strerror(errno) ); 1235 progName, inName, strerror(errno) );
1236 setExit(1);
933 return; 1237 return;
934 } 1238 }
935 for (i = 0; i < BZ_N_SUFFIX_PAIRS; i++) { 1239 for (i = 0; i < BZ_N_SUFFIX_PAIRS; i++) {
@@ -938,6 +1242,7 @@ void compress ( Char *name )
938 fprintf ( stderr, 1242 fprintf ( stderr,
939 "%s: Input file %s already has %s suffix.\n", 1243 "%s: Input file %s already has %s suffix.\n",
940 progName, inName, zSuffix[i] ); 1244 progName, inName, zSuffix[i] );
1245 setExit(1);
941 return; 1246 return;
942 } 1247 }
943 } 1248 }
@@ -945,17 +1250,20 @@ void compress ( Char *name )
945 if (noisy) 1250 if (noisy)
946 fprintf ( stderr, "%s: Input file %s is not a normal file.\n", 1251 fprintf ( stderr, "%s: Input file %s is not a normal file.\n",
947 progName, inName ); 1252 progName, inName );
1253 setExit(1);
948 return; 1254 return;
949 } 1255 }
950 if ( srcMode == SM_F2F && !forceOverwrite && fileExists ( outName ) ) { 1256 if ( srcMode == SM_F2F && !forceOverwrite && fileExists ( outName ) ) {
951 fprintf ( stderr, "%s: Output file %s already exists.\n", 1257 fprintf ( stderr, "%s: Output file %s already exists.\n",
952 progName, outName ); 1258 progName, outName );
1259 setExit(1);
953 return; 1260 return;
954 } 1261 }
955 if ( srcMode == SM_F2F && !forceOverwrite && 1262 if ( srcMode == SM_F2F && !forceOverwrite &&
956 (n=countHardLinks ( inName )) > 0) { 1263 (n=countHardLinks ( inName )) > 0) {
957 fprintf ( stderr, "%s: Input file %s has %d other link%s.\n", 1264 fprintf ( stderr, "%s: Input file %s has %d other link%s.\n",
958 progName, inName, n, n > 1 ? "s" : "" ); 1265 progName, inName, n, n > 1 ? "s" : "" );
1266 setExit(1);
959 return; 1267 return;
960 } 1268 }
961 1269
@@ -970,6 +1278,7 @@ void compress ( Char *name )
970 progName ); 1278 progName );
971 fprintf ( stderr, "%s: For help, type: `%s --help'.\n", 1279 fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
972 progName, progName ); 1280 progName, progName );
1281 setExit(1);
973 return; 1282 return;
974 }; 1283 };
975 break; 1284 break;
@@ -984,11 +1293,13 @@ void compress ( Char *name )
984 fprintf ( stderr, "%s: For help, type: `%s --help'.\n", 1293 fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
985 progName, progName ); 1294 progName, progName );
986 if ( inStr != NULL ) fclose ( inStr ); 1295 if ( inStr != NULL ) fclose ( inStr );
1296 setExit(1);
987 return; 1297 return;
988 }; 1298 };
989 if ( inStr == NULL ) { 1299 if ( inStr == NULL ) {
990 fprintf ( stderr, "%s: Can't open input file %s: %s.\n", 1300 fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
991 progName, inName, strerror(errno) ); 1301 progName, inName, strerror(errno) );
1302 setExit(1);
992 return; 1303 return;
993 }; 1304 };
994 break; 1305 break;
@@ -1000,12 +1311,14 @@ void compress ( Char *name )
1000 fprintf ( stderr, "%s: Can't create output file %s: %s.\n", 1311 fprintf ( stderr, "%s: Can't create output file %s: %s.\n",
1001 progName, outName, strerror(errno) ); 1312 progName, outName, strerror(errno) );
1002 if ( inStr != NULL ) fclose ( inStr ); 1313 if ( inStr != NULL ) fclose ( inStr );
1314 setExit(1);
1003 return; 1315 return;
1004 } 1316 }
1005 if ( inStr == NULL ) { 1317 if ( inStr == NULL ) {
1006 fprintf ( stderr, "%s: Can't open input file %s: %s.\n", 1318 fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
1007 progName, inName, strerror(errno) ); 1319 progName, inName, strerror(errno) );
1008 if ( outStr != NULL ) fclose ( outStr ); 1320 if ( outStr != NULL ) fclose ( outStr );
1321 setExit(1);
1009 return; 1322 return;
1010 }; 1323 };
1011 setInterimPermissions ( outName ); 1324 setInterimPermissions ( outName );
@@ -1024,21 +1337,26 @@ void compress ( Char *name )
1024 1337
1025 /*--- Now the input and output handles are sane. Do the Biz. ---*/ 1338 /*--- Now the input and output handles are sane. Do the Biz. ---*/
1026 outputHandleJustInCase = outStr; 1339 outputHandleJustInCase = outStr;
1340 deleteOutputOnInterrupt = True;
1027 compressStream ( inStr, outStr ); 1341 compressStream ( inStr, outStr );
1028 outputHandleJustInCase = NULL; 1342 outputHandleJustInCase = NULL;
1029 1343
1030 /*--- If there was an I/O error, we won't get here. ---*/ 1344 /*--- If there was an I/O error, we won't get here. ---*/
1031 if ( srcMode == SM_F2F ) { 1345 if ( srcMode == SM_F2F ) {
1032 copyDatePermissionsAndOwner ( inName, outName ); 1346 copyDatePermissionsAndOwner ( inName, outName );
1347 deleteOutputOnInterrupt = False;
1033 if ( !keepInputFiles ) { 1348 if ( !keepInputFiles ) {
1034 IntNative retVal = remove ( inName ); 1349 IntNative retVal = remove ( inName );
1035 ERROR_IF_NOT_ZERO ( retVal ); 1350 ERROR_IF_NOT_ZERO ( retVal );
1036 } 1351 }
1037 } 1352 }
1353
1354 deleteOutputOnInterrupt = False;
1038} 1355}
1039 1356
1040 1357
1041/*---------------------------------------------*/ 1358/*---------------------------------------------*/
1359static
1042void uncompress ( Char *name ) 1360void uncompress ( Char *name )
1043{ 1361{
1044 FILE *inStr; 1362 FILE *inStr;
@@ -1047,6 +1365,8 @@ void uncompress ( Char *name )
1047 Bool magicNumberOK; 1365 Bool magicNumberOK;
1048 Bool cantGuess; 1366 Bool cantGuess;
1049 1367
1368 deleteOutputOnInterrupt = False;
1369
1050 if (name == NULL && srcMode != SM_I2O) 1370 if (name == NULL && srcMode != SM_I2O)
1051 panic ( "uncompress: bad modes\n" ); 1371 panic ( "uncompress: bad modes\n" );
1052 1372
@@ -1076,17 +1396,20 @@ void uncompress ( Char *name )
1076 if (noisy) 1396 if (noisy)
1077 fprintf ( stderr, "%s: There are no files matching `%s'.\n", 1397 fprintf ( stderr, "%s: There are no files matching `%s'.\n",
1078 progName, inName ); 1398 progName, inName );
1399 setExit(1);
1079 return; 1400 return;
1080 } 1401 }
1081 if ( srcMode != SM_I2O && !fileExists ( inName ) ) { 1402 if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
1082 fprintf ( stderr, "%s: Can't open input file %s: %s.\n", 1403 fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
1083 progName, inName, strerror(errno) ); 1404 progName, inName, strerror(errno) );
1405 setExit(1);
1084 return; 1406 return;
1085 } 1407 }
1086 if ( srcMode == SM_F2F && !forceOverwrite && notAStandardFile ( inName )) { 1408 if ( srcMode == SM_F2F && !forceOverwrite && notAStandardFile ( inName )) {
1087 if (noisy) 1409 if (noisy)
1088 fprintf ( stderr, "%s: Input file %s is not a normal file.\n", 1410 fprintf ( stderr, "%s: Input file %s is not a normal file.\n",
1089 progName, inName ); 1411 progName, inName );
1412 setExit(1);
1090 return; 1413 return;
1091 } 1414 }
1092 if ( /* srcMode == SM_F2F implied && */ cantGuess ) { 1415 if ( /* srcMode == SM_F2F implied && */ cantGuess ) {
@@ -1099,12 +1422,14 @@ void uncompress ( Char *name )
1099 if ( srcMode == SM_F2F && !forceOverwrite && fileExists ( outName ) ) { 1422 if ( srcMode == SM_F2F && !forceOverwrite && fileExists ( outName ) ) {
1100 fprintf ( stderr, "%s: Output file %s already exists.\n", 1423 fprintf ( stderr, "%s: Output file %s already exists.\n",
1101 progName, outName ); 1424 progName, outName );
1425 setExit(1);
1102 return; 1426 return;
1103 } 1427 }
1104 if ( srcMode == SM_F2F && !forceOverwrite && 1428 if ( srcMode == SM_F2F && !forceOverwrite &&
1105 (n=countHardLinks ( inName ) ) > 0) { 1429 (n=countHardLinks ( inName ) ) > 0) {
1106 fprintf ( stderr, "%s: Input file %s has %d other link%s.\n", 1430 fprintf ( stderr, "%s: Input file %s has %d other link%s.\n",
1107 progName, inName, n, n > 1 ? "s" : "" ); 1431 progName, inName, n, n > 1 ? "s" : "" );
1432 setExit(1);
1108 return; 1433 return;
1109 } 1434 }
1110 1435
@@ -1119,6 +1444,7 @@ void uncompress ( Char *name )
1119 progName ); 1444 progName );
1120 fprintf ( stderr, "%s: For help, type: `%s --help'.\n", 1445 fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
1121 progName, progName ); 1446 progName, progName );
1447 setExit(1);
1122 return; 1448 return;
1123 }; 1449 };
1124 break; 1450 break;
@@ -1130,6 +1456,7 @@ void uncompress ( Char *name )
1130 fprintf ( stderr, "%s: Can't open input file %s:%s.\n", 1456 fprintf ( stderr, "%s: Can't open input file %s:%s.\n",
1131 progName, inName, strerror(errno) ); 1457 progName, inName, strerror(errno) );
1132 if ( inStr != NULL ) fclose ( inStr ); 1458 if ( inStr != NULL ) fclose ( inStr );
1459 setExit(1);
1133 return; 1460 return;
1134 }; 1461 };
1135 break; 1462 break;
@@ -1141,12 +1468,14 @@ void uncompress ( Char *name )
1141 fprintf ( stderr, "%s: Can't create output file %s: %s.\n", 1468 fprintf ( stderr, "%s: Can't create output file %s: %s.\n",
1142 progName, outName, strerror(errno) ); 1469 progName, outName, strerror(errno) );
1143 if ( inStr != NULL ) fclose ( inStr ); 1470 if ( inStr != NULL ) fclose ( inStr );
1471 setExit(1);
1144 return; 1472 return;
1145 } 1473 }
1146 if ( inStr == NULL ) { 1474 if ( inStr == NULL ) {
1147 fprintf ( stderr, "%s: Can't open input file %s: %s.\n", 1475 fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
1148 progName, inName, strerror(errno) ); 1476 progName, inName, strerror(errno) );
1149 if ( outStr != NULL ) fclose ( outStr ); 1477 if ( outStr != NULL ) fclose ( outStr );
1478 setExit(1);
1150 return; 1479 return;
1151 }; 1480 };
1152 setInterimPermissions ( outName ); 1481 setInterimPermissions ( outName );
@@ -1165,6 +1494,7 @@ void uncompress ( Char *name )
1165 1494
1166 /*--- Now the input and output handles are sane. Do the Biz. ---*/ 1495 /*--- Now the input and output handles are sane. Do the Biz. ---*/
1167 outputHandleJustInCase = outStr; 1496 outputHandleJustInCase = outStr;
1497 deleteOutputOnInterrupt = True;
1168 magicNumberOK = uncompressStream ( inStr, outStr ); 1498 magicNumberOK = uncompressStream ( inStr, outStr );
1169 outputHandleJustInCase = NULL; 1499 outputHandleJustInCase = NULL;
1170 1500
@@ -1172,22 +1502,27 @@ void uncompress ( Char *name )
1172 if ( magicNumberOK ) { 1502 if ( magicNumberOK ) {
1173 if ( srcMode == SM_F2F ) { 1503 if ( srcMode == SM_F2F ) {
1174 copyDatePermissionsAndOwner ( inName, outName ); 1504 copyDatePermissionsAndOwner ( inName, outName );
1505 deleteOutputOnInterrupt = False;
1175 if ( !keepInputFiles ) { 1506 if ( !keepInputFiles ) {
1176 IntNative retVal = remove ( inName ); 1507 IntNative retVal = remove ( inName );
1177 ERROR_IF_NOT_ZERO ( retVal ); 1508 ERROR_IF_NOT_ZERO ( retVal );
1178 } 1509 }
1179 } 1510 }
1180 } else { 1511 } else {
1512 unzFailsExist = True;
1513 deleteOutputOnInterrupt = False;
1181 if ( srcMode == SM_F2F ) { 1514 if ( srcMode == SM_F2F ) {
1182 IntNative retVal = remove ( outName ); 1515 IntNative retVal = remove ( outName );
1183 ERROR_IF_NOT_ZERO ( retVal ); 1516 ERROR_IF_NOT_ZERO ( retVal );
1184 } 1517 }
1185 } 1518 }
1519 deleteOutputOnInterrupt = False;
1186 1520
1187 if ( magicNumberOK ) { 1521 if ( magicNumberOK ) {
1188 if (verbosity >= 1) 1522 if (verbosity >= 1)
1189 fprintf ( stderr, "done\n" ); 1523 fprintf ( stderr, "done\n" );
1190 } else { 1524 } else {
1525 setExit(2);
1191 if (verbosity >= 1) 1526 if (verbosity >= 1)
1192 fprintf ( stderr, "not a bzip2 file.\n" ); else 1527 fprintf ( stderr, "not a bzip2 file.\n" ); else
1193 fprintf ( stderr, 1528 fprintf ( stderr,
@@ -1199,11 +1534,14 @@ void uncompress ( Char *name )
1199 1534
1200 1535
1201/*---------------------------------------------*/ 1536/*---------------------------------------------*/
1537static
1202void testf ( Char *name ) 1538void testf ( Char *name )
1203{ 1539{
1204 FILE *inStr; 1540 FILE *inStr;
1205 Bool allOK; 1541 Bool allOK;
1206 1542
1543 deleteOutputOnInterrupt = False;
1544
1207 if (name == NULL && srcMode != SM_I2O) 1545 if (name == NULL && srcMode != SM_I2O)
1208 panic ( "testf: bad modes\n" ); 1546 panic ( "testf: bad modes\n" );
1209 1547
@@ -1218,11 +1556,13 @@ void testf ( Char *name )
1218 if (noisy) 1556 if (noisy)
1219 fprintf ( stderr, "%s: There are no files matching `%s'.\n", 1557 fprintf ( stderr, "%s: There are no files matching `%s'.\n",
1220 progName, inName ); 1558 progName, inName );
1559 setExit(1);
1221 return; 1560 return;
1222 } 1561 }
1223 if ( srcMode != SM_I2O && !fileExists ( inName ) ) { 1562 if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
1224 fprintf ( stderr, "%s: Can't open input %s: %s.\n", 1563 fprintf ( stderr, "%s: Can't open input %s: %s.\n",
1225 progName, inName, strerror(errno) ); 1564 progName, inName, strerror(errno) );
1565 setExit(1);
1226 return; 1566 return;
1227 } 1567 }
1228 1568
@@ -1235,6 +1575,7 @@ void testf ( Char *name )
1235 progName ); 1575 progName );
1236 fprintf ( stderr, "%s: For help, type: `%s --help'.\n", 1576 fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
1237 progName, progName ); 1577 progName, progName );
1578 setExit(1);
1238 return; 1579 return;
1239 }; 1580 };
1240 inStr = stdin; 1581 inStr = stdin;
@@ -1245,6 +1586,7 @@ void testf ( Char *name )
1245 if ( inStr == NULL ) { 1586 if ( inStr == NULL ) {
1246 fprintf ( stderr, "%s: Can't open input file %s:%s.\n", 1587 fprintf ( stderr, "%s: Can't open input file %s:%s.\n",
1247 progName, inName, strerror(errno) ); 1588 progName, inName, strerror(errno) );
1589 setExit(1);
1248 return; 1590 return;
1249 }; 1591 };
1250 break; 1592 break;
@@ -1269,35 +1611,38 @@ void testf ( Char *name )
1269 1611
1270 1612
1271/*---------------------------------------------*/ 1613/*---------------------------------------------*/
1614static
1272void license ( void ) 1615void license ( void )
1273{ 1616{
1274 fprintf ( stderr, 1617 fprintf ( stderr,
1275 1618
1276 "bzip2, a block-sorting file compressor. " 1619 "bzip2, a block-sorting file compressor. "
1277 "Version 0.9.5d, 4-Sept-99.\n" 1620 "Version %s.\n"
1278 " \n" 1621 " \n"
1279 " Copyright (C) 1996, 1997, 1998, 1999 by Julian Seward.\n" 1622 " Copyright (C) 1996-2000 by Julian Seward.\n"
1280 " \n" 1623 " \n"
1281 " This program is free software; you can redistribute it and/or modify\n" 1624 " This program is free software; you can redistribute it and/or modify\n"
1282 " it under the terms set out in the LICENSE file, which is included\n" 1625 " it under the terms set out in the LICENSE file, which is included\n"
1283 " in the bzip2-0.9.5 source distribution.\n" 1626 " in the bzip2-1.0 source distribution.\n"
1284 " \n" 1627 " \n"
1285 " This program is distributed in the hope that it will be useful,\n" 1628 " This program is distributed in the hope that it will be useful,\n"
1286 " but WITHOUT ANY WARRANTY; without even the implied warranty of\n" 1629 " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
1287 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" 1630 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
1288 " LICENSE file for more details.\n" 1631 " LICENSE file for more details.\n"
1289 " \n" 1632 " \n",
1633 BZ2_bzlibVersion()
1290 ); 1634 );
1291} 1635}
1292 1636
1293 1637
1294/*---------------------------------------------*/ 1638/*---------------------------------------------*/
1639static
1295void usage ( Char *fullProgName ) 1640void usage ( Char *fullProgName )
1296{ 1641{
1297 fprintf ( 1642 fprintf (
1298 stderr, 1643 stderr,
1299 "bzip2, a block-sorting file compressor. " 1644 "bzip2, a block-sorting file compressor. "
1300 "Version 0.9.5d, 4-Sept-99.\n" 1645 "Version %s.\n"
1301 "\n usage: %s [flags and input files in any order]\n" 1646 "\n usage: %s [flags and input files in any order]\n"
1302 "\n" 1647 "\n"
1303 " -h --help print this message\n" 1648 " -h --help print this message\n"
@@ -1326,12 +1671,14 @@ void usage ( Char *fullProgName )
1326#endif 1671#endif
1327 , 1672 ,
1328 1673
1674 BZ2_bzlibVersion(),
1329 fullProgName 1675 fullProgName
1330 ); 1676 );
1331} 1677}
1332 1678
1333 1679
1334/*---------------------------------------------*/ 1680/*---------------------------------------------*/
1681static
1335void redundant ( Char* flag ) 1682void redundant ( Char* flag )
1336{ 1683{
1337 fprintf ( 1684 fprintf (
@@ -1365,6 +1712,7 @@ typedef
1365 1712
1366 1713
1367/*---------------------------------------------*/ 1714/*---------------------------------------------*/
1715static
1368void *myMalloc ( Int32 n ) 1716void *myMalloc ( Int32 n )
1369{ 1717{
1370 void* p; 1718 void* p;
@@ -1376,6 +1724,7 @@ void *myMalloc ( Int32 n )
1376 1724
1377 1725
1378/*---------------------------------------------*/ 1726/*---------------------------------------------*/
1727static
1379Cell *mkCell ( void ) 1728Cell *mkCell ( void )
1380{ 1729{
1381 Cell *c; 1730 Cell *c;
@@ -1388,6 +1737,7 @@ Cell *mkCell ( void )
1388 1737
1389 1738
1390/*---------------------------------------------*/ 1739/*---------------------------------------------*/
1740static
1391Cell *snocString ( Cell *root, Char *name ) 1741Cell *snocString ( Cell *root, Char *name )
1392{ 1742{
1393 if (root == NULL) { 1743 if (root == NULL) {
@@ -1405,6 +1755,7 @@ Cell *snocString ( Cell *root, Char *name )
1405 1755
1406 1756
1407/*---------------------------------------------*/ 1757/*---------------------------------------------*/
1758static
1408void addFlagsFromEnvVar ( Cell** argList, Char* varName ) 1759void addFlagsFromEnvVar ( Cell** argList, Char* varName )
1409{ 1760{
1410 Int32 i, j, k; 1761 Int32 i, j, k;
@@ -1445,16 +1796,8 @@ IntNative main ( IntNative argc, Char *argv[] )
1445 /*-- Be really really really paranoid :-) --*/ 1796 /*-- Be really really really paranoid :-) --*/
1446 if (sizeof(Int32) != 4 || sizeof(UInt32) != 4 || 1797 if (sizeof(Int32) != 4 || sizeof(UInt32) != 4 ||
1447 sizeof(Int16) != 2 || sizeof(UInt16) != 2 || 1798 sizeof(Int16) != 2 || sizeof(UInt16) != 2 ||
1448 sizeof(Char) != 1 || sizeof(UChar) != 1) { 1799 sizeof(Char) != 1 || sizeof(UChar) != 1)
1449 fprintf ( stderr, 1800 configError();
1450 "bzip2: I'm not configured correctly for this platform!\n"
1451 "\tI require Int32, Int16 and Char to have sizes\n"
1452 "\tof 4, 2 and 1 bytes to run properly, and they don't.\n"
1453 "\tProbably you can fix this by defining them correctly,\n"
1454 "\tand recompiling. Bye!\n" );
1455 exit(3);
1456 }
1457
1458 1801
1459 /*-- Initialise --*/ 1802 /*-- Initialise --*/
1460 outputHandleJustInCase = NULL; 1803 outputHandleJustInCase = NULL;
@@ -1465,9 +1808,12 @@ IntNative main ( IntNative argc, Char *argv[] )
1465 verbosity = 0; 1808 verbosity = 0;
1466 blockSize100k = 9; 1809 blockSize100k = 9;
1467 testFailsExist = False; 1810 testFailsExist = False;
1811 unzFailsExist = False;
1468 numFileNames = 0; 1812 numFileNames = 0;
1469 numFilesProcessed = 0; 1813 numFilesProcessed = 0;
1470 workFactor = 30; 1814 workFactor = 30;
1815 deleteOutputOnInterrupt = False;
1816 exitValue = 0;
1471 i = j = 0; /* avoid bogus warning from egcs-1.1.X */ 1817 i = j = 0; /* avoid bogus warning from egcs-1.1.X */
1472 1818
1473 /*-- Set up signal handlers for mem access errors --*/ 1819 /*-- Set up signal handlers for mem access errors --*/
@@ -1636,6 +1982,7 @@ IntNative main ( IntNative argc, Char *argv[] )
1636 else 1982 else
1637 1983
1638 if (opMode == OM_UNZ) { 1984 if (opMode == OM_UNZ) {
1985 unzFailsExist = False;
1639 if (srcMode == SM_I2O) { 1986 if (srcMode == SM_I2O) {
1640 uncompress ( NULL ); 1987 uncompress ( NULL );
1641 } else { 1988 } else {
@@ -1647,6 +1994,10 @@ IntNative main ( IntNative argc, Char *argv[] )
1647 uncompress ( aa->name ); 1994 uncompress ( aa->name );
1648 } 1995 }
1649 } 1996 }
1997 if (unzFailsExist) {
1998 setExit(2);
1999 exit(exitValue);
2000 }
1650 } 2001 }
1651 2002
1652 else { 2003 else {
@@ -1668,7 +2019,8 @@ IntNative main ( IntNative argc, Char *argv[] )
1668 "You can use the `bzip2recover' program to attempt to recover\n" 2019 "You can use the `bzip2recover' program to attempt to recover\n"
1669 "data from undamaged sections of corrupted files.\n\n" 2020 "data from undamaged sections of corrupted files.\n\n"
1670 ); 2021 );
1671 exit(2); 2022 setExit(2);
2023 exit(exitValue);
1672 } 2024 }
1673 } 2025 }
1674 2026
@@ -1678,12 +2030,12 @@ IntNative main ( IntNative argc, Char *argv[] )
1678 aa = argList; 2030 aa = argList;
1679 while (aa != NULL) { 2031 while (aa != NULL) {
1680 Cell* aa2 = aa->link; 2032 Cell* aa2 = aa->link;
1681 if (aa->name) free(aa->name); 2033 if (aa->name != NULL) free(aa->name);
1682 free(aa); 2034 free(aa);
1683 aa = aa2; 2035 aa = aa2;
1684 } 2036 }
1685 2037
1686 return 0; 2038 return exitValue;
1687} 2039}
1688 2040
1689 2041