summaryrefslogtreecommitdiffstats
path: root/bzip2.c
diff options
context:
space:
mode:
authorJulian Seward <jseward@acm.org>2006-12-20 22:13:13 +0100
committerJulian Seward <jseward@acm.org>2006-12-20 22:13:13 +0100
commitf10a33538e9bab6deb61779b3d8aae168824ef48 (patch)
treeecd1c2ed553ced58a090e0d8b7b7a20bb7c95c80 /bzip2.c
parentbzip2-1.0.3 (diff)
downloadbzip2-f10a33538e9bab6deb61779b3d8aae168824ef48.tar.gz
bzip2-f10a33538e9bab6deb61779b3d8aae168824ef48.tar.bz2
bzip2-f10a33538e9bab6deb61779b3d8aae168824ef48.tar.xz
bzip2-1.0.4bzip2-1.0.4
Diffstat (limited to 'bzip2.c')
-rw-r--r--bzip2.c205
1 files changed, 66 insertions, 139 deletions
diff --git a/bzip2.c b/bzip2.c
index 79f87a5..5fbae0e 100644
--- a/bzip2.c
+++ b/bzip2.c
@@ -3,118 +3,26 @@
3/*--- A block-sorting, lossless compressor bzip2.c ---*/ 3/*--- A block-sorting, lossless compressor bzip2.c ---*/
4/*-----------------------------------------------------------*/ 4/*-----------------------------------------------------------*/
5 5
6/*-- 6/* ------------------------------------------------------------------
7 This file is a part of bzip2 and/or libbzip2, a program and 7 This file is part of bzip2/libbzip2, a program and library for
8 library for lossless, block-sorting data compression. 8 lossless, block-sorting data compression.
9
10 Copyright (C) 1996-2005 Julian R Seward. All rights reserved.
11
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions
14 are met:
15
16 1. Redistributions of source code must retain the above copyright
17 notice, this list of conditions and the following disclaimer.
18
19 2. The origin of this software must not be misrepresented; you must
20 not claim that you wrote the original software. If you use this
21 software in a product, an acknowledgment in the product
22 documentation would be appreciated but is not required.
23
24 3. Altered source versions must be plainly marked as such, and must
25 not be misrepresented as being the original software.
26
27 4. The name of the author may not be used to endorse or promote
28 products derived from this software without specific prior written
29 permission.
30
31 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
32 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
33 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
35 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
37 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
38 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
39 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
40 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42
43 Julian Seward, Cambridge, UK.
44 jseward@bzip.org
45 bzip2/libbzip2 version 1.0 of 21 March 2000
46
47 This program is based on (at least) the work of:
48 Mike Burrows
49 David Wheeler
50 Peter Fenwick
51 Alistair Moffat
52 Radford Neal
53 Ian H. Witten
54 Robert Sedgewick
55 Jon L. Bentley
56
57 For more information on these sources, see the manual.
58--*/
59 9
10 bzip2/libbzip2 version 1.0.4 of 20 December 2006
11 Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
60 12
61/*----------------------------------------------------*/ 13 Please read the WARNING, DISCLAIMER and PATENTS sections in the
62/*--- IMPORTANT ---*/ 14 README file.
63/*----------------------------------------------------*/
64 15
65/*-- 16 This program is released under the terms of the license contained
66 WARNING: 17 in the file LICENSE.
67 This program and library (attempts to) compress data by 18 ------------------------------------------------------------------ */
68 performing several non-trivial transformations on it.
69 Unless you are 100% familiar with *all* the algorithms
70 contained herein, and with the consequences of modifying them,
71 you should NOT meddle with the compression or decompression
72 machinery. Incorrect changes can and very likely *will*
73 lead to disasterous loss of data.
74
75 DISCLAIMER:
76 I TAKE NO RESPONSIBILITY FOR ANY LOSS OF DATA ARISING FROM THE
77 USE OF THIS PROGRAM, HOWSOEVER CAUSED.
78
79 Every compression of a file implies an assumption that the
80 compressed file can be decompressed to reproduce the original.
81 Great efforts in design, coding and testing have been made to
82 ensure that this program works correctly. However, the
83 complexity of the algorithms, and, in particular, the presence
84 of various special cases in the code which occur with very low
85 but non-zero probability make it impossible to rule out the
86 possibility of bugs remaining in the program. DO NOT COMPRESS
87 ANY DATA WITH THIS PROGRAM AND/OR LIBRARY UNLESS YOU ARE PREPARED
88 TO ACCEPT THE POSSIBILITY, HOWEVER SMALL, THAT THE DATA WILL
89 NOT BE RECOVERABLE.
90
91 That is not to say this program is inherently unreliable.
92 Indeed, I very much hope the opposite is true. bzip2/libbzip2
93 has been carefully constructed and extensively tested.
94
95 PATENTS:
96 To the best of my knowledge, bzip2/libbzip2 does not use any
97 patented algorithms. However, I do not have the resources
98 available to carry out a full patent search. Therefore I cannot
99 give any guarantee of the above statement.
100--*/
101 19
102 20
103 21/* Place a 1 beside your platform, and 0 elsewhere.
104/*----------------------------------------------------*/ 22 Generic 32-bit Unix.
105/*--- and now for something much more pleasant :-) ---*/ 23 Also works on 64-bit Unix boxes.
106/*----------------------------------------------------*/ 24 This is the default.
107 25*/
108/*---------------------------------------------*/
109/*--
110 Place a 1 beside your platform, and 0 elsewhere.
111--*/
112
113/*--
114 Generic 32-bit Unix.
115 Also works on 64-bit Unix boxes.
116 This is the default.
117--*/
118#define BZ_UNIX 1 26#define BZ_UNIX 1
119 27
120/*-- 28/*--
@@ -302,16 +210,17 @@ Char progNameReally[FILE_NAME_LEN];
302FILE *outputHandleJustInCase; 210FILE *outputHandleJustInCase;
303Int32 workFactor; 211Int32 workFactor;
304 212
305static void panic ( Char* ) NORETURN; 213static void panic ( const Char* ) NORETURN;
306static void ioError ( void ) NORETURN; 214static void ioError ( void ) NORETURN;
307static void outOfMemory ( void ) NORETURN; 215static void outOfMemory ( void ) NORETURN;
308static void configError ( void ) NORETURN; 216static void configError ( void ) NORETURN;
309static void crcError ( void ) NORETURN; 217static void crcError ( void ) NORETURN;
310static void cleanUpAndFail ( Int32 ) NORETURN; 218static void cleanUpAndFail ( Int32 ) NORETURN;
311static void compressedStreamEOF ( void ) NORETURN; 219static void compressedStreamEOF ( void ) NORETURN;
312 220
313static void copyFileName ( Char*, Char* ); 221static void copyFileName ( Char*, Char* );
314static void* myMalloc ( Int32 ); 222static void* myMalloc ( Int32 );
223static void applySavedFileAttrToOutputFile ( IntNative fd );
315 224
316 225
317 226
@@ -457,6 +366,9 @@ void compressStream ( FILE *stream, FILE *zStream )
457 ret = fflush ( zStream ); 366 ret = fflush ( zStream );
458 if (ret == EOF) goto errhandler_io; 367 if (ret == EOF) goto errhandler_io;
459 if (zStream != stdout) { 368 if (zStream != stdout) {
369 Int32 fd = fileno ( zStream );
370 if (fd < 0) goto errhandler_io;
371 applySavedFileAttrToOutputFile ( fd );
460 ret = fclose ( zStream ); 372 ret = fclose ( zStream );
461 outputHandleJustInCase = NULL; 373 outputHandleJustInCase = NULL;
462 if (ret == EOF) goto errhandler_io; 374 if (ret == EOF) goto errhandler_io;
@@ -569,6 +481,11 @@ Bool uncompressStream ( FILE *zStream, FILE *stream )
569 481
570 closeok: 482 closeok:
571 if (ferror(zStream)) goto errhandler_io; 483 if (ferror(zStream)) goto errhandler_io;
484 if (stream != stdout) {
485 Int32 fd = fileno ( stream );
486 if (fd < 0) goto errhandler_io;
487 applySavedFileAttrToOutputFile ( fd );
488 }
572 ret = fclose ( zStream ); 489 ret = fclose ( zStream );
573 if (ret == EOF) goto errhandler_io; 490 if (ret == EOF) goto errhandler_io;
574 491
@@ -826,7 +743,7 @@ void cleanUpAndFail ( Int32 ec )
826 743
827/*---------------------------------------------*/ 744/*---------------------------------------------*/
828static 745static
829void panic ( Char* s ) 746void panic ( const Char* s )
830{ 747{
831 fprintf ( stderr, 748 fprintf ( stderr,
832 "\n%s: PANIC -- internal consistency error:\n" 749 "\n%s: PANIC -- internal consistency error:\n"
@@ -1039,6 +956,7 @@ Bool fileExists ( Char* name )
1039 For non-Unix platforms, if we are not worrying about 956 For non-Unix platforms, if we are not worrying about
1040 security issues, simple this simply behaves like fopen. 957 security issues, simple this simply behaves like fopen.
1041*/ 958*/
959static
1042FILE* fopen_output_safely ( Char* name, const char* mode ) 960FILE* fopen_output_safely ( Char* name, const char* mode )
1043{ 961{
1044# if BZ_UNIX 962# if BZ_UNIX
@@ -1129,7 +1047,7 @@ void saveInputFileMetaInfo ( Char *srcName )
1129 1047
1130 1048
1131static 1049static
1132void applySavedMetaInfoToOutputFile ( Char *dstName ) 1050void applySavedTimeInfoToOutputFile ( Char *dstName )
1133{ 1051{
1134# if BZ_UNIX 1052# if BZ_UNIX
1135 IntNative retVal; 1053 IntNative retVal;
@@ -1138,13 +1056,21 @@ void applySavedMetaInfoToOutputFile ( Char *dstName )
1138 uTimBuf.actime = fileMetaInfo.st_atime; 1056 uTimBuf.actime = fileMetaInfo.st_atime;
1139 uTimBuf.modtime = fileMetaInfo.st_mtime; 1057 uTimBuf.modtime = fileMetaInfo.st_mtime;
1140 1058
1141 retVal = chmod ( dstName, fileMetaInfo.st_mode ); 1059 retVal = utime ( dstName, &uTimBuf );
1142 ERROR_IF_NOT_ZERO ( retVal ); 1060 ERROR_IF_NOT_ZERO ( retVal );
1061# endif
1062}
1143 1063
1144 retVal = utime ( dstName, &uTimBuf ); 1064static
1065void applySavedFileAttrToOutputFile ( IntNative fd )
1066{
1067# if BZ_UNIX
1068 IntNative retVal;
1069
1070 retVal = fchmod ( fd, fileMetaInfo.st_mode );
1145 ERROR_IF_NOT_ZERO ( retVal ); 1071 ERROR_IF_NOT_ZERO ( retVal );
1146 1072
1147 retVal = chown ( dstName, fileMetaInfo.st_uid, fileMetaInfo.st_gid ); 1073 (void) fchown ( fd, fileMetaInfo.st_uid, fileMetaInfo.st_gid );
1148 /* chown() will in many cases return with EPERM, which can 1074 /* chown() will in many cases return with EPERM, which can
1149 be safely ignored. 1075 be safely ignored.
1150 */ 1076 */
@@ -1175,13 +1101,13 @@ Bool containsDubiousChars ( Char* name )
1175/*---------------------------------------------*/ 1101/*---------------------------------------------*/
1176#define BZ_N_SUFFIX_PAIRS 4 1102#define BZ_N_SUFFIX_PAIRS 4
1177 1103
1178Char* zSuffix[BZ_N_SUFFIX_PAIRS] 1104const Char* zSuffix[BZ_N_SUFFIX_PAIRS]
1179 = { ".bz2", ".bz", ".tbz2", ".tbz" }; 1105 = { ".bz2", ".bz", ".tbz2", ".tbz" };
1180Char* unzSuffix[BZ_N_SUFFIX_PAIRS] 1106const Char* unzSuffix[BZ_N_SUFFIX_PAIRS]
1181 = { "", "", ".tar", ".tar" }; 1107 = { "", "", ".tar", ".tar" };
1182 1108
1183static 1109static
1184Bool hasSuffix ( Char* s, Char* suffix ) 1110Bool hasSuffix ( Char* s, const Char* suffix )
1185{ 1111{
1186 Int32 ns = strlen(s); 1112 Int32 ns = strlen(s);
1187 Int32 nx = strlen(suffix); 1113 Int32 nx = strlen(suffix);
@@ -1192,7 +1118,8 @@ Bool hasSuffix ( Char* s, Char* suffix )
1192 1118
1193static 1119static
1194Bool mapSuffix ( Char* name, 1120Bool mapSuffix ( Char* name,
1195 Char* oldSuffix, Char* newSuffix ) 1121 const Char* oldSuffix,
1122 const Char* newSuffix )
1196{ 1123{
1197 if (!hasSuffix(name,oldSuffix)) return False; 1124 if (!hasSuffix(name,oldSuffix)) return False;
1198 name[strlen(name)-strlen(oldSuffix)] = 0; 1125 name[strlen(name)-strlen(oldSuffix)] = 0;
@@ -1217,8 +1144,8 @@ void compress ( Char *name )
1217 1144
1218 switch (srcMode) { 1145 switch (srcMode) {
1219 case SM_I2O: 1146 case SM_I2O:
1220 copyFileName ( inName, "(stdin)" ); 1147 copyFileName ( inName, (Char*)"(stdin)" );
1221 copyFileName ( outName, "(stdout)" ); 1148 copyFileName ( outName, (Char*)"(stdout)" );
1222 break; 1149 break;
1223 case SM_F2F: 1150 case SM_F2F:
1224 copyFileName ( inName, name ); 1151 copyFileName ( inName, name );
@@ -1227,7 +1154,7 @@ void compress ( Char *name )
1227 break; 1154 break;
1228 case SM_F2O: 1155 case SM_F2O:
1229 copyFileName ( inName, name ); 1156 copyFileName ( inName, name );
1230 copyFileName ( outName, "(stdout)" ); 1157 copyFileName ( outName, (Char*)"(stdout)" );
1231 break; 1158 break;
1232 } 1159 }
1233 1160
@@ -1370,7 +1297,7 @@ void compress ( Char *name )
1370 1297
1371 /*--- If there was an I/O error, we won't get here. ---*/ 1298 /*--- If there was an I/O error, we won't get here. ---*/
1372 if ( srcMode == SM_F2F ) { 1299 if ( srcMode == SM_F2F ) {
1373 applySavedMetaInfoToOutputFile ( outName ); 1300 applySavedTimeInfoToOutputFile ( outName );
1374 deleteOutputOnInterrupt = False; 1301 deleteOutputOnInterrupt = False;
1375 if ( !keepInputFiles ) { 1302 if ( !keepInputFiles ) {
1376 IntNative retVal = remove ( inName ); 1303 IntNative retVal = remove ( inName );
@@ -1401,8 +1328,8 @@ void uncompress ( Char *name )
1401 cantGuess = False; 1328 cantGuess = False;
1402 switch (srcMode) { 1329 switch (srcMode) {
1403 case SM_I2O: 1330 case SM_I2O:
1404 copyFileName ( inName, "(stdin)" ); 1331 copyFileName ( inName, (Char*)"(stdin)" );
1405 copyFileName ( outName, "(stdout)" ); 1332 copyFileName ( outName, (Char*)"(stdout)" );
1406 break; 1333 break;
1407 case SM_F2F: 1334 case SM_F2F:
1408 copyFileName ( inName, name ); 1335 copyFileName ( inName, name );
@@ -1415,7 +1342,7 @@ void uncompress ( Char *name )
1415 break; 1342 break;
1416 case SM_F2O: 1343 case SM_F2O:
1417 copyFileName ( inName, name ); 1344 copyFileName ( inName, name );
1418 copyFileName ( outName, "(stdout)" ); 1345 copyFileName ( outName, (Char*)"(stdout)" );
1419 break; 1346 break;
1420 } 1347 }
1421 1348
@@ -1548,7 +1475,7 @@ void uncompress ( Char *name )
1548 /*--- If there was an I/O error, we won't get here. ---*/ 1475 /*--- If there was an I/O error, we won't get here. ---*/
1549 if ( magicNumberOK ) { 1476 if ( magicNumberOK ) {
1550 if ( srcMode == SM_F2F ) { 1477 if ( srcMode == SM_F2F ) {
1551 applySavedMetaInfoToOutputFile ( outName ); 1478 applySavedTimeInfoToOutputFile ( outName );
1552 deleteOutputOnInterrupt = False; 1479 deleteOutputOnInterrupt = False;
1553 if ( !keepInputFiles ) { 1480 if ( !keepInputFiles ) {
1554 IntNative retVal = remove ( inName ); 1481 IntNative retVal = remove ( inName );
@@ -1593,9 +1520,9 @@ void testf ( Char *name )
1593 if (name == NULL && srcMode != SM_I2O) 1520 if (name == NULL && srcMode != SM_I2O)
1594 panic ( "testf: bad modes\n" ); 1521 panic ( "testf: bad modes\n" );
1595 1522
1596 copyFileName ( outName, "(none)" ); 1523 copyFileName ( outName, (Char*)"(none)" );
1597 switch (srcMode) { 1524 switch (srcMode) {
1598 case SM_I2O: copyFileName ( inName, "(stdin)" ); break; 1525 case SM_I2O: copyFileName ( inName, (Char*)"(stdin)" ); break;
1599 case SM_F2F: copyFileName ( inName, name ); break; 1526 case SM_F2F: copyFileName ( inName, name ); break;
1600 case SM_F2O: copyFileName ( inName, name ); break; 1527 case SM_F2O: copyFileName ( inName, name ); break;
1601 } 1528 }
@@ -1678,11 +1605,11 @@ void license ( void )
1678 "bzip2, a block-sorting file compressor. " 1605 "bzip2, a block-sorting file compressor. "
1679 "Version %s.\n" 1606 "Version %s.\n"
1680 " \n" 1607 " \n"
1681 " Copyright (C) 1996-2005 by Julian Seward.\n" 1608 " Copyright (C) 1996-2006 by Julian Seward.\n"
1682 " \n" 1609 " \n"
1683 " This program is free software; you can redistribute it and/or modify\n" 1610 " This program is free software; you can redistribute it and/or modify\n"
1684 " it under the terms set out in the LICENSE file, which is included\n" 1611 " it under the terms set out in the LICENSE file, which is included\n"
1685 " in the bzip2-1.0 source distribution.\n" 1612 " in the bzip2-1.0.4 source distribution.\n"
1686 " \n" 1613 " \n"
1687 " This program is distributed in the hope that it will be useful,\n" 1614 " This program is distributed in the hope that it will be useful,\n"
1688 " but WITHOUT ANY WARRANTY; without even the implied warranty of\n" 1615 " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
@@ -1885,8 +1812,8 @@ IntNative main ( IntNative argc, Char *argv[] )
1885# endif 1812# endif
1886# endif 1813# endif
1887 1814
1888 copyFileName ( inName, "(none)" ); 1815 copyFileName ( inName, (Char*)"(none)" );
1889 copyFileName ( outName, "(none)" ); 1816 copyFileName ( outName, (Char*)"(none)" );
1890 1817
1891 copyFileName ( progNameReally, argv[0] ); 1818 copyFileName ( progNameReally, argv[0] );
1892 progName = &progNameReally[0]; 1819 progName = &progNameReally[0];
@@ -1898,8 +1825,8 @@ IntNative main ( IntNative argc, Char *argv[] )
1898 expand filename wildcards in arg list. 1825 expand filename wildcards in arg list.
1899 --*/ 1826 --*/
1900 argList = NULL; 1827 argList = NULL;
1901 addFlagsFromEnvVar ( &argList, "BZIP2" ); 1828 addFlagsFromEnvVar ( &argList, (Char*)"BZIP2" );
1902 addFlagsFromEnvVar ( &argList, "BZIP" ); 1829 addFlagsFromEnvVar ( &argList, (Char*)"BZIP" );
1903 for (i = 1; i <= argc-1; i++) 1830 for (i = 1; i <= argc-1; i++)
1904 APPEND_FILESPEC(argList, argv[i]); 1831 APPEND_FILESPEC(argList, argv[i]);
1905 1832