1*b30d1939SAndy Fiddaman /*
2*b30d1939SAndy Fiddaman * ratz -- read a tar gzip archive from the standard input
3*b30d1939SAndy Fiddaman *
4*b30d1939SAndy Fiddaman * coded for portability
5*b30d1939SAndy Fiddaman * _SEAR_* macros for win32 self extracting archives -- see sear(1).
6*b30d1939SAndy Fiddaman */
7*b30d1939SAndy Fiddaman
8*b30d1939SAndy Fiddaman static char id[] = "\n@(#)$Id: ratz (Jean-loup Gailly, Mark Adler, Glenn Fowler) 1.2.3 2010-10-10 $\0\n";
9*b30d1939SAndy Fiddaman
10*b30d1939SAndy Fiddaman #if _PACKAGE_ast
11*b30d1939SAndy Fiddaman
12*b30d1939SAndy Fiddaman #include <ast.h>
13*b30d1939SAndy Fiddaman #include <error.h>
14*b30d1939SAndy Fiddaman
15*b30d1939SAndy Fiddaman static const char usage[] =
16*b30d1939SAndy Fiddaman "[-?\n@(#)$Id: ratz (Jean-loup Gailly, Mark Adler, Glenn Fowler) 1.2.3 2010-10-10 $\n]"
17*b30d1939SAndy Fiddaman "[-author?Jean-loup Gailly]"
18*b30d1939SAndy Fiddaman "[-author?Mark Adler]"
19*b30d1939SAndy Fiddaman "[-author?Glenn Fowler <gsf@research.att.com>]"
20*b30d1939SAndy Fiddaman "[-copyright?Copyright (c) 1995-2005 Jean-loup Gailly and Mark Adler]"
21*b30d1939SAndy Fiddaman "[-license?http://www.opensource.org/licenses/zlib-license]"
22*b30d1939SAndy Fiddaman "[+NAME?ratz - read a tar gzip archive]"
23*b30d1939SAndy Fiddaman "[+DESCRIPTION?\bratz\b extracts files and directories from a tar gzip"
24*b30d1939SAndy Fiddaman " archive on the standard input. It is a standalone program for systems"
25*b30d1939SAndy Fiddaman " that do not have \bpax\b(1), \btar\b(1) or \bgunzip\b(1). Only regular"
26*b30d1939SAndy Fiddaman " files and directories are extracted; all other file types are ignored.]"
27*b30d1939SAndy Fiddaman "[+?\b.exe\b files generated by \bsear\b(1) are fully functional \bratz\b"
28*b30d1939SAndy Fiddaman " executables, so any \bratz\b option may be used on a \bsear\b file."
29*b30d1939SAndy Fiddaman " This allows \bsear\b file contents to be examined and extracted without"
30*b30d1939SAndy Fiddaman " executing any embedded installation scripts.]"
31*b30d1939SAndy Fiddaman "[c:cat|uncompress?Uncompress the standard input and copy it to the standard"
32*b30d1939SAndy Fiddaman " output.]"
33*b30d1939SAndy Fiddaman #if defined(_SEAR_EXEC) || defined(_SEAR_SEEK)
34*b30d1939SAndy Fiddaman "[i!:install?Execute the sear installation script.]"
35*b30d1939SAndy Fiddaman "[k:keep?Keep the installation temporary directory.]"
36*b30d1939SAndy Fiddaman #endif
37*b30d1939SAndy Fiddaman "[l:local?Reject files that traverse outside the current directory.]"
38*b30d1939SAndy Fiddaman "[m:meter?Display a one line text meter showing archive read progress.]"
39*b30d1939SAndy Fiddaman "[n!:convert?In ebcdic environments convert text archive members from ascii"
40*b30d1939SAndy Fiddaman " to the native ebcdic.]"
41*b30d1939SAndy Fiddaman "[t:list?List each file path on the standard output but do not extract.]"
42*b30d1939SAndy Fiddaman "[v:verbose?List each file path on the standard output as it is extracted.]"
43*b30d1939SAndy Fiddaman "[V?Print the program version and exit.]"
44*b30d1939SAndy Fiddaman "[+SEE ALSO?\bgunzip\b(1), \bpackage\b(1), \bpax\b(1), \bsear\b(1), \btar\b(1)]"
45*b30d1939SAndy Fiddaman ;
46*b30d1939SAndy Fiddaman
47*b30d1939SAndy Fiddaman #else
48*b30d1939SAndy Fiddaman
49*b30d1939SAndy Fiddaman #define NiL ((char*)0)
50*b30d1939SAndy Fiddaman
51*b30d1939SAndy Fiddaman #endif
52*b30d1939SAndy Fiddaman
53*b30d1939SAndy Fiddaman #define METER_width 80
54*b30d1939SAndy Fiddaman #define METER_parts 20
55*b30d1939SAndy Fiddaman
56*b30d1939SAndy Fiddaman #ifndef _GUNZIP_H
57*b30d1939SAndy Fiddaman #define _GUNZIP_H 1
58*b30d1939SAndy Fiddaman
59*b30d1939SAndy Fiddaman /*
60*b30d1939SAndy Fiddaman * stripped down zlib containing public gzfopen()+gzread() in one file
61*b30d1939SAndy Fiddaman * USE THE REAL ZLIB AFTER BOOTSTRAP
62*b30d1939SAndy Fiddaman */
63*b30d1939SAndy Fiddaman
64*b30d1939SAndy Fiddaman #define ZLIB_INTERNAL 1
65*b30d1939SAndy Fiddaman #define NO_GZCOMPRESS 1
66*b30d1939SAndy Fiddaman
67*b30d1939SAndy Fiddaman #define gz_headerp voidp
68*b30d1939SAndy Fiddaman
69*b30d1939SAndy Fiddaman #include <stdio.h>
70*b30d1939SAndy Fiddaman #include <sys/types.h>
71*b30d1939SAndy Fiddaman
72*b30d1939SAndy Fiddaman #if _PACKAGE_ast || defined(__STDC__) || defined(_SEAR_EXEC) || defined(_WIN32)
73*b30d1939SAndy Fiddaman
74*b30d1939SAndy Fiddaman #define FOPEN_READ "rb"
75*b30d1939SAndy Fiddaman #define FOPEN_WRITE "wb"
76*b30d1939SAndy Fiddaman
77*b30d1939SAndy Fiddaman #else
78*b30d1939SAndy Fiddaman
79*b30d1939SAndy Fiddaman #define FOPEN_READ "r"
80*b30d1939SAndy Fiddaman #define FOPEN_WRITE "w"
81*b30d1939SAndy Fiddaman
82*b30d1939SAndy Fiddaman #endif
83*b30d1939SAndy Fiddaman
84*b30d1939SAndy Fiddaman #ifndef O_BINARY
85*b30d1939SAndy Fiddaman #define O_BINARY 0
86*b30d1939SAndy Fiddaman #endif
87*b30d1939SAndy Fiddaman
88*b30d1939SAndy Fiddaman #if _PACKAGE_ast
89*b30d1939SAndy Fiddaman
90*b30d1939SAndy Fiddaman #ifndef setmode
91*b30d1939SAndy Fiddaman #define setmode(d,m)
92*b30d1939SAndy Fiddaman #endif
93*b30d1939SAndy Fiddaman
94*b30d1939SAndy Fiddaman #else
95*b30d1939SAndy Fiddaman
96*b30d1939SAndy Fiddaman #if !defined(_WINIX) && (_UWIN || __CYGWIN__ || __EMX__)
97*b30d1939SAndy Fiddaman #define _WINIX 1
98*b30d1939SAndy Fiddaman #endif
99*b30d1939SAndy Fiddaman
100*b30d1939SAndy Fiddaman #if _WIN32 && !_WINIX
101*b30d1939SAndy Fiddaman
102*b30d1939SAndy Fiddaman #include <direct.h>
103*b30d1939SAndy Fiddaman #include <io.h>
104*b30d1939SAndy Fiddaman #include <fcntl.h>
105*b30d1939SAndy Fiddaman #include <windows.h>
106*b30d1939SAndy Fiddaman
107*b30d1939SAndy Fiddaman #define access _access
108*b30d1939SAndy Fiddaman #define chmod _chmod
109*b30d1939SAndy Fiddaman #define close _close
110*b30d1939SAndy Fiddaman #define dup _dup
111*b30d1939SAndy Fiddaman #define lseek _lseek
112*b30d1939SAndy Fiddaman #define open _open
113*b30d1939SAndy Fiddaman #define read _read
114*b30d1939SAndy Fiddaman #define setmode _setmode
115*b30d1939SAndy Fiddaman #define unlink _unlink
116*b30d1939SAndy Fiddaman
117*b30d1939SAndy Fiddaman #define mkdir(a,b) _mkdir(a)
118*b30d1939SAndy Fiddaman
119*b30d1939SAndy Fiddaman #else
120*b30d1939SAndy Fiddaman
121*b30d1939SAndy Fiddaman #define HAVE_UNISTD_H 1
122*b30d1939SAndy Fiddaman
123*b30d1939SAndy Fiddaman #include <unistd.h>
124*b30d1939SAndy Fiddaman #include <errno.h>
125*b30d1939SAndy Fiddaman
126*b30d1939SAndy Fiddaman #ifndef setmode
127*b30d1939SAndy Fiddaman #define setmode(d,m)
128*b30d1939SAndy Fiddaman #endif
129*b30d1939SAndy Fiddaman
130*b30d1939SAndy Fiddaman #endif
131*b30d1939SAndy Fiddaman
132*b30d1939SAndy Fiddaman #if defined(__STDC__)
133*b30d1939SAndy Fiddaman
134*b30d1939SAndy Fiddaman #include <stdlib.h>
135*b30d1939SAndy Fiddaman #include <string.h>
136*b30d1939SAndy Fiddaman
137*b30d1939SAndy Fiddaman #endif
138*b30d1939SAndy Fiddaman
139*b30d1939SAndy Fiddaman #endif
140*b30d1939SAndy Fiddaman
141*b30d1939SAndy Fiddaman #ifndef _ZLIB_H
142*b30d1939SAndy Fiddaman #define _ZLIB_H 1
143*b30d1939SAndy Fiddaman
144*b30d1939SAndy Fiddaman /* zlib.h -- interface of the 'zlib' general purpose compression library
145*b30d1939SAndy Fiddaman version 1.2.3, July 18th, 2005
146*b30d1939SAndy Fiddaman
147*b30d1939SAndy Fiddaman Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
148*b30d1939SAndy Fiddaman
149*b30d1939SAndy Fiddaman This software is provided 'as-is', without any express or implied
150*b30d1939SAndy Fiddaman warranty. In no event will the authors be held liable for any damages
151*b30d1939SAndy Fiddaman arising from the use of this software.
152*b30d1939SAndy Fiddaman
153*b30d1939SAndy Fiddaman Permission is granted to anyone to use this software for any purpose,
154*b30d1939SAndy Fiddaman including commercial applications, and to alter it and redistribute it
155*b30d1939SAndy Fiddaman freely, subject to the following restrictions:
156*b30d1939SAndy Fiddaman
157*b30d1939SAndy Fiddaman 1. The origin of this software must not be misrepresented; you must not
158*b30d1939SAndy Fiddaman claim that you wrote the original software. If you use this software
159*b30d1939SAndy Fiddaman in a product, an acknowledgment in the product documentation would be
160*b30d1939SAndy Fiddaman appreciated but is not required.
161*b30d1939SAndy Fiddaman 2. Altered source versions must be plainly marked as such, and must not be
162*b30d1939SAndy Fiddaman misrepresented as being the original software.
163*b30d1939SAndy Fiddaman 3. This notice may not be removed or altered from any source distribution.
164*b30d1939SAndy Fiddaman
165*b30d1939SAndy Fiddaman Jean-loup Gailly Mark Adler
166*b30d1939SAndy Fiddaman jloup@gzip.org madler@alumni.caltech.edu
167*b30d1939SAndy Fiddaman
168*b30d1939SAndy Fiddaman
169*b30d1939SAndy Fiddaman The data format used by the zlib library is described by RFCs (Request for
170*b30d1939SAndy Fiddaman Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
171*b30d1939SAndy Fiddaman (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
172*b30d1939SAndy Fiddaman */
173*b30d1939SAndy Fiddaman
174*b30d1939SAndy Fiddaman #ifndef _ZCONF_H
175*b30d1939SAndy Fiddaman #define _ZCONF_H 1
176*b30d1939SAndy Fiddaman
177*b30d1939SAndy Fiddaman #if _PACKAGE_ast
178*b30d1939SAndy Fiddaman #include <ast_std.h> /* for { _WINIX __IMPORT__ __EXPORT__ } */
179*b30d1939SAndy Fiddaman #define z_off_t int32_t
180*b30d1939SAndy Fiddaman #if _typ_int64_t
181*b30d1939SAndy Fiddaman #define z_off64_t int64_t
182*b30d1939SAndy Fiddaman #endif
183*b30d1939SAndy Fiddaman #else
184*b30d1939SAndy Fiddaman #if !defined(_WINIX) && (_UWIN || __CYGWIN__ || __EMX__)
185*b30d1939SAndy Fiddaman #define _WINIX 1
186*b30d1939SAndy Fiddaman #endif
187*b30d1939SAndy Fiddaman #endif
188*b30d1939SAndy Fiddaman
189*b30d1939SAndy Fiddaman #if _BLD_z && defined(__EXPORT__)
190*b30d1939SAndy Fiddaman #define ZEXTERN __EXPORT__
191*b30d1939SAndy Fiddaman #define ZEXPORT
192*b30d1939SAndy Fiddaman #endif
193*b30d1939SAndy Fiddaman
194*b30d1939SAndy Fiddaman #if defined(__MSDOS__) && !defined(MSDOS)
195*b30d1939SAndy Fiddaman # define MSDOS
196*b30d1939SAndy Fiddaman #endif
197*b30d1939SAndy Fiddaman #if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
198*b30d1939SAndy Fiddaman # define OS2
199*b30d1939SAndy Fiddaman #endif
200*b30d1939SAndy Fiddaman #if defined(_WINDOWS) && !defined(WINDOWS)
201*b30d1939SAndy Fiddaman # define WINDOWS
202*b30d1939SAndy Fiddaman #endif
203*b30d1939SAndy Fiddaman #if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
204*b30d1939SAndy Fiddaman # ifndef WIN32
205*b30d1939SAndy Fiddaman # define WIN32
206*b30d1939SAndy Fiddaman # endif
207*b30d1939SAndy Fiddaman #endif
208*b30d1939SAndy Fiddaman #if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
209*b30d1939SAndy Fiddaman # if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
210*b30d1939SAndy Fiddaman # ifndef SYS16BIT
211*b30d1939SAndy Fiddaman # define SYS16BIT
212*b30d1939SAndy Fiddaman # endif
213*b30d1939SAndy Fiddaman # endif
214*b30d1939SAndy Fiddaman #endif
215*b30d1939SAndy Fiddaman
216*b30d1939SAndy Fiddaman /*
217*b30d1939SAndy Fiddaman * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
218*b30d1939SAndy Fiddaman * than 64k bytes at a time (needed on systems with 16-bit int).
219*b30d1939SAndy Fiddaman */
220*b30d1939SAndy Fiddaman #ifdef SYS16BIT
221*b30d1939SAndy Fiddaman # define MAXSEG_64K
222*b30d1939SAndy Fiddaman #endif
223*b30d1939SAndy Fiddaman #ifdef MSDOS
224*b30d1939SAndy Fiddaman # define UNALIGNED_OK
225*b30d1939SAndy Fiddaman #endif
226*b30d1939SAndy Fiddaman
227*b30d1939SAndy Fiddaman #ifdef __STDC_VERSION__
228*b30d1939SAndy Fiddaman # ifndef STDC
229*b30d1939SAndy Fiddaman # define STDC
230*b30d1939SAndy Fiddaman # endif
231*b30d1939SAndy Fiddaman # if __STDC_VERSION__ >= 199901L
232*b30d1939SAndy Fiddaman # ifndef STDC99
233*b30d1939SAndy Fiddaman # define STDC99
234*b30d1939SAndy Fiddaman # endif
235*b30d1939SAndy Fiddaman # endif
236*b30d1939SAndy Fiddaman #endif
237*b30d1939SAndy Fiddaman #if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
238*b30d1939SAndy Fiddaman # define STDC
239*b30d1939SAndy Fiddaman #endif
240*b30d1939SAndy Fiddaman #if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
241*b30d1939SAndy Fiddaman # define STDC
242*b30d1939SAndy Fiddaman #endif
243*b30d1939SAndy Fiddaman #if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
244*b30d1939SAndy Fiddaman # define STDC
245*b30d1939SAndy Fiddaman #endif
246*b30d1939SAndy Fiddaman #if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
247*b30d1939SAndy Fiddaman # define STDC
248*b30d1939SAndy Fiddaman #endif
249*b30d1939SAndy Fiddaman
250*b30d1939SAndy Fiddaman #if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
251*b30d1939SAndy Fiddaman # define STDC
252*b30d1939SAndy Fiddaman #endif
253*b30d1939SAndy Fiddaman
254*b30d1939SAndy Fiddaman #ifndef STDC
255*b30d1939SAndy Fiddaman # ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
256*b30d1939SAndy Fiddaman # define const /* note: need a more gentle solution here */
257*b30d1939SAndy Fiddaman # endif
258*b30d1939SAndy Fiddaman #endif
259*b30d1939SAndy Fiddaman
260*b30d1939SAndy Fiddaman /* Some Mac compilers merge all .h files incorrectly: */
261*b30d1939SAndy Fiddaman #if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
262*b30d1939SAndy Fiddaman # define NO_DUMMY_DECL
263*b30d1939SAndy Fiddaman #endif
264*b30d1939SAndy Fiddaman
265*b30d1939SAndy Fiddaman /* Maximum value for memLevel in deflateInit2 */
266*b30d1939SAndy Fiddaman #ifndef MAX_MEM_LEVEL
267*b30d1939SAndy Fiddaman # ifdef MAXSEG_64K
268*b30d1939SAndy Fiddaman # define MAX_MEM_LEVEL 8
269*b30d1939SAndy Fiddaman # else
270*b30d1939SAndy Fiddaman # define MAX_MEM_LEVEL 9
271*b30d1939SAndy Fiddaman # endif
272*b30d1939SAndy Fiddaman #endif
273*b30d1939SAndy Fiddaman
274*b30d1939SAndy Fiddaman /* Maximum value for windowBits in deflateInit2 and inflateInit2.
275*b30d1939SAndy Fiddaman * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
276*b30d1939SAndy Fiddaman * created by gzip. (Files created by minigzip can still be extracted by
277*b30d1939SAndy Fiddaman * gzip.)
278*b30d1939SAndy Fiddaman */
279*b30d1939SAndy Fiddaman #ifndef MAX_WBITS
280*b30d1939SAndy Fiddaman # define MAX_WBITS 15 /* 32K LZ77 window */
281*b30d1939SAndy Fiddaman #endif
282*b30d1939SAndy Fiddaman
283*b30d1939SAndy Fiddaman /* The memory requirements for deflate are (in bytes):
284*b30d1939SAndy Fiddaman (1 << (windowBits+2)) + (1 << (memLevel+9))
285*b30d1939SAndy Fiddaman that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
286*b30d1939SAndy Fiddaman plus a few kilobytes for small objects. For example, if you want to reduce
287*b30d1939SAndy Fiddaman the default memory requirements from 256K to 128K, compile with
288*b30d1939SAndy Fiddaman make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
289*b30d1939SAndy Fiddaman Of course this will generally degrade compression (there's no free lunch).
290*b30d1939SAndy Fiddaman
291*b30d1939SAndy Fiddaman The memory requirements for inflate are (in bytes) 1 << windowBits
292*b30d1939SAndy Fiddaman that is, 32K for windowBits=15 (default value) plus a few kilobytes
293*b30d1939SAndy Fiddaman for small objects.
294*b30d1939SAndy Fiddaman */
295*b30d1939SAndy Fiddaman
296*b30d1939SAndy Fiddaman /* Type declarations */
297*b30d1939SAndy Fiddaman
298*b30d1939SAndy Fiddaman #ifndef OF /* function prototypes */
299*b30d1939SAndy Fiddaman # ifdef STDC
300*b30d1939SAndy Fiddaman # define OF(args) args
301*b30d1939SAndy Fiddaman # else
302*b30d1939SAndy Fiddaman # define OF(args) ()
303*b30d1939SAndy Fiddaman # endif
304*b30d1939SAndy Fiddaman #endif
305*b30d1939SAndy Fiddaman
306*b30d1939SAndy Fiddaman /* The following definitions for FAR are needed only for MSDOS mixed
307*b30d1939SAndy Fiddaman * model programming (small or medium model with some far allocations).
308*b30d1939SAndy Fiddaman * This was tested only with MSC; for other MSDOS compilers you may have
309*b30d1939SAndy Fiddaman * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
310*b30d1939SAndy Fiddaman * just define FAR to be empty.
311*b30d1939SAndy Fiddaman */
312*b30d1939SAndy Fiddaman #ifdef SYS16BIT
313*b30d1939SAndy Fiddaman # if defined(M_I86SM) || defined(M_I86MM)
314*b30d1939SAndy Fiddaman /* MSC small or medium model */
315*b30d1939SAndy Fiddaman # define SMALL_MEDIUM
316*b30d1939SAndy Fiddaman # ifdef _MSC_VER
317*b30d1939SAndy Fiddaman # define FAR _far
318*b30d1939SAndy Fiddaman # else
319*b30d1939SAndy Fiddaman # define FAR far
320*b30d1939SAndy Fiddaman # endif
321*b30d1939SAndy Fiddaman # endif
322*b30d1939SAndy Fiddaman # if (defined(__SMALL__) || defined(__MEDIUM__))
323*b30d1939SAndy Fiddaman /* Turbo C small or medium model */
324*b30d1939SAndy Fiddaman # define SMALL_MEDIUM
325*b30d1939SAndy Fiddaman # ifdef __BORLANDC__
326*b30d1939SAndy Fiddaman # define FAR _far
327*b30d1939SAndy Fiddaman # else
328*b30d1939SAndy Fiddaman # define FAR far
329*b30d1939SAndy Fiddaman # endif
330*b30d1939SAndy Fiddaman # endif
331*b30d1939SAndy Fiddaman #endif
332*b30d1939SAndy Fiddaman
333*b30d1939SAndy Fiddaman #if defined(WINDOWS) || defined(WIN32)
334*b30d1939SAndy Fiddaman /* If building or using zlib as a DLL, define ZLIB_DLL.
335*b30d1939SAndy Fiddaman * This is not mandatory, but it offers a little performance increase.
336*b30d1939SAndy Fiddaman */
337*b30d1939SAndy Fiddaman # ifdef ZLIB_DLL
338*b30d1939SAndy Fiddaman # if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
339*b30d1939SAndy Fiddaman # ifdef ZLIB_INTERNAL
340*b30d1939SAndy Fiddaman # define ZEXTERN extern __declspec(dllexport)
341*b30d1939SAndy Fiddaman # else
342*b30d1939SAndy Fiddaman # define ZEXTERN extern __declspec(dllimport)
343*b30d1939SAndy Fiddaman # endif
344*b30d1939SAndy Fiddaman # endif
345*b30d1939SAndy Fiddaman # endif /* ZLIB_DLL */
346*b30d1939SAndy Fiddaman /* If building or using zlib with the WINAPI/WINAPIV calling convention,
347*b30d1939SAndy Fiddaman * define ZLIB_WINAPI.
348*b30d1939SAndy Fiddaman * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
349*b30d1939SAndy Fiddaman */
350*b30d1939SAndy Fiddaman # ifdef ZLIB_WINAPI
351*b30d1939SAndy Fiddaman # ifdef FAR
352*b30d1939SAndy Fiddaman # undef FAR
353*b30d1939SAndy Fiddaman # endif
354*b30d1939SAndy Fiddaman # include <windows.h>
355*b30d1939SAndy Fiddaman /* No need for _export, use ZLIB.DEF instead. */
356*b30d1939SAndy Fiddaman /* For complete Windows compatibility, use WINAPI, not __stdcall. */
357*b30d1939SAndy Fiddaman # define ZEXPORT WINAPI
358*b30d1939SAndy Fiddaman # ifdef WIN32
359*b30d1939SAndy Fiddaman # define ZEXPORTVA WINAPIV
360*b30d1939SAndy Fiddaman # else
361*b30d1939SAndy Fiddaman # define ZEXPORTVA FAR CDECL
362*b30d1939SAndy Fiddaman # endif
363*b30d1939SAndy Fiddaman # endif
364*b30d1939SAndy Fiddaman #endif
365*b30d1939SAndy Fiddaman
366*b30d1939SAndy Fiddaman #if defined (__BEOS__)
367*b30d1939SAndy Fiddaman # ifdef ZLIB_DLL
368*b30d1939SAndy Fiddaman # ifdef ZLIB_INTERNAL
369*b30d1939SAndy Fiddaman # define ZEXPORT __declspec(dllexport)
370*b30d1939SAndy Fiddaman # define ZEXPORTVA __declspec(dllexport)
371*b30d1939SAndy Fiddaman # else
372*b30d1939SAndy Fiddaman # define ZEXPORT __declspec(dllimport)
373*b30d1939SAndy Fiddaman # define ZEXPORTVA __declspec(dllimport)
374*b30d1939SAndy Fiddaman # endif
375*b30d1939SAndy Fiddaman # endif
376*b30d1939SAndy Fiddaman #endif
377*b30d1939SAndy Fiddaman
378*b30d1939SAndy Fiddaman #ifndef ZEXTERN
379*b30d1939SAndy Fiddaman # define ZEXTERN extern
380*b30d1939SAndy Fiddaman #endif
381*b30d1939SAndy Fiddaman #ifndef ZEXPORT
382*b30d1939SAndy Fiddaman # define ZEXPORT
383*b30d1939SAndy Fiddaman #endif
384*b30d1939SAndy Fiddaman #ifndef ZEXPORTVA
385*b30d1939SAndy Fiddaman # define ZEXPORTVA
386*b30d1939SAndy Fiddaman #endif
387*b30d1939SAndy Fiddaman
388*b30d1939SAndy Fiddaman #ifndef FAR
389*b30d1939SAndy Fiddaman # define FAR
390*b30d1939SAndy Fiddaman #endif
391*b30d1939SAndy Fiddaman
392*b30d1939SAndy Fiddaman #if !defined(__MACTYPES__)
393*b30d1939SAndy Fiddaman typedef unsigned char Byte; /* 8 bits */
394*b30d1939SAndy Fiddaman #endif
395*b30d1939SAndy Fiddaman typedef unsigned int uInt; /* 16 bits or more */
396*b30d1939SAndy Fiddaman typedef unsigned long uLong; /* 32 bits or more */
397*b30d1939SAndy Fiddaman
398*b30d1939SAndy Fiddaman #ifdef SMALL_MEDIUM
399*b30d1939SAndy Fiddaman /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
400*b30d1939SAndy Fiddaman # define Bytef Byte FAR
401*b30d1939SAndy Fiddaman #else
402*b30d1939SAndy Fiddaman typedef Byte FAR Bytef;
403*b30d1939SAndy Fiddaman #endif
404*b30d1939SAndy Fiddaman typedef char FAR charf;
405*b30d1939SAndy Fiddaman typedef int FAR intf;
406*b30d1939SAndy Fiddaman typedef uInt FAR uIntf;
407*b30d1939SAndy Fiddaman typedef uLong FAR uLongf;
408*b30d1939SAndy Fiddaman
409*b30d1939SAndy Fiddaman #ifdef STDC
410*b30d1939SAndy Fiddaman typedef void const *voidpc;
411*b30d1939SAndy Fiddaman typedef void FAR *voidpf;
412*b30d1939SAndy Fiddaman typedef void *voidp;
413*b30d1939SAndy Fiddaman #else
414*b30d1939SAndy Fiddaman typedef Byte const *voidpc;
415*b30d1939SAndy Fiddaman typedef Byte FAR *voidpf;
416*b30d1939SAndy Fiddaman typedef Byte *voidp;
417*b30d1939SAndy Fiddaman #endif
418*b30d1939SAndy Fiddaman
419*b30d1939SAndy Fiddaman #if HAVE_UNISTD_H
420*b30d1939SAndy Fiddaman # include <sys/types.h> /* for off_t */
421*b30d1939SAndy Fiddaman # include <unistd.h> /* for SEEK_* and off_t */
422*b30d1939SAndy Fiddaman # ifdef VMS
423*b30d1939SAndy Fiddaman # include <unixio.h> /* for off_t */
424*b30d1939SAndy Fiddaman # endif
425*b30d1939SAndy Fiddaman # define z_off_t off_t
426*b30d1939SAndy Fiddaman #endif
427*b30d1939SAndy Fiddaman #ifndef SEEK_SET
428*b30d1939SAndy Fiddaman # define SEEK_SET 0 /* Seek from beginning of file. */
429*b30d1939SAndy Fiddaman # define SEEK_CUR 1 /* Seek from current position. */
430*b30d1939SAndy Fiddaman # define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
431*b30d1939SAndy Fiddaman #endif
432*b30d1939SAndy Fiddaman #ifndef z_off_t
433*b30d1939SAndy Fiddaman # define z_off_t long
434*b30d1939SAndy Fiddaman #endif
435*b30d1939SAndy Fiddaman
436*b30d1939SAndy Fiddaman #if defined(__OS400__)
437*b30d1939SAndy Fiddaman # define NO_vsnprintf
438*b30d1939SAndy Fiddaman #endif
439*b30d1939SAndy Fiddaman
440*b30d1939SAndy Fiddaman #if defined(__MVS__)
441*b30d1939SAndy Fiddaman # define NO_vsnprintf
442*b30d1939SAndy Fiddaman #endif
443*b30d1939SAndy Fiddaman
444*b30d1939SAndy Fiddaman /* MVS linker does not support external names larger than 8 bytes */
445*b30d1939SAndy Fiddaman #if defined(__MVS__)
446*b30d1939SAndy Fiddaman # pragma map(deflateInit_,"DEIN")
447*b30d1939SAndy Fiddaman # pragma map(deflateInit2_,"DEIN2")
448*b30d1939SAndy Fiddaman # pragma map(deflateEnd,"DEEND")
449*b30d1939SAndy Fiddaman # pragma map(deflateBound,"DEBND")
450*b30d1939SAndy Fiddaman # pragma map(inflateInit_,"ININ")
451*b30d1939SAndy Fiddaman # pragma map(inflateInit2_,"ININ2")
452*b30d1939SAndy Fiddaman # pragma map(inflateEnd,"INEND")
453*b30d1939SAndy Fiddaman # pragma map(inflateSync,"INSY")
454*b30d1939SAndy Fiddaman # pragma map(inflateSetDictionary,"INSEDI")
455*b30d1939SAndy Fiddaman # pragma map(compressBound,"CMBND")
456*b30d1939SAndy Fiddaman # pragma map(inflate_table,"INTABL")
457*b30d1939SAndy Fiddaman # pragma map(inflate_fast,"INFA")
458*b30d1939SAndy Fiddaman # pragma map(inflate_copyright,"INCOPY")
459*b30d1939SAndy Fiddaman #endif
460*b30d1939SAndy Fiddaman
461*b30d1939SAndy Fiddaman #endif /* _ZCONF_H */
462*b30d1939SAndy Fiddaman
463*b30d1939SAndy Fiddaman #define ZLIB_VERSION "1.2.3"
464*b30d1939SAndy Fiddaman #define ZLIB_VERNUM 0x1230
465*b30d1939SAndy Fiddaman
466*b30d1939SAndy Fiddaman /*
467*b30d1939SAndy Fiddaman The 'zlib' compression library provides in-memory compression and
468*b30d1939SAndy Fiddaman decompression functions, including integrity checks of the uncompressed
469*b30d1939SAndy Fiddaman data. This version of the library supports only one compression method
470*b30d1939SAndy Fiddaman (deflation) but other algorithms will be added later and will have the same
471*b30d1939SAndy Fiddaman stream interface.
472*b30d1939SAndy Fiddaman
473*b30d1939SAndy Fiddaman Compression can be done in a single step if the buffers are large
474*b30d1939SAndy Fiddaman enough (for example if an input file is mmap'ed), or can be done by
475*b30d1939SAndy Fiddaman repeated calls of the compression function. In the latter case, the
476*b30d1939SAndy Fiddaman application must provide more input and/or consume the output
477*b30d1939SAndy Fiddaman (providing more output space) before each call.
478*b30d1939SAndy Fiddaman
479*b30d1939SAndy Fiddaman The compressed data format used by default by the in-memory functions is
480*b30d1939SAndy Fiddaman the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
481*b30d1939SAndy Fiddaman around a deflate stream, which is itself documented in RFC 1951.
482*b30d1939SAndy Fiddaman
483*b30d1939SAndy Fiddaman The library also supports reading and writing files in gzip (.gz) format
484*b30d1939SAndy Fiddaman with an interface similar to that of stdio using the functions that start
485*b30d1939SAndy Fiddaman with "gz". The gzip format is different from the zlib format. gzip is a
486*b30d1939SAndy Fiddaman gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
487*b30d1939SAndy Fiddaman
488*b30d1939SAndy Fiddaman This library can optionally read and write gzip streams in memory as well.
489*b30d1939SAndy Fiddaman
490*b30d1939SAndy Fiddaman The zlib format was designed to be compact and fast for use in memory
491*b30d1939SAndy Fiddaman and on communications channels. The gzip format was designed for single-
492*b30d1939SAndy Fiddaman file compression on file systems, has a larger header than zlib to maintain
493*b30d1939SAndy Fiddaman directory information, and uses a different, slower check method than zlib.
494*b30d1939SAndy Fiddaman
495*b30d1939SAndy Fiddaman The library does not install any signal handler. The decoder checks
496*b30d1939SAndy Fiddaman the consistency of the compressed data, so the library should never
497*b30d1939SAndy Fiddaman crash even in case of corrupted input.
498*b30d1939SAndy Fiddaman */
499*b30d1939SAndy Fiddaman
500*b30d1939SAndy Fiddaman typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
501*b30d1939SAndy Fiddaman typedef void (*free_func) OF((voidpf opaque, voidpf address));
502*b30d1939SAndy Fiddaman
503*b30d1939SAndy Fiddaman struct internal_state;
504*b30d1939SAndy Fiddaman
505*b30d1939SAndy Fiddaman typedef struct z_stream_s {
506*b30d1939SAndy Fiddaman Bytef *next_in; /* next input byte */
507*b30d1939SAndy Fiddaman uInt avail_in; /* number of bytes available at next_in */
508*b30d1939SAndy Fiddaman uLong total_in; /* total nb of input bytes read so far */
509*b30d1939SAndy Fiddaman
510*b30d1939SAndy Fiddaman Bytef *next_out; /* next output byte should be put there */
511*b30d1939SAndy Fiddaman uInt avail_out; /* remaining free space at next_out */
512*b30d1939SAndy Fiddaman uLong total_out; /* total nb of bytes output so far */
513*b30d1939SAndy Fiddaman
514*b30d1939SAndy Fiddaman char *msg; /* last error message, NULL if no error */
515*b30d1939SAndy Fiddaman struct internal_state FAR *state; /* not visible by applications */
516*b30d1939SAndy Fiddaman
517*b30d1939SAndy Fiddaman alloc_func zalloc; /* used to allocate the internal state */
518*b30d1939SAndy Fiddaman free_func zfree; /* used to free the internal state */
519*b30d1939SAndy Fiddaman voidpf opaque; /* private data object passed to zalloc and zfree */
520*b30d1939SAndy Fiddaman
521*b30d1939SAndy Fiddaman int data_type; /* best guess about the data type: binary or text */
522*b30d1939SAndy Fiddaman uLong adler; /* adler32 value of the uncompressed data */
523*b30d1939SAndy Fiddaman uLong reserved; /* reserved for future use */
524*b30d1939SAndy Fiddaman } z_stream;
525*b30d1939SAndy Fiddaman
526*b30d1939SAndy Fiddaman typedef z_stream FAR *z_streamp;
527*b30d1939SAndy Fiddaman
528*b30d1939SAndy Fiddaman /* constants */
529*b30d1939SAndy Fiddaman
530*b30d1939SAndy Fiddaman #define Z_NO_FLUSH 0
531*b30d1939SAndy Fiddaman #define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
532*b30d1939SAndy Fiddaman #define Z_SYNC_FLUSH 2
533*b30d1939SAndy Fiddaman #define Z_FULL_FLUSH 3
534*b30d1939SAndy Fiddaman #define Z_FINISH 4
535*b30d1939SAndy Fiddaman #define Z_BLOCK 5
536*b30d1939SAndy Fiddaman /* Allowed flush values; see deflate() and inflate() below for details */
537*b30d1939SAndy Fiddaman
538*b30d1939SAndy Fiddaman #define Z_OK 0
539*b30d1939SAndy Fiddaman #define Z_STREAM_END 1
540*b30d1939SAndy Fiddaman #define Z_NEED_DICT 2
541*b30d1939SAndy Fiddaman #define Z_ERRNO (-1)
542*b30d1939SAndy Fiddaman #define Z_STREAM_ERROR (-2)
543*b30d1939SAndy Fiddaman #define Z_DATA_ERROR (-3)
544*b30d1939SAndy Fiddaman #define Z_MEM_ERROR (-4)
545*b30d1939SAndy Fiddaman #define Z_BUF_ERROR (-5)
546*b30d1939SAndy Fiddaman #define Z_VERSION_ERROR (-6)
547*b30d1939SAndy Fiddaman /* Return codes for the compression/decompression functions. Negative
548*b30d1939SAndy Fiddaman * values are errors, positive values are used for special but normal events.
549*b30d1939SAndy Fiddaman */
550*b30d1939SAndy Fiddaman
551*b30d1939SAndy Fiddaman #define Z_NO_COMPRESSION 0
552*b30d1939SAndy Fiddaman #define Z_BEST_SPEED 1
553*b30d1939SAndy Fiddaman #define Z_BEST_COMPRESSION 9
554*b30d1939SAndy Fiddaman #define Z_DEFAULT_COMPRESSION (-1)
555*b30d1939SAndy Fiddaman /* compression levels */
556*b30d1939SAndy Fiddaman
557*b30d1939SAndy Fiddaman #define Z_FILTERED 1
558*b30d1939SAndy Fiddaman #define Z_HUFFMAN_ONLY 2
559*b30d1939SAndy Fiddaman #define Z_RLE 3
560*b30d1939SAndy Fiddaman #define Z_FIXED 4
561*b30d1939SAndy Fiddaman #define Z_DEFAULT_STRATEGY 0
562*b30d1939SAndy Fiddaman /* compression strategy; see deflateInit2() below for details */
563*b30d1939SAndy Fiddaman
564*b30d1939SAndy Fiddaman #define Z_BINARY 0
565*b30d1939SAndy Fiddaman #define Z_TEXT 1
566*b30d1939SAndy Fiddaman #define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */
567*b30d1939SAndy Fiddaman #define Z_UNKNOWN 2
568*b30d1939SAndy Fiddaman /* Possible values of the data_type field (though see inflate()) */
569*b30d1939SAndy Fiddaman
570*b30d1939SAndy Fiddaman #define Z_DEFLATED 8
571*b30d1939SAndy Fiddaman /* The deflate compression method (the only one supported in this version) */
572*b30d1939SAndy Fiddaman
573*b30d1939SAndy Fiddaman #define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
574*b30d1939SAndy Fiddaman
575*b30d1939SAndy Fiddaman #define inflateInit2(strm, windowBits) \
576*b30d1939SAndy Fiddaman inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
577*b30d1939SAndy Fiddaman
578*b30d1939SAndy Fiddaman #endif /* _ZLIB_H */
579*b30d1939SAndy Fiddaman
580*b30d1939SAndy Fiddaman #ifndef _ZUTIL_H
581*b30d1939SAndy Fiddaman #define _ZUTIL_H 1
582*b30d1939SAndy Fiddaman
583*b30d1939SAndy Fiddaman #if !_PACKAGE_ast && !defined(STDC)
584*b30d1939SAndy Fiddaman #if defined(__STDC__)
585*b30d1939SAndy Fiddaman # include <stddef.h>
586*b30d1939SAndy Fiddaman #endif
587*b30d1939SAndy Fiddaman # include <string.h>
588*b30d1939SAndy Fiddaman # include <stdlib.h>
589*b30d1939SAndy Fiddaman #endif
590*b30d1939SAndy Fiddaman
591*b30d1939SAndy Fiddaman #ifndef local
592*b30d1939SAndy Fiddaman # define local static
593*b30d1939SAndy Fiddaman #endif
594*b30d1939SAndy Fiddaman /* compile with -Dlocal if your debugger can't find static symbols */
595*b30d1939SAndy Fiddaman
596*b30d1939SAndy Fiddaman typedef unsigned char uch;
597*b30d1939SAndy Fiddaman typedef uch FAR uchf;
598*b30d1939SAndy Fiddaman typedef unsigned short ush;
599*b30d1939SAndy Fiddaman typedef ush FAR ushf;
600*b30d1939SAndy Fiddaman typedef unsigned long ulg;
601*b30d1939SAndy Fiddaman
602*b30d1939SAndy Fiddaman /* common constants */
603*b30d1939SAndy Fiddaman
604*b30d1939SAndy Fiddaman #ifndef DEF_WBITS
605*b30d1939SAndy Fiddaman # define DEF_WBITS MAX_WBITS
606*b30d1939SAndy Fiddaman #endif
607*b30d1939SAndy Fiddaman /* default windowBits for decompression. MAX_WBITS is for compression only */
608*b30d1939SAndy Fiddaman
609*b30d1939SAndy Fiddaman #if MAX_MEM_LEVEL >= 8
610*b30d1939SAndy Fiddaman # define DEF_MEM_LEVEL 8
611*b30d1939SAndy Fiddaman #else
612*b30d1939SAndy Fiddaman # define DEF_MEM_LEVEL MAX_MEM_LEVEL
613*b30d1939SAndy Fiddaman #endif
614*b30d1939SAndy Fiddaman /* default memLevel */
615*b30d1939SAndy Fiddaman
616*b30d1939SAndy Fiddaman #define STORED_BLOCK 0
617*b30d1939SAndy Fiddaman #define STATIC_TREES 1
618*b30d1939SAndy Fiddaman #define DYN_TREES 2
619*b30d1939SAndy Fiddaman /* The three kinds of block type */
620*b30d1939SAndy Fiddaman
621*b30d1939SAndy Fiddaman #define MIN_MATCH 3
622*b30d1939SAndy Fiddaman #define MAX_MATCH 258
623*b30d1939SAndy Fiddaman /* The minimum and maximum match lengths */
624*b30d1939SAndy Fiddaman
625*b30d1939SAndy Fiddaman #define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
626*b30d1939SAndy Fiddaman
627*b30d1939SAndy Fiddaman /* target dependencies */
628*b30d1939SAndy Fiddaman
629*b30d1939SAndy Fiddaman #if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
630*b30d1939SAndy Fiddaman # define OS_CODE 0x00
631*b30d1939SAndy Fiddaman # if defined(__TURBOC__) || defined(__BORLANDC__)
632*b30d1939SAndy Fiddaman # if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
633*b30d1939SAndy Fiddaman /* Allow compilation with ANSI keywords only enabled */
634*b30d1939SAndy Fiddaman void _Cdecl farfree( void *block );
635*b30d1939SAndy Fiddaman void *_Cdecl farmalloc( unsigned long nbytes );
636*b30d1939SAndy Fiddaman # else
637*b30d1939SAndy Fiddaman # include <alloc.h>
638*b30d1939SAndy Fiddaman # endif
639*b30d1939SAndy Fiddaman # else /* MSC or DJGPP */
640*b30d1939SAndy Fiddaman # include <malloc.h>
641*b30d1939SAndy Fiddaman # endif
642*b30d1939SAndy Fiddaman #endif
643*b30d1939SAndy Fiddaman
644*b30d1939SAndy Fiddaman #ifdef AMIGA
645*b30d1939SAndy Fiddaman # define OS_CODE 0x01
646*b30d1939SAndy Fiddaman #endif
647*b30d1939SAndy Fiddaman
648*b30d1939SAndy Fiddaman #if defined(VAXC) || defined(VMS)
649*b30d1939SAndy Fiddaman # define OS_CODE 0x02
650*b30d1939SAndy Fiddaman # define F_OPEN(name, mode) \
651*b30d1939SAndy Fiddaman fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
652*b30d1939SAndy Fiddaman #endif
653*b30d1939SAndy Fiddaman
654*b30d1939SAndy Fiddaman #if defined(ATARI) || defined(atarist)
655*b30d1939SAndy Fiddaman # define OS_CODE 0x05
656*b30d1939SAndy Fiddaman #endif
657*b30d1939SAndy Fiddaman
658*b30d1939SAndy Fiddaman #ifdef OS2
659*b30d1939SAndy Fiddaman # define OS_CODE 0x06
660*b30d1939SAndy Fiddaman # ifdef M_I86
661*b30d1939SAndy Fiddaman #include <malloc.h>
662*b30d1939SAndy Fiddaman # endif
663*b30d1939SAndy Fiddaman #endif
664*b30d1939SAndy Fiddaman
665*b30d1939SAndy Fiddaman #if defined(MACOS) || defined(TARGET_OS_MAC)
666*b30d1939SAndy Fiddaman # define OS_CODE 0x07
667*b30d1939SAndy Fiddaman # if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
668*b30d1939SAndy Fiddaman # include <unix.h> /* for fdopen */
669*b30d1939SAndy Fiddaman # else
670*b30d1939SAndy Fiddaman # ifndef fdopen
671*b30d1939SAndy Fiddaman # define fdopen(fd,mode) NULL /* No fdopen() */
672*b30d1939SAndy Fiddaman # endif
673*b30d1939SAndy Fiddaman # endif
674*b30d1939SAndy Fiddaman #endif
675*b30d1939SAndy Fiddaman
676*b30d1939SAndy Fiddaman #ifdef TOPS20
677*b30d1939SAndy Fiddaman # define OS_CODE 0x0a
678*b30d1939SAndy Fiddaman #endif
679*b30d1939SAndy Fiddaman
680*b30d1939SAndy Fiddaman #ifdef WIN32
681*b30d1939SAndy Fiddaman # ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */
682*b30d1939SAndy Fiddaman # define OS_CODE 0x0b
683*b30d1939SAndy Fiddaman # endif
684*b30d1939SAndy Fiddaman #endif
685*b30d1939SAndy Fiddaman
686*b30d1939SAndy Fiddaman #ifdef __50SERIES /* Prime/PRIMOS */
687*b30d1939SAndy Fiddaman # define OS_CODE 0x0f
688*b30d1939SAndy Fiddaman #endif
689*b30d1939SAndy Fiddaman
690*b30d1939SAndy Fiddaman #if defined(_BEOS_) || defined(RISCOS)
691*b30d1939SAndy Fiddaman # define fdopen(fd,mode) NULL /* No fdopen() */
692*b30d1939SAndy Fiddaman #endif
693*b30d1939SAndy Fiddaman
694*b30d1939SAndy Fiddaman #if (defined(_MSC_VER) && (_MSC_VER > 600))
695*b30d1939SAndy Fiddaman # if defined(_WIN32_WCE)
696*b30d1939SAndy Fiddaman # define fdopen(fd,mode) NULL /* No fdopen() */
697*b30d1939SAndy Fiddaman # ifndef _PTRDIFF_T_DEFINED
698*b30d1939SAndy Fiddaman typedef int ptrdiff_t;
699*b30d1939SAndy Fiddaman # define _PTRDIFF_T_DEFINED
700*b30d1939SAndy Fiddaman # endif
701*b30d1939SAndy Fiddaman # else
702*b30d1939SAndy Fiddaman # define fdopen(fd,type) _fdopen(fd,type)
703*b30d1939SAndy Fiddaman # endif
704*b30d1939SAndy Fiddaman #endif
705*b30d1939SAndy Fiddaman
706*b30d1939SAndy Fiddaman /* common defaults */
707*b30d1939SAndy Fiddaman
708*b30d1939SAndy Fiddaman #ifndef OS_CODE
709*b30d1939SAndy Fiddaman # define OS_CODE 0x03 /* assume Unix */
710*b30d1939SAndy Fiddaman #endif
711*b30d1939SAndy Fiddaman
712*b30d1939SAndy Fiddaman #ifndef F_OPEN
713*b30d1939SAndy Fiddaman # define F_OPEN(name, mode) fopen((name), (mode))
714*b30d1939SAndy Fiddaman #endif
715*b30d1939SAndy Fiddaman
716*b30d1939SAndy Fiddaman /* functions */
717*b30d1939SAndy Fiddaman
718*b30d1939SAndy Fiddaman #if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
719*b30d1939SAndy Fiddaman # ifndef HAVE_VSNPRINTF
720*b30d1939SAndy Fiddaman # define HAVE_VSNPRINTF
721*b30d1939SAndy Fiddaman # endif
722*b30d1939SAndy Fiddaman #endif
723*b30d1939SAndy Fiddaman #if defined(__CYGWIN__)
724*b30d1939SAndy Fiddaman # ifndef HAVE_VSNPRINTF
725*b30d1939SAndy Fiddaman # define HAVE_VSNPRINTF
726*b30d1939SAndy Fiddaman # endif
727*b30d1939SAndy Fiddaman #endif
728*b30d1939SAndy Fiddaman #ifndef HAVE_VSNPRINTF
729*b30d1939SAndy Fiddaman # ifdef MSDOS
730*b30d1939SAndy Fiddaman /* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
731*b30d1939SAndy Fiddaman but for now we just assume it doesn't. */
732*b30d1939SAndy Fiddaman # define NO_vsnprintf
733*b30d1939SAndy Fiddaman # endif
734*b30d1939SAndy Fiddaman # ifdef __TURBOC__
735*b30d1939SAndy Fiddaman # define NO_vsnprintf
736*b30d1939SAndy Fiddaman # endif
737*b30d1939SAndy Fiddaman # ifdef WIN32
738*b30d1939SAndy Fiddaman /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
739*b30d1939SAndy Fiddaman # if !defined(vsnprintf) && !defined(NO_vsnprintf)
740*b30d1939SAndy Fiddaman # define vsnprintf _vsnprintf
741*b30d1939SAndy Fiddaman # endif
742*b30d1939SAndy Fiddaman # endif
743*b30d1939SAndy Fiddaman # ifdef __SASC
744*b30d1939SAndy Fiddaman # define NO_vsnprintf
745*b30d1939SAndy Fiddaman # endif
746*b30d1939SAndy Fiddaman #endif
747*b30d1939SAndy Fiddaman #ifdef VMS
748*b30d1939SAndy Fiddaman # define NO_vsnprintf
749*b30d1939SAndy Fiddaman #endif
750*b30d1939SAndy Fiddaman
751*b30d1939SAndy Fiddaman #if defined(pyr)
752*b30d1939SAndy Fiddaman # define NO_MEMCPY
753*b30d1939SAndy Fiddaman #endif
754*b30d1939SAndy Fiddaman #if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
755*b30d1939SAndy Fiddaman /* Use our own functions for small and medium model with MSC <= 5.0.
756*b30d1939SAndy Fiddaman * You may have to use the same strategy for Borland C (untested).
757*b30d1939SAndy Fiddaman * The __SC__ check is for Symantec.
758*b30d1939SAndy Fiddaman */
759*b30d1939SAndy Fiddaman # define NO_MEMCPY
760*b30d1939SAndy Fiddaman #endif
761*b30d1939SAndy Fiddaman #if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
762*b30d1939SAndy Fiddaman # define HAVE_MEMCPY
763*b30d1939SAndy Fiddaman #endif
764*b30d1939SAndy Fiddaman #ifdef HAVE_MEMCPY
765*b30d1939SAndy Fiddaman # ifdef SMALL_MEDIUM /* MSDOS small or medium model */
766*b30d1939SAndy Fiddaman # define zmemcpy _fmemcpy
767*b30d1939SAndy Fiddaman # define zmemcmp _fmemcmp
768*b30d1939SAndy Fiddaman # define zmemzero(dest, len) _fmemset(dest, 0, len)
769*b30d1939SAndy Fiddaman # else
770*b30d1939SAndy Fiddaman # define zmemcpy memcpy
771*b30d1939SAndy Fiddaman # define zmemcmp memcmp
772*b30d1939SAndy Fiddaman # define zmemzero(dest, len) memset(dest, 0, len)
773*b30d1939SAndy Fiddaman # endif
774*b30d1939SAndy Fiddaman #else
775*b30d1939SAndy Fiddaman extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
776*b30d1939SAndy Fiddaman extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
777*b30d1939SAndy Fiddaman extern void zmemzero OF((Bytef* dest, uInt len));
778*b30d1939SAndy Fiddaman #endif
779*b30d1939SAndy Fiddaman
780*b30d1939SAndy Fiddaman /* Diagnostic functions */
781*b30d1939SAndy Fiddaman #ifdef Z_DEBUG
782*b30d1939SAndy Fiddaman # include <stdio.h>
783*b30d1939SAndy Fiddaman extern int z_verbose;
784*b30d1939SAndy Fiddaman extern void z_error OF((char *m));
785*b30d1939SAndy Fiddaman # define Assert(cond,msg) {if(!(cond)) z_error(msg);}
786*b30d1939SAndy Fiddaman # define Trace(x) {if (z_verbose>=0) fprintf x ;}
787*b30d1939SAndy Fiddaman # define Tracev(x) {if (z_verbose>0) fprintf x ;}
788*b30d1939SAndy Fiddaman # define Tracevv(x) {if (z_verbose>1) fprintf x ;}
789*b30d1939SAndy Fiddaman # define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
790*b30d1939SAndy Fiddaman # define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
791*b30d1939SAndy Fiddaman #else
792*b30d1939SAndy Fiddaman # define Assert(cond,msg)
793*b30d1939SAndy Fiddaman # define Trace(x)
794*b30d1939SAndy Fiddaman # define Tracev(x)
795*b30d1939SAndy Fiddaman # define Tracevv(x)
796*b30d1939SAndy Fiddaman # define Tracec(c,x)
797*b30d1939SAndy Fiddaman # define Tracecv(c,x)
798*b30d1939SAndy Fiddaman #endif
799*b30d1939SAndy Fiddaman
800*b30d1939SAndy Fiddaman
801*b30d1939SAndy Fiddaman voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
802*b30d1939SAndy Fiddaman void zcfree OF((voidpf opaque, voidpf ptr));
803*b30d1939SAndy Fiddaman
804*b30d1939SAndy Fiddaman #define ZALLOC(strm, items, size) \
805*b30d1939SAndy Fiddaman (*((strm)->zalloc))((strm)->opaque, (items), (size))
806*b30d1939SAndy Fiddaman #define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
807*b30d1939SAndy Fiddaman #define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
808*b30d1939SAndy Fiddaman #endif /* _ZUTIL_H */
809*b30d1939SAndy Fiddaman
810*b30d1939SAndy Fiddaman #ifndef _ZUTIL_C
811*b30d1939SAndy Fiddaman #define _ZUTIL_C
812*b30d1939SAndy Fiddaman
813*b30d1939SAndy Fiddaman #if 0 && !_PACKAGE_ast && !defined(STDC)
814*b30d1939SAndy Fiddaman extern void exit OF((int));
815*b30d1939SAndy Fiddaman #endif
816*b30d1939SAndy Fiddaman
817*b30d1939SAndy Fiddaman #ifndef HAVE_MEMCPY
818*b30d1939SAndy Fiddaman
zmemcpy(dest,source,len)819*b30d1939SAndy Fiddaman void zmemcpy(dest, source, len)
820*b30d1939SAndy Fiddaman Bytef* dest;
821*b30d1939SAndy Fiddaman const Bytef* source;
822*b30d1939SAndy Fiddaman uInt len;
823*b30d1939SAndy Fiddaman {
824*b30d1939SAndy Fiddaman if (len == 0) return;
825*b30d1939SAndy Fiddaman do {
826*b30d1939SAndy Fiddaman *dest++ = *source++; /* ??? to be unrolled */
827*b30d1939SAndy Fiddaman } while (--len != 0);
828*b30d1939SAndy Fiddaman }
829*b30d1939SAndy Fiddaman
zmemcmp(s1,s2,len)830*b30d1939SAndy Fiddaman int zmemcmp(s1, s2, len)
831*b30d1939SAndy Fiddaman const Bytef* s1;
832*b30d1939SAndy Fiddaman const Bytef* s2;
833*b30d1939SAndy Fiddaman uInt len;
834*b30d1939SAndy Fiddaman {
835*b30d1939SAndy Fiddaman uInt j;
836*b30d1939SAndy Fiddaman
837*b30d1939SAndy Fiddaman for (j = 0; j < len; j++) {
838*b30d1939SAndy Fiddaman if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
839*b30d1939SAndy Fiddaman }
840*b30d1939SAndy Fiddaman return 0;
841*b30d1939SAndy Fiddaman }
842*b30d1939SAndy Fiddaman
zmemzero(dest,len)843*b30d1939SAndy Fiddaman void zmemzero(dest, len)
844*b30d1939SAndy Fiddaman Bytef* dest;
845*b30d1939SAndy Fiddaman uInt len;
846*b30d1939SAndy Fiddaman {
847*b30d1939SAndy Fiddaman if (len == 0) return;
848*b30d1939SAndy Fiddaman do {
849*b30d1939SAndy Fiddaman *dest++ = 0; /* ??? to be unrolled */
850*b30d1939SAndy Fiddaman } while (--len != 0);
851*b30d1939SAndy Fiddaman }
852*b30d1939SAndy Fiddaman #endif
853*b30d1939SAndy Fiddaman
854*b30d1939SAndy Fiddaman
855*b30d1939SAndy Fiddaman #ifdef SYS16BIT
856*b30d1939SAndy Fiddaman
857*b30d1939SAndy Fiddaman #ifdef __TURBOC__
858*b30d1939SAndy Fiddaman /* Turbo C in 16-bit mode */
859*b30d1939SAndy Fiddaman
860*b30d1939SAndy Fiddaman # define MY_ZCALLOC
861*b30d1939SAndy Fiddaman
862*b30d1939SAndy Fiddaman /* Turbo C malloc() does not allow dynamic allocation of 64K bytes
863*b30d1939SAndy Fiddaman * and farmalloc(64K) returns a pointer with an offset of 8, so we
864*b30d1939SAndy Fiddaman * must fix the pointer. Warning: the pointer must be put back to its
865*b30d1939SAndy Fiddaman * original form in order to free it, use zcfree().
866*b30d1939SAndy Fiddaman */
867*b30d1939SAndy Fiddaman
868*b30d1939SAndy Fiddaman #define MAX_PTR 10
869*b30d1939SAndy Fiddaman /* 10*64K = 640K */
870*b30d1939SAndy Fiddaman
871*b30d1939SAndy Fiddaman local int next_ptr = 0;
872*b30d1939SAndy Fiddaman
873*b30d1939SAndy Fiddaman typedef struct ptr_table_s {
874*b30d1939SAndy Fiddaman voidpf org_ptr;
875*b30d1939SAndy Fiddaman voidpf new_ptr;
876*b30d1939SAndy Fiddaman } ptr_table;
877*b30d1939SAndy Fiddaman
878*b30d1939SAndy Fiddaman local ptr_table table[MAX_PTR];
879*b30d1939SAndy Fiddaman /* This table is used to remember the original form of pointers
880*b30d1939SAndy Fiddaman * to large buffers (64K). Such pointers are normalized with a zero offset.
881*b30d1939SAndy Fiddaman * Since MSDOS is not a preemptive multitasking OS, this table is not
882*b30d1939SAndy Fiddaman * protected from concurrent access. This hack doesn't work anyway on
883*b30d1939SAndy Fiddaman * a protected system like OS/2. Use Microsoft C instead.
884*b30d1939SAndy Fiddaman */
885*b30d1939SAndy Fiddaman
zcalloc(voidpf opaque,unsigned items,unsigned size)886*b30d1939SAndy Fiddaman voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
887*b30d1939SAndy Fiddaman {
888*b30d1939SAndy Fiddaman voidpf buf = opaque; /* just to make some compilers happy */
889*b30d1939SAndy Fiddaman ulg bsize = (ulg)items*size;
890*b30d1939SAndy Fiddaman
891*b30d1939SAndy Fiddaman /* If we allocate less than 65520 bytes, we assume that farmalloc
892*b30d1939SAndy Fiddaman * will return a usable pointer which doesn't have to be normalized.
893*b30d1939SAndy Fiddaman */
894*b30d1939SAndy Fiddaman if (bsize < 65520L) {
895*b30d1939SAndy Fiddaman buf = farmalloc(bsize);
896*b30d1939SAndy Fiddaman if (*(ush*)&buf != 0) return buf;
897*b30d1939SAndy Fiddaman } else {
898*b30d1939SAndy Fiddaman buf = farmalloc(bsize + 16L);
899*b30d1939SAndy Fiddaman }
900*b30d1939SAndy Fiddaman if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
901*b30d1939SAndy Fiddaman table[next_ptr].org_ptr = buf;
902*b30d1939SAndy Fiddaman
903*b30d1939SAndy Fiddaman /* Normalize the pointer to seg:0 */
904*b30d1939SAndy Fiddaman *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
905*b30d1939SAndy Fiddaman *(ush*)&buf = 0;
906*b30d1939SAndy Fiddaman table[next_ptr++].new_ptr = buf;
907*b30d1939SAndy Fiddaman return buf;
908*b30d1939SAndy Fiddaman }
909*b30d1939SAndy Fiddaman
zcfree(voidpf opaque,voidpf ptr)910*b30d1939SAndy Fiddaman void zcfree (voidpf opaque, voidpf ptr)
911*b30d1939SAndy Fiddaman {
912*b30d1939SAndy Fiddaman int n;
913*b30d1939SAndy Fiddaman if (*(ush*)&ptr != 0) { /* object < 64K */
914*b30d1939SAndy Fiddaman farfree(ptr);
915*b30d1939SAndy Fiddaman return;
916*b30d1939SAndy Fiddaman }
917*b30d1939SAndy Fiddaman /* Find the original pointer */
918*b30d1939SAndy Fiddaman for (n = 0; n < next_ptr; n++) {
919*b30d1939SAndy Fiddaman if (ptr != table[n].new_ptr) continue;
920*b30d1939SAndy Fiddaman
921*b30d1939SAndy Fiddaman farfree(table[n].org_ptr);
922*b30d1939SAndy Fiddaman while (++n < next_ptr) {
923*b30d1939SAndy Fiddaman table[n-1] = table[n];
924*b30d1939SAndy Fiddaman }
925*b30d1939SAndy Fiddaman next_ptr--;
926*b30d1939SAndy Fiddaman return;
927*b30d1939SAndy Fiddaman }
928*b30d1939SAndy Fiddaman ptr = opaque; /* just to make some compilers happy */
929*b30d1939SAndy Fiddaman Assert(0, "zcfree: ptr not found");
930*b30d1939SAndy Fiddaman }
931*b30d1939SAndy Fiddaman
932*b30d1939SAndy Fiddaman #endif /* __TURBOC__ */
933*b30d1939SAndy Fiddaman
934*b30d1939SAndy Fiddaman
935*b30d1939SAndy Fiddaman #ifdef M_I86
936*b30d1939SAndy Fiddaman /* Microsoft C in 16-bit mode */
937*b30d1939SAndy Fiddaman
938*b30d1939SAndy Fiddaman # define MY_ZCALLOC
939*b30d1939SAndy Fiddaman
940*b30d1939SAndy Fiddaman #if (!defined(_MSC_VER) || (_MSC_VER <= 600))
941*b30d1939SAndy Fiddaman # define _halloc halloc
942*b30d1939SAndy Fiddaman # define _hfree hfree
943*b30d1939SAndy Fiddaman #endif
944*b30d1939SAndy Fiddaman
zcalloc(voidpf opaque,unsigned items,unsigned size)945*b30d1939SAndy Fiddaman voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
946*b30d1939SAndy Fiddaman {
947*b30d1939SAndy Fiddaman if (opaque) opaque = 0; /* to make compiler happy */
948*b30d1939SAndy Fiddaman return _halloc((long)items, size);
949*b30d1939SAndy Fiddaman }
950*b30d1939SAndy Fiddaman
zcfree(voidpf opaque,voidpf ptr)951*b30d1939SAndy Fiddaman void zcfree (voidpf opaque, voidpf ptr)
952*b30d1939SAndy Fiddaman {
953*b30d1939SAndy Fiddaman if (opaque) opaque = 0; /* to make compiler happy */
954*b30d1939SAndy Fiddaman _hfree(ptr);
955*b30d1939SAndy Fiddaman }
956*b30d1939SAndy Fiddaman
957*b30d1939SAndy Fiddaman #endif /* M_I86 */
958*b30d1939SAndy Fiddaman
959*b30d1939SAndy Fiddaman #endif /* SYS16BIT */
960*b30d1939SAndy Fiddaman
961*b30d1939SAndy Fiddaman
962*b30d1939SAndy Fiddaman #ifndef MY_ZCALLOC /* Any system without a special alloc function */
963*b30d1939SAndy Fiddaman
964*b30d1939SAndy Fiddaman #if 0 && !_PACKAGE_ast
965*b30d1939SAndy Fiddaman #ifndef STDC
966*b30d1939SAndy Fiddaman extern voidp malloc OF((uInt size));
967*b30d1939SAndy Fiddaman extern voidp calloc OF((uInt items, uInt size));
968*b30d1939SAndy Fiddaman extern void free OF((voidpf ptr));
969*b30d1939SAndy Fiddaman #endif
970*b30d1939SAndy Fiddaman #endif
971*b30d1939SAndy Fiddaman
zcalloc(opaque,items,size)972*b30d1939SAndy Fiddaman voidpf zcalloc (opaque, items, size)
973*b30d1939SAndy Fiddaman voidpf opaque;
974*b30d1939SAndy Fiddaman unsigned items;
975*b30d1939SAndy Fiddaman unsigned size;
976*b30d1939SAndy Fiddaman {
977*b30d1939SAndy Fiddaman if (opaque) items += size - size; /* make compiler happy */
978*b30d1939SAndy Fiddaman return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
979*b30d1939SAndy Fiddaman (voidpf)calloc(items, size);
980*b30d1939SAndy Fiddaman }
981*b30d1939SAndy Fiddaman
zcfree(opaque,ptr)982*b30d1939SAndy Fiddaman void zcfree (opaque, ptr)
983*b30d1939SAndy Fiddaman voidpf opaque;
984*b30d1939SAndy Fiddaman voidpf ptr;
985*b30d1939SAndy Fiddaman {
986*b30d1939SAndy Fiddaman free(ptr);
987*b30d1939SAndy Fiddaman if (opaque) return; /* make compiler happy */
988*b30d1939SAndy Fiddaman }
989*b30d1939SAndy Fiddaman
990*b30d1939SAndy Fiddaman #endif /* MY_ZCALLOC */
991*b30d1939SAndy Fiddaman
992*b30d1939SAndy Fiddaman #endif /* _ZUTIL_C */
993*b30d1939SAndy Fiddaman
994*b30d1939SAndy Fiddaman #ifndef _CRC32_H
995*b30d1939SAndy Fiddaman #define _CRC32_H 1
996*b30d1939SAndy Fiddaman
997*b30d1939SAndy Fiddaman /* crc32.h -- tables for rapid CRC calculation
998*b30d1939SAndy Fiddaman * Generated automatically by crc32.c
999*b30d1939SAndy Fiddaman */
1000*b30d1939SAndy Fiddaman
1001*b30d1939SAndy Fiddaman #ifndef TBLS
1002*b30d1939SAndy Fiddaman #define TBLS 1
1003*b30d1939SAndy Fiddaman #endif
1004*b30d1939SAndy Fiddaman
1005*b30d1939SAndy Fiddaman local const unsigned long FAR crc_table[TBLS][256] =
1006*b30d1939SAndy Fiddaman {
1007*b30d1939SAndy Fiddaman {
1008*b30d1939SAndy Fiddaman 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
1009*b30d1939SAndy Fiddaman 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
1010*b30d1939SAndy Fiddaman 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
1011*b30d1939SAndy Fiddaman 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
1012*b30d1939SAndy Fiddaman 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
1013*b30d1939SAndy Fiddaman 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
1014*b30d1939SAndy Fiddaman 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
1015*b30d1939SAndy Fiddaman 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
1016*b30d1939SAndy Fiddaman 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
1017*b30d1939SAndy Fiddaman 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
1018*b30d1939SAndy Fiddaman 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
1019*b30d1939SAndy Fiddaman 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
1020*b30d1939SAndy Fiddaman 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
1021*b30d1939SAndy Fiddaman 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
1022*b30d1939SAndy Fiddaman 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
1023*b30d1939SAndy Fiddaman 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
1024*b30d1939SAndy Fiddaman 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
1025*b30d1939SAndy Fiddaman 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
1026*b30d1939SAndy Fiddaman 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
1027*b30d1939SAndy Fiddaman 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
1028*b30d1939SAndy Fiddaman 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
1029*b30d1939SAndy Fiddaman 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
1030*b30d1939SAndy Fiddaman 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
1031*b30d1939SAndy Fiddaman 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
1032*b30d1939SAndy Fiddaman 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
1033*b30d1939SAndy Fiddaman 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
1034*b30d1939SAndy Fiddaman 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
1035*b30d1939SAndy Fiddaman 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
1036*b30d1939SAndy Fiddaman 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
1037*b30d1939SAndy Fiddaman 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
1038*b30d1939SAndy Fiddaman 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
1039*b30d1939SAndy Fiddaman 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
1040*b30d1939SAndy Fiddaman 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
1041*b30d1939SAndy Fiddaman 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
1042*b30d1939SAndy Fiddaman 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
1043*b30d1939SAndy Fiddaman 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
1044*b30d1939SAndy Fiddaman 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
1045*b30d1939SAndy Fiddaman 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
1046*b30d1939SAndy Fiddaman 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
1047*b30d1939SAndy Fiddaman 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
1048*b30d1939SAndy Fiddaman 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
1049*b30d1939SAndy Fiddaman 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
1050*b30d1939SAndy Fiddaman 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
1051*b30d1939SAndy Fiddaman 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
1052*b30d1939SAndy Fiddaman 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
1053*b30d1939SAndy Fiddaman 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
1054*b30d1939SAndy Fiddaman 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
1055*b30d1939SAndy Fiddaman 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
1056*b30d1939SAndy Fiddaman 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
1057*b30d1939SAndy Fiddaman 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
1058*b30d1939SAndy Fiddaman 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
1059*b30d1939SAndy Fiddaman 0x2d02ef8d
1060*b30d1939SAndy Fiddaman },
1061*b30d1939SAndy Fiddaman };
1062*b30d1939SAndy Fiddaman
1063*b30d1939SAndy Fiddaman #endif /* _CRC32_H */
1064*b30d1939SAndy Fiddaman
1065*b30d1939SAndy Fiddaman #ifndef _CRC32_C
1066*b30d1939SAndy Fiddaman #define _CRC32_C 1
1067*b30d1939SAndy Fiddaman
1068*b30d1939SAndy Fiddaman /* ========================================================================= */
1069*b30d1939SAndy Fiddaman #define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
1070*b30d1939SAndy Fiddaman #define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
1071*b30d1939SAndy Fiddaman
1072*b30d1939SAndy Fiddaman /* ========================================================================= */
crc32(crc,buf,len)1073*b30d1939SAndy Fiddaman unsigned long ZEXPORT crc32(crc, buf, len)
1074*b30d1939SAndy Fiddaman unsigned long crc;
1075*b30d1939SAndy Fiddaman const unsigned char FAR *buf;
1076*b30d1939SAndy Fiddaman unsigned len;
1077*b30d1939SAndy Fiddaman {
1078*b30d1939SAndy Fiddaman if (buf == Z_NULL) return 0;
1079*b30d1939SAndy Fiddaman
1080*b30d1939SAndy Fiddaman #ifdef DYNAMIC_CRC_TABLE
1081*b30d1939SAndy Fiddaman if (crc_table_empty)
1082*b30d1939SAndy Fiddaman make_crc_table();
1083*b30d1939SAndy Fiddaman #endif /* DYNAMIC_CRC_TABLE */
1084*b30d1939SAndy Fiddaman
1085*b30d1939SAndy Fiddaman #ifdef BYFOUR
1086*b30d1939SAndy Fiddaman if (sizeof(void *) == sizeof(ptrdiff_t)) {
1087*b30d1939SAndy Fiddaman u4 endian;
1088*b30d1939SAndy Fiddaman
1089*b30d1939SAndy Fiddaman endian = 1;
1090*b30d1939SAndy Fiddaman if (*((unsigned char *)(&endian)))
1091*b30d1939SAndy Fiddaman return crc32_little(crc, buf, len);
1092*b30d1939SAndy Fiddaman else
1093*b30d1939SAndy Fiddaman return crc32_big(crc, buf, len);
1094*b30d1939SAndy Fiddaman }
1095*b30d1939SAndy Fiddaman #endif /* BYFOUR */
1096*b30d1939SAndy Fiddaman crc = crc ^ 0xffffffff;
1097*b30d1939SAndy Fiddaman while (len >= 8) {
1098*b30d1939SAndy Fiddaman DO8;
1099*b30d1939SAndy Fiddaman len -= 8;
1100*b30d1939SAndy Fiddaman }
1101*b30d1939SAndy Fiddaman if (len) do {
1102*b30d1939SAndy Fiddaman DO1;
1103*b30d1939SAndy Fiddaman } while (--len);
1104*b30d1939SAndy Fiddaman return crc ^ 0xffffffff;
1105*b30d1939SAndy Fiddaman }
1106*b30d1939SAndy Fiddaman
1107*b30d1939SAndy Fiddaman #undef DO1
1108*b30d1939SAndy Fiddaman #undef DO8
1109*b30d1939SAndy Fiddaman
1110*b30d1939SAndy Fiddaman #endif /* _CRC32_C */
1111*b30d1939SAndy Fiddaman
1112*b30d1939SAndy Fiddaman #ifndef _ADLER32_C
1113*b30d1939SAndy Fiddaman #define _ADLER32_C 1
1114*b30d1939SAndy Fiddaman
1115*b30d1939SAndy Fiddaman #define BASE 65521 /* largest prime smaller than 65536 */
1116*b30d1939SAndy Fiddaman #define NMAX 5552
1117*b30d1939SAndy Fiddaman /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
1118*b30d1939SAndy Fiddaman
1119*b30d1939SAndy Fiddaman #define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
1120*b30d1939SAndy Fiddaman #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
1121*b30d1939SAndy Fiddaman #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
1122*b30d1939SAndy Fiddaman #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
1123*b30d1939SAndy Fiddaman #define DO16(buf) DO8(buf,0); DO8(buf,8);
1124*b30d1939SAndy Fiddaman
1125*b30d1939SAndy Fiddaman /* use NO_DIVIDE if your processor does not do division in hardware */
1126*b30d1939SAndy Fiddaman #ifdef NO_DIVIDE
1127*b30d1939SAndy Fiddaman # define MOD(a) \
1128*b30d1939SAndy Fiddaman do { \
1129*b30d1939SAndy Fiddaman if (a >= (BASE << 16)) a -= (BASE << 16); \
1130*b30d1939SAndy Fiddaman if (a >= (BASE << 15)) a -= (BASE << 15); \
1131*b30d1939SAndy Fiddaman if (a >= (BASE << 14)) a -= (BASE << 14); \
1132*b30d1939SAndy Fiddaman if (a >= (BASE << 13)) a -= (BASE << 13); \
1133*b30d1939SAndy Fiddaman if (a >= (BASE << 12)) a -= (BASE << 12); \
1134*b30d1939SAndy Fiddaman if (a >= (BASE << 11)) a -= (BASE << 11); \
1135*b30d1939SAndy Fiddaman if (a >= (BASE << 10)) a -= (BASE << 10); \
1136*b30d1939SAndy Fiddaman if (a >= (BASE << 9)) a -= (BASE << 9); \
1137*b30d1939SAndy Fiddaman if (a >= (BASE << 8)) a -= (BASE << 8); \
1138*b30d1939SAndy Fiddaman if (a >= (BASE << 7)) a -= (BASE << 7); \
1139*b30d1939SAndy Fiddaman if (a >= (BASE << 6)) a -= (BASE << 6); \
1140*b30d1939SAndy Fiddaman if (a >= (BASE << 5)) a -= (BASE << 5); \
1141*b30d1939SAndy Fiddaman if (a >= (BASE << 4)) a -= (BASE << 4); \
1142*b30d1939SAndy Fiddaman if (a >= (BASE << 3)) a -= (BASE << 3); \
1143*b30d1939SAndy Fiddaman if (a >= (BASE << 2)) a -= (BASE << 2); \
1144*b30d1939SAndy Fiddaman if (a >= (BASE << 1)) a -= (BASE << 1); \
1145*b30d1939SAndy Fiddaman if (a >= BASE) a -= BASE; \
1146*b30d1939SAndy Fiddaman } while (0)
1147*b30d1939SAndy Fiddaman # define MOD4(a) \
1148*b30d1939SAndy Fiddaman do { \
1149*b30d1939SAndy Fiddaman if (a >= (BASE << 4)) a -= (BASE << 4); \
1150*b30d1939SAndy Fiddaman if (a >= (BASE << 3)) a -= (BASE << 3); \
1151*b30d1939SAndy Fiddaman if (a >= (BASE << 2)) a -= (BASE << 2); \
1152*b30d1939SAndy Fiddaman if (a >= (BASE << 1)) a -= (BASE << 1); \
1153*b30d1939SAndy Fiddaman if (a >= BASE) a -= BASE; \
1154*b30d1939SAndy Fiddaman } while (0)
1155*b30d1939SAndy Fiddaman #else
1156*b30d1939SAndy Fiddaman # define MOD(a) a %= BASE
1157*b30d1939SAndy Fiddaman # define MOD4(a) a %= BASE
1158*b30d1939SAndy Fiddaman #endif
1159*b30d1939SAndy Fiddaman
1160*b30d1939SAndy Fiddaman /* ========================================================================= */
adler32(adler,buf,len)1161*b30d1939SAndy Fiddaman uLong ZEXPORT adler32(adler, buf, len)
1162*b30d1939SAndy Fiddaman uLong adler;
1163*b30d1939SAndy Fiddaman const Bytef *buf;
1164*b30d1939SAndy Fiddaman uInt len;
1165*b30d1939SAndy Fiddaman {
1166*b30d1939SAndy Fiddaman unsigned long sum2;
1167*b30d1939SAndy Fiddaman unsigned n;
1168*b30d1939SAndy Fiddaman
1169*b30d1939SAndy Fiddaman /* split Adler-32 into component sums */
1170*b30d1939SAndy Fiddaman sum2 = (adler >> 16) & 0xffff;
1171*b30d1939SAndy Fiddaman adler &= 0xffff;
1172*b30d1939SAndy Fiddaman
1173*b30d1939SAndy Fiddaman /* in case user likes doing a byte at a time, keep it fast */
1174*b30d1939SAndy Fiddaman if (len == 1) {
1175*b30d1939SAndy Fiddaman adler += buf[0];
1176*b30d1939SAndy Fiddaman if (adler >= BASE)
1177*b30d1939SAndy Fiddaman adler -= BASE;
1178*b30d1939SAndy Fiddaman sum2 += adler;
1179*b30d1939SAndy Fiddaman if (sum2 >= BASE)
1180*b30d1939SAndy Fiddaman sum2 -= BASE;
1181*b30d1939SAndy Fiddaman return adler | (sum2 << 16);
1182*b30d1939SAndy Fiddaman }
1183*b30d1939SAndy Fiddaman
1184*b30d1939SAndy Fiddaman /* initial Adler-32 value (deferred check for len == 1 speed) */
1185*b30d1939SAndy Fiddaman if (buf == Z_NULL)
1186*b30d1939SAndy Fiddaman return 1L;
1187*b30d1939SAndy Fiddaman
1188*b30d1939SAndy Fiddaman /* in case short lengths are provided, keep it somewhat fast */
1189*b30d1939SAndy Fiddaman if (len < 16) {
1190*b30d1939SAndy Fiddaman while (len--) {
1191*b30d1939SAndy Fiddaman adler += *buf++;
1192*b30d1939SAndy Fiddaman sum2 += adler;
1193*b30d1939SAndy Fiddaman }
1194*b30d1939SAndy Fiddaman if (adler >= BASE)
1195*b30d1939SAndy Fiddaman adler -= BASE;
1196*b30d1939SAndy Fiddaman MOD4(sum2); /* only added so many BASE's */
1197*b30d1939SAndy Fiddaman return adler | (sum2 << 16);
1198*b30d1939SAndy Fiddaman }
1199*b30d1939SAndy Fiddaman
1200*b30d1939SAndy Fiddaman /* do length NMAX blocks -- requires just one modulo operation */
1201*b30d1939SAndy Fiddaman while (len >= NMAX) {
1202*b30d1939SAndy Fiddaman len -= NMAX;
1203*b30d1939SAndy Fiddaman n = NMAX / 16; /* NMAX is divisible by 16 */
1204*b30d1939SAndy Fiddaman do {
1205*b30d1939SAndy Fiddaman DO16(buf); /* 16 sums unrolled */
1206*b30d1939SAndy Fiddaman buf += 16;
1207*b30d1939SAndy Fiddaman } while (--n);
1208*b30d1939SAndy Fiddaman MOD(adler);
1209*b30d1939SAndy Fiddaman MOD(sum2);
1210*b30d1939SAndy Fiddaman }
1211*b30d1939SAndy Fiddaman
1212*b30d1939SAndy Fiddaman /* do remaining bytes (less than NMAX, still just one modulo) */
1213*b30d1939SAndy Fiddaman if (len) { /* avoid modulos if none remaining */
1214*b30d1939SAndy Fiddaman while (len >= 16) {
1215*b30d1939SAndy Fiddaman len -= 16;
1216*b30d1939SAndy Fiddaman DO16(buf);
1217*b30d1939SAndy Fiddaman buf += 16;
1218*b30d1939SAndy Fiddaman }
1219*b30d1939SAndy Fiddaman while (len--) {
1220*b30d1939SAndy Fiddaman adler += *buf++;
1221*b30d1939SAndy Fiddaman sum2 += adler;
1222*b30d1939SAndy Fiddaman }
1223*b30d1939SAndy Fiddaman MOD(adler);
1224*b30d1939SAndy Fiddaman MOD(sum2);
1225*b30d1939SAndy Fiddaman }
1226*b30d1939SAndy Fiddaman
1227*b30d1939SAndy Fiddaman /* return recombined sums */
1228*b30d1939SAndy Fiddaman return adler | (sum2 << 16);
1229*b30d1939SAndy Fiddaman }
1230*b30d1939SAndy Fiddaman
1231*b30d1939SAndy Fiddaman #endif /* _ADLER32_C */
1232*b30d1939SAndy Fiddaman
1233*b30d1939SAndy Fiddaman #ifndef _DEFLATE_H
1234*b30d1939SAndy Fiddaman #define _DEFLATE_H 1
1235*b30d1939SAndy Fiddaman
1236*b30d1939SAndy Fiddaman /* ===========================================================================
1237*b30d1939SAndy Fiddaman * Internal compression state.
1238*b30d1939SAndy Fiddaman */
1239*b30d1939SAndy Fiddaman
1240*b30d1939SAndy Fiddaman #define LENGTH_CODES 29
1241*b30d1939SAndy Fiddaman /* number of length codes, not counting the special END_BLOCK code */
1242*b30d1939SAndy Fiddaman
1243*b30d1939SAndy Fiddaman #define LITERALS 256
1244*b30d1939SAndy Fiddaman /* number of literal bytes 0..255 */
1245*b30d1939SAndy Fiddaman
1246*b30d1939SAndy Fiddaman #define L_CODES (LITERALS+1+LENGTH_CODES)
1247*b30d1939SAndy Fiddaman /* number of Literal or Length codes, including the END_BLOCK code */
1248*b30d1939SAndy Fiddaman
1249*b30d1939SAndy Fiddaman #define D_CODES 30
1250*b30d1939SAndy Fiddaman /* number of distance codes */
1251*b30d1939SAndy Fiddaman
1252*b30d1939SAndy Fiddaman #define BL_CODES 19
1253*b30d1939SAndy Fiddaman /* number of codes used to transfer the bit lengths */
1254*b30d1939SAndy Fiddaman
1255*b30d1939SAndy Fiddaman #define HEAP_SIZE (2*L_CODES+1)
1256*b30d1939SAndy Fiddaman /* maximum heap size */
1257*b30d1939SAndy Fiddaman
1258*b30d1939SAndy Fiddaman #define MAX_BITS 15
1259*b30d1939SAndy Fiddaman /* All codes must not exceed MAX_BITS bits */
1260*b30d1939SAndy Fiddaman
1261*b30d1939SAndy Fiddaman #define INIT_STATE 42
1262*b30d1939SAndy Fiddaman #define EXTRA_STATE 69
1263*b30d1939SAndy Fiddaman #define NAME_STATE 73
1264*b30d1939SAndy Fiddaman #define COMMENT_STATE 91
1265*b30d1939SAndy Fiddaman #define HCRC_STATE 103
1266*b30d1939SAndy Fiddaman #define BUSY_STATE 113
1267*b30d1939SAndy Fiddaman #define FINISH_STATE 666
1268*b30d1939SAndy Fiddaman /* Stream status */
1269*b30d1939SAndy Fiddaman
1270*b30d1939SAndy Fiddaman
1271*b30d1939SAndy Fiddaman /* Data structure describing a single value and its code string. */
1272*b30d1939SAndy Fiddaman typedef struct ct_data_s {
1273*b30d1939SAndy Fiddaman union {
1274*b30d1939SAndy Fiddaman ush freq; /* frequency count */
1275*b30d1939SAndy Fiddaman ush code; /* bit string */
1276*b30d1939SAndy Fiddaman } fc;
1277*b30d1939SAndy Fiddaman union {
1278*b30d1939SAndy Fiddaman ush dad; /* father node in Huffman tree */
1279*b30d1939SAndy Fiddaman ush len; /* length of bit string */
1280*b30d1939SAndy Fiddaman } dl;
1281*b30d1939SAndy Fiddaman } FAR ct_data;
1282*b30d1939SAndy Fiddaman
1283*b30d1939SAndy Fiddaman #define Freq fc.freq
1284*b30d1939SAndy Fiddaman #define Code fc.code
1285*b30d1939SAndy Fiddaman #define Dad dl.dad
1286*b30d1939SAndy Fiddaman #define Len dl.len
1287*b30d1939SAndy Fiddaman
1288*b30d1939SAndy Fiddaman typedef struct static_tree_desc_s static_tree_desc;
1289*b30d1939SAndy Fiddaman
1290*b30d1939SAndy Fiddaman typedef struct tree_desc_s {
1291*b30d1939SAndy Fiddaman ct_data *dyn_tree; /* the dynamic tree */
1292*b30d1939SAndy Fiddaman int max_code; /* largest code with non zero frequency */
1293*b30d1939SAndy Fiddaman static_tree_desc *stat_desc; /* the corresponding static tree */
1294*b30d1939SAndy Fiddaman } FAR tree_desc;
1295*b30d1939SAndy Fiddaman
1296*b30d1939SAndy Fiddaman typedef ush Pos;
1297*b30d1939SAndy Fiddaman typedef Pos FAR Posf;
1298*b30d1939SAndy Fiddaman typedef unsigned IPos;
1299*b30d1939SAndy Fiddaman
1300*b30d1939SAndy Fiddaman /* A Pos is an index in the character window. We use short instead of int to
1301*b30d1939SAndy Fiddaman * save space in the various tables. IPos is used only for parameter passing.
1302*b30d1939SAndy Fiddaman */
1303*b30d1939SAndy Fiddaman
1304*b30d1939SAndy Fiddaman typedef struct internal_state {
1305*b30d1939SAndy Fiddaman z_streamp strm; /* pointer back to this zlib stream */
1306*b30d1939SAndy Fiddaman int status; /* as the name implies */
1307*b30d1939SAndy Fiddaman Bytef *pending_buf; /* output still pending */
1308*b30d1939SAndy Fiddaman ulg pending_buf_size; /* size of pending_buf */
1309*b30d1939SAndy Fiddaman Bytef *pending_out; /* next pending byte to output to the stream */
1310*b30d1939SAndy Fiddaman uInt pending; /* nb of bytes in the pending buffer */
1311*b30d1939SAndy Fiddaman int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
1312*b30d1939SAndy Fiddaman gz_headerp gzhead; /* gzip header information to write */
1313*b30d1939SAndy Fiddaman uInt gzindex; /* where in extra, name, or comment */
1314*b30d1939SAndy Fiddaman Byte method; /* STORED (for zip only) or DEFLATED */
1315*b30d1939SAndy Fiddaman int last_flush; /* value of flush param for previous deflate call */
1316*b30d1939SAndy Fiddaman
1317*b30d1939SAndy Fiddaman /* used by deflate.c: */
1318*b30d1939SAndy Fiddaman
1319*b30d1939SAndy Fiddaman uInt w_size; /* LZ77 window size (32K by default) */
1320*b30d1939SAndy Fiddaman uInt w_bits; /* log2(w_size) (8..16) */
1321*b30d1939SAndy Fiddaman uInt w_mask; /* w_size - 1 */
1322*b30d1939SAndy Fiddaman
1323*b30d1939SAndy Fiddaman Bytef *window;
1324*b30d1939SAndy Fiddaman /* Sliding window. Input bytes are read into the second half of the window,
1325*b30d1939SAndy Fiddaman * and move to the first half later to keep a dictionary of at least wSize
1326*b30d1939SAndy Fiddaman * bytes. With this organization, matches are limited to a distance of
1327*b30d1939SAndy Fiddaman * wSize-MAX_MATCH bytes, but this ensures that IO is always
1328*b30d1939SAndy Fiddaman * performed with a length multiple of the block size. Also, it limits
1329*b30d1939SAndy Fiddaman * the window size to 64K, which is quite useful on MSDOS.
1330*b30d1939SAndy Fiddaman * To do: use the user input buffer as sliding window.
1331*b30d1939SAndy Fiddaman */
1332*b30d1939SAndy Fiddaman
1333*b30d1939SAndy Fiddaman ulg window_size;
1334*b30d1939SAndy Fiddaman /* Actual size of window: 2*wSize, except when the user input buffer
1335*b30d1939SAndy Fiddaman * is directly used as sliding window.
1336*b30d1939SAndy Fiddaman */
1337*b30d1939SAndy Fiddaman
1338*b30d1939SAndy Fiddaman Posf *prev;
1339*b30d1939SAndy Fiddaman /* Link to older string with same hash index. To limit the size of this
1340*b30d1939SAndy Fiddaman * array to 64K, this link is maintained only for the last 32K strings.
1341*b30d1939SAndy Fiddaman * An index in this array is thus a window index modulo 32K.
1342*b30d1939SAndy Fiddaman */
1343*b30d1939SAndy Fiddaman
1344*b30d1939SAndy Fiddaman Posf *head; /* Heads of the hash chains or NIL. */
1345*b30d1939SAndy Fiddaman
1346*b30d1939SAndy Fiddaman uInt ins_h; /* hash index of string to be inserted */
1347*b30d1939SAndy Fiddaman uInt hash_size; /* number of elements in hash table */
1348*b30d1939SAndy Fiddaman uInt hash_bits; /* log2(hash_size) */
1349*b30d1939SAndy Fiddaman uInt hash_mask; /* hash_size-1 */
1350*b30d1939SAndy Fiddaman
1351*b30d1939SAndy Fiddaman uInt hash_shift;
1352*b30d1939SAndy Fiddaman /* Number of bits by which ins_h must be shifted at each input
1353*b30d1939SAndy Fiddaman * step. It must be such that after MIN_MATCH steps, the oldest
1354*b30d1939SAndy Fiddaman * byte no longer takes part in the hash key, that is:
1355*b30d1939SAndy Fiddaman * hash_shift * MIN_MATCH >= hash_bits
1356*b30d1939SAndy Fiddaman */
1357*b30d1939SAndy Fiddaman
1358*b30d1939SAndy Fiddaman long block_start;
1359*b30d1939SAndy Fiddaman /* Window position at the beginning of the current output block. Gets
1360*b30d1939SAndy Fiddaman * negative when the window is moved backwards.
1361*b30d1939SAndy Fiddaman */
1362*b30d1939SAndy Fiddaman
1363*b30d1939SAndy Fiddaman uInt match_length; /* length of best match */
1364*b30d1939SAndy Fiddaman IPos prev_match; /* previous match */
1365*b30d1939SAndy Fiddaman int match_available; /* set if previous match exists */
1366*b30d1939SAndy Fiddaman uInt strstart; /* start of string to insert */
1367*b30d1939SAndy Fiddaman uInt match_start; /* start of matching string */
1368*b30d1939SAndy Fiddaman uInt lookahead; /* number of valid bytes ahead in window */
1369*b30d1939SAndy Fiddaman
1370*b30d1939SAndy Fiddaman uInt prev_length;
1371*b30d1939SAndy Fiddaman /* Length of the best match at previous step. Matches not greater than this
1372*b30d1939SAndy Fiddaman * are discarded. This is used in the lazy match evaluation.
1373*b30d1939SAndy Fiddaman */
1374*b30d1939SAndy Fiddaman
1375*b30d1939SAndy Fiddaman uInt max_chain_length;
1376*b30d1939SAndy Fiddaman /* To speed up deflation, hash chains are never searched beyond this
1377*b30d1939SAndy Fiddaman * length. A higher limit improves compression ratio but degrades the
1378*b30d1939SAndy Fiddaman * speed.
1379*b30d1939SAndy Fiddaman */
1380*b30d1939SAndy Fiddaman
1381*b30d1939SAndy Fiddaman uInt max_lazy_match;
1382*b30d1939SAndy Fiddaman /* Attempt to find a better match only when the current match is strictly
1383*b30d1939SAndy Fiddaman * smaller than this value. This mechanism is used only for compression
1384*b30d1939SAndy Fiddaman * levels >= 4.
1385*b30d1939SAndy Fiddaman */
1386*b30d1939SAndy Fiddaman # define max_insert_length max_lazy_match
1387*b30d1939SAndy Fiddaman /* Insert new strings in the hash table only if the match length is not
1388*b30d1939SAndy Fiddaman * greater than this length. This saves time but degrades compression.
1389*b30d1939SAndy Fiddaman * max_insert_length is used only for compression levels <= 3.
1390*b30d1939SAndy Fiddaman */
1391*b30d1939SAndy Fiddaman
1392*b30d1939SAndy Fiddaman int level; /* compression level (1..9) */
1393*b30d1939SAndy Fiddaman int strategy; /* favor or force Huffman coding*/
1394*b30d1939SAndy Fiddaman
1395*b30d1939SAndy Fiddaman uInt good_match;
1396*b30d1939SAndy Fiddaman /* Use a faster search when the previous match is longer than this */
1397*b30d1939SAndy Fiddaman
1398*b30d1939SAndy Fiddaman int nice_match; /* Stop searching when current match exceeds this */
1399*b30d1939SAndy Fiddaman
1400*b30d1939SAndy Fiddaman /* used by trees.c: */
1401*b30d1939SAndy Fiddaman /* Didn't use ct_data typedef below to supress compiler warning */
1402*b30d1939SAndy Fiddaman struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
1403*b30d1939SAndy Fiddaman struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
1404*b30d1939SAndy Fiddaman struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
1405*b30d1939SAndy Fiddaman
1406*b30d1939SAndy Fiddaman struct tree_desc_s l_desc; /* desc. for literal tree */
1407*b30d1939SAndy Fiddaman struct tree_desc_s d_desc; /* desc. for distance tree */
1408*b30d1939SAndy Fiddaman struct tree_desc_s bl_desc; /* desc. for bit length tree */
1409*b30d1939SAndy Fiddaman
1410*b30d1939SAndy Fiddaman ush bl_count[MAX_BITS+1];
1411*b30d1939SAndy Fiddaman /* number of codes at each bit length for an optimal tree */
1412*b30d1939SAndy Fiddaman
1413*b30d1939SAndy Fiddaman int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
1414*b30d1939SAndy Fiddaman int heap_len; /* number of elements in the heap */
1415*b30d1939SAndy Fiddaman int heap_max; /* element of largest frequency */
1416*b30d1939SAndy Fiddaman /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
1417*b30d1939SAndy Fiddaman * The same heap array is used to build all trees.
1418*b30d1939SAndy Fiddaman */
1419*b30d1939SAndy Fiddaman
1420*b30d1939SAndy Fiddaman uch depth[2*L_CODES+1];
1421*b30d1939SAndy Fiddaman /* Depth of each subtree used as tie breaker for trees of equal frequency
1422*b30d1939SAndy Fiddaman */
1423*b30d1939SAndy Fiddaman
1424*b30d1939SAndy Fiddaman uchf *l_buf; /* buffer for literals or lengths */
1425*b30d1939SAndy Fiddaman
1426*b30d1939SAndy Fiddaman uInt lit_bufsize;
1427*b30d1939SAndy Fiddaman /* Size of match buffer for literals/lengths. There are 4 reasons for
1428*b30d1939SAndy Fiddaman * limiting lit_bufsize to 64K:
1429*b30d1939SAndy Fiddaman * - frequencies can be kept in 16 bit counters
1430*b30d1939SAndy Fiddaman * - if compression is not successful for the first block, all input
1431*b30d1939SAndy Fiddaman * data is still in the window so we can still emit a stored block even
1432*b30d1939SAndy Fiddaman * when input comes from standard input. (This can also be done for
1433*b30d1939SAndy Fiddaman * all blocks if lit_bufsize is not greater than 32K.)
1434*b30d1939SAndy Fiddaman * - if compression is not successful for a file smaller than 64K, we can
1435*b30d1939SAndy Fiddaman * even emit a stored file instead of a stored block (saving 5 bytes).
1436*b30d1939SAndy Fiddaman * This is applicable only for zip (not gzip or zlib).
1437*b30d1939SAndy Fiddaman * - creating new Huffman trees less frequently may not provide fast
1438*b30d1939SAndy Fiddaman * adaptation to changes in the input data statistics. (Take for
1439*b30d1939SAndy Fiddaman * example a binary file with poorly compressible code followed by
1440*b30d1939SAndy Fiddaman * a highly compressible string table.) Smaller buffer sizes give
1441*b30d1939SAndy Fiddaman * fast adaptation but have of course the overhead of transmitting
1442*b30d1939SAndy Fiddaman * trees more frequently.
1443*b30d1939SAndy Fiddaman * - I can't count above 4
1444*b30d1939SAndy Fiddaman */
1445*b30d1939SAndy Fiddaman
1446*b30d1939SAndy Fiddaman uInt last_lit; /* running index in l_buf */
1447*b30d1939SAndy Fiddaman
1448*b30d1939SAndy Fiddaman ushf *d_buf;
1449*b30d1939SAndy Fiddaman /* Buffer for distances. To simplify the code, d_buf and l_buf have
1450*b30d1939SAndy Fiddaman * the same number of elements. To use different lengths, an extra flag
1451*b30d1939SAndy Fiddaman * array would be necessary.
1452*b30d1939SAndy Fiddaman */
1453*b30d1939SAndy Fiddaman
1454*b30d1939SAndy Fiddaman ulg opt_len; /* bit length of current block with optimal trees */
1455*b30d1939SAndy Fiddaman ulg static_len; /* bit length of current block with static trees */
1456*b30d1939SAndy Fiddaman uInt matches; /* number of string matches in current block */
1457*b30d1939SAndy Fiddaman int last_eob_len; /* bit length of EOB code for last block */
1458*b30d1939SAndy Fiddaman
1459*b30d1939SAndy Fiddaman #ifdef Z_DEBUG
1460*b30d1939SAndy Fiddaman ulg compressed_len; /* total bit length of compressed file mod 2^32 */
1461*b30d1939SAndy Fiddaman ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
1462*b30d1939SAndy Fiddaman #endif
1463*b30d1939SAndy Fiddaman
1464*b30d1939SAndy Fiddaman ush bi_buf;
1465*b30d1939SAndy Fiddaman /* Output buffer. bits are inserted starting at the bottom (least
1466*b30d1939SAndy Fiddaman * significant bits).
1467*b30d1939SAndy Fiddaman */
1468*b30d1939SAndy Fiddaman int bi_valid;
1469*b30d1939SAndy Fiddaman /* Number of valid bits in bi_buf. All bits above the last valid bit
1470*b30d1939SAndy Fiddaman * are always zero.
1471*b30d1939SAndy Fiddaman */
1472*b30d1939SAndy Fiddaman
1473*b30d1939SAndy Fiddaman } FAR deflate_state;
1474*b30d1939SAndy Fiddaman
1475*b30d1939SAndy Fiddaman /* Output a byte on the stream.
1476*b30d1939SAndy Fiddaman * IN assertion: there is enough room in pending_buf.
1477*b30d1939SAndy Fiddaman */
1478*b30d1939SAndy Fiddaman #define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
1479*b30d1939SAndy Fiddaman
1480*b30d1939SAndy Fiddaman
1481*b30d1939SAndy Fiddaman #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
1482*b30d1939SAndy Fiddaman /* Minimum amount of lookahead, except at the end of the input file.
1483*b30d1939SAndy Fiddaman * See deflate.c for comments about the MIN_MATCH+1.
1484*b30d1939SAndy Fiddaman */
1485*b30d1939SAndy Fiddaman
1486*b30d1939SAndy Fiddaman #define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
1487*b30d1939SAndy Fiddaman /* In order to simplify the code, particularly on 16 bit machines, match
1488*b30d1939SAndy Fiddaman * distances are limited to MAX_DIST instead of WSIZE.
1489*b30d1939SAndy Fiddaman */
1490*b30d1939SAndy Fiddaman
1491*b30d1939SAndy Fiddaman /* in trees.c */
1492*b30d1939SAndy Fiddaman void _tr_init OF((deflate_state *s));
1493*b30d1939SAndy Fiddaman int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
1494*b30d1939SAndy Fiddaman void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
1495*b30d1939SAndy Fiddaman int eof));
1496*b30d1939SAndy Fiddaman void _tr_align OF((deflate_state *s));
1497*b30d1939SAndy Fiddaman void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
1498*b30d1939SAndy Fiddaman int eof));
1499*b30d1939SAndy Fiddaman
1500*b30d1939SAndy Fiddaman #define d_code(dist) \
1501*b30d1939SAndy Fiddaman ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
1502*b30d1939SAndy Fiddaman /* Mapping from a distance to a distance code. dist is the distance - 1 and
1503*b30d1939SAndy Fiddaman * must not have side effects. _dist_code[256] and _dist_code[257] are never
1504*b30d1939SAndy Fiddaman * used.
1505*b30d1939SAndy Fiddaman */
1506*b30d1939SAndy Fiddaman
1507*b30d1939SAndy Fiddaman #ifndef Z_DEBUG
1508*b30d1939SAndy Fiddaman /* Inline versions of _tr_tally for speed: */
1509*b30d1939SAndy Fiddaman
1510*b30d1939SAndy Fiddaman #if defined(GEN_TREES_H) || !defined(STDC)
1511*b30d1939SAndy Fiddaman extern uch _length_code[];
1512*b30d1939SAndy Fiddaman extern uch _dist_code[];
1513*b30d1939SAndy Fiddaman #else
1514*b30d1939SAndy Fiddaman extern const uch _length_code[];
1515*b30d1939SAndy Fiddaman extern const uch _dist_code[];
1516*b30d1939SAndy Fiddaman #endif
1517*b30d1939SAndy Fiddaman
1518*b30d1939SAndy Fiddaman # define _tr_tally_lit(s, c, flush) \
1519*b30d1939SAndy Fiddaman { uch cc = (c); \
1520*b30d1939SAndy Fiddaman s->d_buf[s->last_lit] = 0; \
1521*b30d1939SAndy Fiddaman s->l_buf[s->last_lit++] = cc; \
1522*b30d1939SAndy Fiddaman s->dyn_ltree[cc].Freq++; \
1523*b30d1939SAndy Fiddaman flush = (s->last_lit == s->lit_bufsize-1); \
1524*b30d1939SAndy Fiddaman }
1525*b30d1939SAndy Fiddaman # define _tr_tally_dist(s, distance, length, flush) \
1526*b30d1939SAndy Fiddaman { uch len = (length); \
1527*b30d1939SAndy Fiddaman ush dist = (distance); \
1528*b30d1939SAndy Fiddaman s->d_buf[s->last_lit] = dist; \
1529*b30d1939SAndy Fiddaman s->l_buf[s->last_lit++] = len; \
1530*b30d1939SAndy Fiddaman dist--; \
1531*b30d1939SAndy Fiddaman s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
1532*b30d1939SAndy Fiddaman s->dyn_dtree[d_code(dist)].Freq++; \
1533*b30d1939SAndy Fiddaman flush = (s->last_lit == s->lit_bufsize-1); \
1534*b30d1939SAndy Fiddaman }
1535*b30d1939SAndy Fiddaman #else
1536*b30d1939SAndy Fiddaman # define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
1537*b30d1939SAndy Fiddaman # define _tr_tally_dist(s, distance, length, flush) \
1538*b30d1939SAndy Fiddaman flush = _tr_tally(s, distance, length)
1539*b30d1939SAndy Fiddaman #endif
1540*b30d1939SAndy Fiddaman
1541*b30d1939SAndy Fiddaman #endif /* _DEFLATE_H */
1542*b30d1939SAndy Fiddaman
1543*b30d1939SAndy Fiddaman #ifndef _INFTREES_H
1544*b30d1939SAndy Fiddaman #define _INFTREES_H 1
1545*b30d1939SAndy Fiddaman
1546*b30d1939SAndy Fiddaman typedef struct {
1547*b30d1939SAndy Fiddaman unsigned char op; /* operation, extra bits, table bits */
1548*b30d1939SAndy Fiddaman unsigned char bits; /* bits in this part of the code */
1549*b30d1939SAndy Fiddaman unsigned short val; /* offset in table or code value */
1550*b30d1939SAndy Fiddaman } code;
1551*b30d1939SAndy Fiddaman
1552*b30d1939SAndy Fiddaman /* op values as set by inflate_table():
1553*b30d1939SAndy Fiddaman 00000000 - literal
1554*b30d1939SAndy Fiddaman 0000tttt - table link, tttt != 0 is the number of table index bits
1555*b30d1939SAndy Fiddaman 0001eeee - length or distance, eeee is the number of extra bits
1556*b30d1939SAndy Fiddaman 01100000 - end of block
1557*b30d1939SAndy Fiddaman 01000000 - invalid code
1558*b30d1939SAndy Fiddaman */
1559*b30d1939SAndy Fiddaman
1560*b30d1939SAndy Fiddaman /* Maximum size of dynamic tree. The maximum found in a long but non-
1561*b30d1939SAndy Fiddaman exhaustive search was 1444 code structures (852 for length/literals
1562*b30d1939SAndy Fiddaman and 592 for distances, the latter actually the result of an
1563*b30d1939SAndy Fiddaman exhaustive search). The true maximum is not known, but the value
1564*b30d1939SAndy Fiddaman below is more than safe. */
1565*b30d1939SAndy Fiddaman #define ENOUGH 2048
1566*b30d1939SAndy Fiddaman #define MAXD 592
1567*b30d1939SAndy Fiddaman
1568*b30d1939SAndy Fiddaman /* Type of code to build for inftable() */
1569*b30d1939SAndy Fiddaman typedef enum {
1570*b30d1939SAndy Fiddaman CODES,
1571*b30d1939SAndy Fiddaman LENS,
1572*b30d1939SAndy Fiddaman DISTS
1573*b30d1939SAndy Fiddaman } codetype;
1574*b30d1939SAndy Fiddaman
1575*b30d1939SAndy Fiddaman #endif /* _INFTREES_H */
1576*b30d1939SAndy Fiddaman
1577*b30d1939SAndy Fiddaman #ifndef _INFLATE_H
1578*b30d1939SAndy Fiddaman #define _INFLATE_H 1
1579*b30d1939SAndy Fiddaman
1580*b30d1939SAndy Fiddaman /* Possible inflate modes between inflate() calls */
1581*b30d1939SAndy Fiddaman typedef enum {
1582*b30d1939SAndy Fiddaman HEAD, /* i: waiting for magic header */
1583*b30d1939SAndy Fiddaman FLAGS, /* i: waiting for method and flags (gzip) */
1584*b30d1939SAndy Fiddaman TIME, /* i: waiting for modification time (gzip) */
1585*b30d1939SAndy Fiddaman OS, /* i: waiting for extra flags and operating system (gzip) */
1586*b30d1939SAndy Fiddaman EXLEN, /* i: waiting for extra length (gzip) */
1587*b30d1939SAndy Fiddaman EXTRA, /* i: waiting for extra bytes (gzip) */
1588*b30d1939SAndy Fiddaman NAME, /* i: waiting for end of file name (gzip) */
1589*b30d1939SAndy Fiddaman COMMENT, /* i: waiting for end of comment (gzip) */
1590*b30d1939SAndy Fiddaman HCRC, /* i: waiting for header crc (gzip) */
1591*b30d1939SAndy Fiddaman DICTID, /* i: waiting for dictionary check value */
1592*b30d1939SAndy Fiddaman DICT, /* waiting for inflateSetDictionary() call */
1593*b30d1939SAndy Fiddaman TYPE, /* i: waiting for type bits, including last-flag bit */
1594*b30d1939SAndy Fiddaman TYPEDO, /* i: same, but skip check to exit inflate on new block */
1595*b30d1939SAndy Fiddaman STORED, /* i: waiting for stored size (length and complement) */
1596*b30d1939SAndy Fiddaman COPY, /* i/o: waiting for input or output to copy stored block */
1597*b30d1939SAndy Fiddaman TABLE, /* i: waiting for dynamic block table lengths */
1598*b30d1939SAndy Fiddaman LENLENS, /* i: waiting for code length code lengths */
1599*b30d1939SAndy Fiddaman CODELENS, /* i: waiting for length/lit and distance code lengths */
1600*b30d1939SAndy Fiddaman LEN, /* i: waiting for length/lit code */
1601*b30d1939SAndy Fiddaman LENEXT, /* i: waiting for length extra bits */
1602*b30d1939SAndy Fiddaman DIST, /* i: waiting for distance code */
1603*b30d1939SAndy Fiddaman DISTEXT, /* i: waiting for distance extra bits */
1604*b30d1939SAndy Fiddaman MATCH, /* o: waiting for output space to copy string */
1605*b30d1939SAndy Fiddaman LIT, /* o: waiting for output space to write literal */
1606*b30d1939SAndy Fiddaman CHECK, /* i: waiting for 32-bit check value */
1607*b30d1939SAndy Fiddaman LENGTH, /* i: waiting for 32-bit length (gzip) */
1608*b30d1939SAndy Fiddaman DONE, /* finished check, done -- remain here until reset */
1609*b30d1939SAndy Fiddaman BAD, /* got a data error -- remain here until reset */
1610*b30d1939SAndy Fiddaman MEM, /* got an inflate() memory error -- remain here until reset */
1611*b30d1939SAndy Fiddaman SYNC /* looking for synchronization bytes to restart inflate() */
1612*b30d1939SAndy Fiddaman } inflate_mode;
1613*b30d1939SAndy Fiddaman
1614*b30d1939SAndy Fiddaman /*
1615*b30d1939SAndy Fiddaman State transitions between above modes -
1616*b30d1939SAndy Fiddaman
1617*b30d1939SAndy Fiddaman (most modes can go to the BAD or MEM mode -- not shown for clarity)
1618*b30d1939SAndy Fiddaman
1619*b30d1939SAndy Fiddaman Process header:
1620*b30d1939SAndy Fiddaman HEAD -> (gzip) or (zlib)
1621*b30d1939SAndy Fiddaman (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
1622*b30d1939SAndy Fiddaman NAME -> COMMENT -> HCRC -> TYPE
1623*b30d1939SAndy Fiddaman (zlib) -> DICTID or TYPE
1624*b30d1939SAndy Fiddaman DICTID -> DICT -> TYPE
1625*b30d1939SAndy Fiddaman Read deflate blocks:
1626*b30d1939SAndy Fiddaman TYPE -> STORED or TABLE or LEN or CHECK
1627*b30d1939SAndy Fiddaman STORED -> COPY -> TYPE
1628*b30d1939SAndy Fiddaman TABLE -> LENLENS -> CODELENS -> LEN
1629*b30d1939SAndy Fiddaman Read deflate codes:
1630*b30d1939SAndy Fiddaman LEN -> LENEXT or LIT or TYPE
1631*b30d1939SAndy Fiddaman LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
1632*b30d1939SAndy Fiddaman LIT -> LEN
1633*b30d1939SAndy Fiddaman Process trailer:
1634*b30d1939SAndy Fiddaman CHECK -> LENGTH -> DONE
1635*b30d1939SAndy Fiddaman */
1636*b30d1939SAndy Fiddaman
1637*b30d1939SAndy Fiddaman /* state maintained between inflate() calls. Approximately 7K bytes. */
1638*b30d1939SAndy Fiddaman struct inflate_state {
1639*b30d1939SAndy Fiddaman inflate_mode mode; /* current inflate mode */
1640*b30d1939SAndy Fiddaman int last; /* true if processing last block */
1641*b30d1939SAndy Fiddaman int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
1642*b30d1939SAndy Fiddaman int havedict; /* true if dictionary provided */
1643*b30d1939SAndy Fiddaman int flags; /* gzip header method and flags (0 if zlib) */
1644*b30d1939SAndy Fiddaman unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
1645*b30d1939SAndy Fiddaman unsigned long check; /* protected copy of check value */
1646*b30d1939SAndy Fiddaman unsigned long total; /* protected copy of output count */
1647*b30d1939SAndy Fiddaman gz_headerp head; /* where to save gzip header information */
1648*b30d1939SAndy Fiddaman /* sliding window */
1649*b30d1939SAndy Fiddaman unsigned wbits; /* log base 2 of requested window size */
1650*b30d1939SAndy Fiddaman unsigned wsize; /* window size or zero if not using window */
1651*b30d1939SAndy Fiddaman unsigned whave; /* valid bytes in the window */
1652*b30d1939SAndy Fiddaman unsigned write; /* window write index */
1653*b30d1939SAndy Fiddaman unsigned char FAR *window; /* allocated sliding window, if needed */
1654*b30d1939SAndy Fiddaman /* bit accumulator */
1655*b30d1939SAndy Fiddaman unsigned long hold; /* input bit accumulator */
1656*b30d1939SAndy Fiddaman unsigned bits; /* number of bits in "in" */
1657*b30d1939SAndy Fiddaman /* for string and stored block copying */
1658*b30d1939SAndy Fiddaman unsigned length; /* literal or length of data to copy */
1659*b30d1939SAndy Fiddaman unsigned offset; /* distance back to copy string from */
1660*b30d1939SAndy Fiddaman /* for table and code decoding */
1661*b30d1939SAndy Fiddaman unsigned extra; /* extra bits needed */
1662*b30d1939SAndy Fiddaman /* fixed and dynamic code tables */
1663*b30d1939SAndy Fiddaman code const FAR *lencode; /* starting table for length/literal codes */
1664*b30d1939SAndy Fiddaman code const FAR *distcode; /* starting table for distance codes */
1665*b30d1939SAndy Fiddaman unsigned lenbits; /* index bits for lencode */
1666*b30d1939SAndy Fiddaman unsigned distbits; /* index bits for distcode */
1667*b30d1939SAndy Fiddaman /* dynamic table building */
1668*b30d1939SAndy Fiddaman unsigned ncode; /* number of code length code lengths */
1669*b30d1939SAndy Fiddaman unsigned nlen; /* number of length code lengths */
1670*b30d1939SAndy Fiddaman unsigned ndist; /* number of distance code lengths */
1671*b30d1939SAndy Fiddaman unsigned have; /* number of code lengths in lens[] */
1672*b30d1939SAndy Fiddaman code FAR *next; /* next available space in codes[] */
1673*b30d1939SAndy Fiddaman unsigned short lens[320]; /* temporary storage for code lengths */
1674*b30d1939SAndy Fiddaman unsigned short work[288]; /* work area for code table building */
1675*b30d1939SAndy Fiddaman code codes[ENOUGH]; /* space for code tables */
1676*b30d1939SAndy Fiddaman };
1677*b30d1939SAndy Fiddaman #endif /* _INFLATE_H */
1678*b30d1939SAndy Fiddaman
1679*b30d1939SAndy Fiddaman #ifndef _INFTREES_C
1680*b30d1939SAndy Fiddaman #define _INFTREES_C 1
1681*b30d1939SAndy Fiddaman
1682*b30d1939SAndy Fiddaman #define MAXBITS 15
1683*b30d1939SAndy Fiddaman
1684*b30d1939SAndy Fiddaman const char inflate_copyright[] =
1685*b30d1939SAndy Fiddaman " inflate 1.2.3 Copyright 1995-2005 Mark Adler ";
1686*b30d1939SAndy Fiddaman /*
1687*b30d1939SAndy Fiddaman If you use the zlib library in a product, an acknowledgment is welcome
1688*b30d1939SAndy Fiddaman in the documentation of your product. If for some reason you cannot
1689*b30d1939SAndy Fiddaman include such an acknowledgment, I would appreciate that you keep this
1690*b30d1939SAndy Fiddaman copyright string in the executable of your product.
1691*b30d1939SAndy Fiddaman */
1692*b30d1939SAndy Fiddaman
1693*b30d1939SAndy Fiddaman /*
1694*b30d1939SAndy Fiddaman Build a set of tables to decode the provided canonical Huffman code.
1695*b30d1939SAndy Fiddaman The code lengths are lens[0..codes-1]. The result starts at *table,
1696*b30d1939SAndy Fiddaman whose indices are 0..2^bits-1. work is a writable array of at least
1697*b30d1939SAndy Fiddaman lens shorts, which is used as a work area. type is the type of code
1698*b30d1939SAndy Fiddaman to be generated, CODES, LENS, or DISTS. On return, zero is success,
1699*b30d1939SAndy Fiddaman -1 is an invalid code, and +1 means that ENOUGH isn't enough. table
1700*b30d1939SAndy Fiddaman on return points to the next available entry's address. bits is the
1701*b30d1939SAndy Fiddaman requested root table index bits, and on return it is the actual root
1702*b30d1939SAndy Fiddaman table index bits. It will differ if the request is greater than the
1703*b30d1939SAndy Fiddaman longest code or if it is less than the shortest code.
1704*b30d1939SAndy Fiddaman */
inflate_table(type,lens,codes,table,bits,work)1705*b30d1939SAndy Fiddaman int inflate_table(type, lens, codes, table, bits, work)
1706*b30d1939SAndy Fiddaman codetype type;
1707*b30d1939SAndy Fiddaman unsigned short FAR *lens;
1708*b30d1939SAndy Fiddaman unsigned codes;
1709*b30d1939SAndy Fiddaman code FAR * FAR *table;
1710*b30d1939SAndy Fiddaman unsigned FAR *bits;
1711*b30d1939SAndy Fiddaman unsigned short FAR *work;
1712*b30d1939SAndy Fiddaman {
1713*b30d1939SAndy Fiddaman unsigned len; /* a code's length in bits */
1714*b30d1939SAndy Fiddaman unsigned sym; /* index of code symbols */
1715*b30d1939SAndy Fiddaman unsigned min, max; /* minimum and maximum code lengths */
1716*b30d1939SAndy Fiddaman unsigned root; /* number of index bits for root table */
1717*b30d1939SAndy Fiddaman unsigned curr; /* number of index bits for current table */
1718*b30d1939SAndy Fiddaman unsigned drop; /* code bits to drop for sub-table */
1719*b30d1939SAndy Fiddaman int left; /* number of prefix codes available */
1720*b30d1939SAndy Fiddaman unsigned used; /* code entries in table used */
1721*b30d1939SAndy Fiddaman unsigned huff; /* Huffman code */
1722*b30d1939SAndy Fiddaman unsigned incr; /* for incrementing code, index */
1723*b30d1939SAndy Fiddaman unsigned fill; /* index for replicating entries */
1724*b30d1939SAndy Fiddaman unsigned low; /* low bits for current root entry */
1725*b30d1939SAndy Fiddaman unsigned mask; /* mask for low root bits */
1726*b30d1939SAndy Fiddaman code this; /* table entry for duplication */
1727*b30d1939SAndy Fiddaman code FAR *next; /* next available space in table */
1728*b30d1939SAndy Fiddaman const unsigned short FAR *base; /* base value table to use */
1729*b30d1939SAndy Fiddaman const unsigned short FAR *extra; /* extra bits table to use */
1730*b30d1939SAndy Fiddaman int end; /* use base and extra for symbol > end */
1731*b30d1939SAndy Fiddaman unsigned short count[MAXBITS+1]; /* number of codes of each length */
1732*b30d1939SAndy Fiddaman unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
1733*b30d1939SAndy Fiddaman static const unsigned short lbase[31] = { /* Length codes 257..285 base */
1734*b30d1939SAndy Fiddaman 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
1735*b30d1939SAndy Fiddaman 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
1736*b30d1939SAndy Fiddaman static const unsigned short lext[31] = { /* Length codes 257..285 extra */
1737*b30d1939SAndy Fiddaman 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
1738*b30d1939SAndy Fiddaman 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196};
1739*b30d1939SAndy Fiddaman static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
1740*b30d1939SAndy Fiddaman 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
1741*b30d1939SAndy Fiddaman 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
1742*b30d1939SAndy Fiddaman 8193, 12289, 16385, 24577, 0, 0};
1743*b30d1939SAndy Fiddaman static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
1744*b30d1939SAndy Fiddaman 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
1745*b30d1939SAndy Fiddaman 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
1746*b30d1939SAndy Fiddaman 28, 28, 29, 29, 64, 64};
1747*b30d1939SAndy Fiddaman
1748*b30d1939SAndy Fiddaman /*
1749*b30d1939SAndy Fiddaman Process a set of code lengths to create a canonical Huffman code. The
1750*b30d1939SAndy Fiddaman code lengths are lens[0..codes-1]. Each length corresponds to the
1751*b30d1939SAndy Fiddaman symbols 0..codes-1. The Huffman code is generated by first sorting the
1752*b30d1939SAndy Fiddaman symbols by length from short to long, and retaining the symbol order
1753*b30d1939SAndy Fiddaman for codes with equal lengths. Then the code starts with all zero bits
1754*b30d1939SAndy Fiddaman for the first code of the shortest length, and the codes are integer
1755*b30d1939SAndy Fiddaman increments for the same length, and zeros are appended as the length
1756*b30d1939SAndy Fiddaman increases. For the deflate format, these bits are stored backwards
1757*b30d1939SAndy Fiddaman from their more natural integer increment ordering, and so when the
1758*b30d1939SAndy Fiddaman decoding tables are built in the large loop below, the integer codes
1759*b30d1939SAndy Fiddaman are incremented backwards.
1760*b30d1939SAndy Fiddaman
1761*b30d1939SAndy Fiddaman This routine assumes, but does not check, that all of the entries in
1762*b30d1939SAndy Fiddaman lens[] are in the range 0..MAXBITS. The caller must assure this.
1763*b30d1939SAndy Fiddaman 1..MAXBITS is interpreted as that code length. zero means that that
1764*b30d1939SAndy Fiddaman symbol does not occur in this code.
1765*b30d1939SAndy Fiddaman
1766*b30d1939SAndy Fiddaman The codes are sorted by computing a count of codes for each length,
1767*b30d1939SAndy Fiddaman creating from that a table of starting indices for each length in the
1768*b30d1939SAndy Fiddaman sorted table, and then entering the symbols in order in the sorted
1769*b30d1939SAndy Fiddaman table. The sorted table is work[], with that space being provided by
1770*b30d1939SAndy Fiddaman the caller.
1771*b30d1939SAndy Fiddaman
1772*b30d1939SAndy Fiddaman The length counts are used for other purposes as well, i.e. finding
1773*b30d1939SAndy Fiddaman the minimum and maximum length codes, determining if there are any
1774*b30d1939SAndy Fiddaman codes at all, checking for a valid set of lengths, and looking ahead
1775*b30d1939SAndy Fiddaman at length counts to determine sub-table sizes when building the
1776*b30d1939SAndy Fiddaman decoding tables.
1777*b30d1939SAndy Fiddaman */
1778*b30d1939SAndy Fiddaman
1779*b30d1939SAndy Fiddaman /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
1780*b30d1939SAndy Fiddaman for (len = 0; len <= MAXBITS; len++)
1781*b30d1939SAndy Fiddaman count[len] = 0;
1782*b30d1939SAndy Fiddaman for (sym = 0; sym < codes; sym++)
1783*b30d1939SAndy Fiddaman count[lens[sym]]++;
1784*b30d1939SAndy Fiddaman
1785*b30d1939SAndy Fiddaman /* bound code lengths, force root to be within code lengths */
1786*b30d1939SAndy Fiddaman root = *bits;
1787*b30d1939SAndy Fiddaman for (max = MAXBITS; max >= 1; max--)
1788*b30d1939SAndy Fiddaman if (count[max] != 0) break;
1789*b30d1939SAndy Fiddaman if (root > max) root = max;
1790*b30d1939SAndy Fiddaman if (max == 0) { /* no symbols to code at all */
1791*b30d1939SAndy Fiddaman this.op = (unsigned char)64; /* invalid code marker */
1792*b30d1939SAndy Fiddaman this.bits = (unsigned char)1;
1793*b30d1939SAndy Fiddaman this.val = (unsigned short)0;
1794*b30d1939SAndy Fiddaman *(*table)++ = this; /* make a table to force an error */
1795*b30d1939SAndy Fiddaman *(*table)++ = this;
1796*b30d1939SAndy Fiddaman *bits = 1;
1797*b30d1939SAndy Fiddaman return 0; /* no symbols, but wait for decoding to report error */
1798*b30d1939SAndy Fiddaman }
1799*b30d1939SAndy Fiddaman for (min = 1; min <= MAXBITS; min++)
1800*b30d1939SAndy Fiddaman if (count[min] != 0) break;
1801*b30d1939SAndy Fiddaman if (root < min) root = min;
1802*b30d1939SAndy Fiddaman
1803*b30d1939SAndy Fiddaman /* check for an over-subscribed or incomplete set of lengths */
1804*b30d1939SAndy Fiddaman left = 1;
1805*b30d1939SAndy Fiddaman for (len = 1; len <= MAXBITS; len++) {
1806*b30d1939SAndy Fiddaman left <<= 1;
1807*b30d1939SAndy Fiddaman left -= count[len];
1808*b30d1939SAndy Fiddaman if (left < 0) return -1; /* over-subscribed */
1809*b30d1939SAndy Fiddaman }
1810*b30d1939SAndy Fiddaman if (left > 0 && (type == CODES || max != 1))
1811*b30d1939SAndy Fiddaman return -1; /* incomplete set */
1812*b30d1939SAndy Fiddaman
1813*b30d1939SAndy Fiddaman /* generate offsets into symbol table for each length for sorting */
1814*b30d1939SAndy Fiddaman offs[1] = 0;
1815*b30d1939SAndy Fiddaman for (len = 1; len < MAXBITS; len++)
1816*b30d1939SAndy Fiddaman offs[len + 1] = offs[len] + count[len];
1817*b30d1939SAndy Fiddaman
1818*b30d1939SAndy Fiddaman /* sort symbols by length, by symbol order within each length */
1819*b30d1939SAndy Fiddaman for (sym = 0; sym < codes; sym++)
1820*b30d1939SAndy Fiddaman if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
1821*b30d1939SAndy Fiddaman
1822*b30d1939SAndy Fiddaman /*
1823*b30d1939SAndy Fiddaman Create and fill in decoding tables. In this loop, the table being
1824*b30d1939SAndy Fiddaman filled is at next and has curr index bits. The code being used is huff
1825*b30d1939SAndy Fiddaman with length len. That code is converted to an index by dropping drop
1826*b30d1939SAndy Fiddaman bits off of the bottom. For codes where len is less than drop + curr,
1827*b30d1939SAndy Fiddaman those top drop + curr - len bits are incremented through all values to
1828*b30d1939SAndy Fiddaman fill the table with replicated entries.
1829*b30d1939SAndy Fiddaman
1830*b30d1939SAndy Fiddaman root is the number of index bits for the root table. When len exceeds
1831*b30d1939SAndy Fiddaman root, sub-tables are created pointed to by the root entry with an index
1832*b30d1939SAndy Fiddaman of the low root bits of huff. This is saved in low to check for when a
1833*b30d1939SAndy Fiddaman new sub-table should be started. drop is zero when the root table is
1834*b30d1939SAndy Fiddaman being filled, and drop is root when sub-tables are being filled.
1835*b30d1939SAndy Fiddaman
1836*b30d1939SAndy Fiddaman When a new sub-table is needed, it is necessary to look ahead in the
1837*b30d1939SAndy Fiddaman code lengths to determine what size sub-table is needed. The length
1838*b30d1939SAndy Fiddaman counts are used for this, and so count[] is decremented as codes are
1839*b30d1939SAndy Fiddaman entered in the tables.
1840*b30d1939SAndy Fiddaman
1841*b30d1939SAndy Fiddaman used keeps track of how many table entries have been allocated from the
1842*b30d1939SAndy Fiddaman provided *table space. It is checked when a LENS table is being made
1843*b30d1939SAndy Fiddaman against the space in *table, ENOUGH, minus the maximum space needed by
1844*b30d1939SAndy Fiddaman the worst case distance code, MAXD. This should never happen, but the
1845*b30d1939SAndy Fiddaman sufficiency of ENOUGH has not been proven exhaustively, hence the check.
1846*b30d1939SAndy Fiddaman This assumes that when type == LENS, bits == 9.
1847*b30d1939SAndy Fiddaman
1848*b30d1939SAndy Fiddaman sym increments through all symbols, and the loop terminates when
1849*b30d1939SAndy Fiddaman all codes of length max, i.e. all codes, have been processed. This
1850*b30d1939SAndy Fiddaman routine permits incomplete codes, so another loop after this one fills
1851*b30d1939SAndy Fiddaman in the rest of the decoding tables with invalid code markers.
1852*b30d1939SAndy Fiddaman */
1853*b30d1939SAndy Fiddaman
1854*b30d1939SAndy Fiddaman /* set up for code type */
1855*b30d1939SAndy Fiddaman switch (type) {
1856*b30d1939SAndy Fiddaman case CODES:
1857*b30d1939SAndy Fiddaman base = extra = work; /* dummy value--not used */
1858*b30d1939SAndy Fiddaman end = 19;
1859*b30d1939SAndy Fiddaman break;
1860*b30d1939SAndy Fiddaman case LENS:
1861*b30d1939SAndy Fiddaman base = lbase;
1862*b30d1939SAndy Fiddaman base -= 257;
1863*b30d1939SAndy Fiddaman extra = lext;
1864*b30d1939SAndy Fiddaman extra -= 257;
1865*b30d1939SAndy Fiddaman end = 256;
1866*b30d1939SAndy Fiddaman break;
1867*b30d1939SAndy Fiddaman default: /* DISTS */
1868*b30d1939SAndy Fiddaman base = dbase;
1869*b30d1939SAndy Fiddaman extra = dext;
1870*b30d1939SAndy Fiddaman end = -1;
1871*b30d1939SAndy Fiddaman }
1872*b30d1939SAndy Fiddaman
1873*b30d1939SAndy Fiddaman /* initialize state for loop */
1874*b30d1939SAndy Fiddaman huff = 0; /* starting code */
1875*b30d1939SAndy Fiddaman sym = 0; /* starting code symbol */
1876*b30d1939SAndy Fiddaman len = min; /* starting code length */
1877*b30d1939SAndy Fiddaman next = *table; /* current table to fill in */
1878*b30d1939SAndy Fiddaman curr = root; /* current table index bits */
1879*b30d1939SAndy Fiddaman drop = 0; /* current bits to drop from code for index */
1880*b30d1939SAndy Fiddaman low = (unsigned)(-1); /* trigger new sub-table when len > root */
1881*b30d1939SAndy Fiddaman used = ((unsigned int)1) << root; /* use root table entries */
1882*b30d1939SAndy Fiddaman mask = used - 1; /* mask for comparing low */
1883*b30d1939SAndy Fiddaman
1884*b30d1939SAndy Fiddaman /* check available table space */
1885*b30d1939SAndy Fiddaman if (type == LENS && used >= ENOUGH - MAXD)
1886*b30d1939SAndy Fiddaman return 1;
1887*b30d1939SAndy Fiddaman
1888*b30d1939SAndy Fiddaman /* process all codes and make table entries */
1889*b30d1939SAndy Fiddaman for (;;) {
1890*b30d1939SAndy Fiddaman /* create table entry */
1891*b30d1939SAndy Fiddaman this.bits = (unsigned char)(len - drop);
1892*b30d1939SAndy Fiddaman if ((int)(work[sym]) < end) {
1893*b30d1939SAndy Fiddaman this.op = (unsigned char)0;
1894*b30d1939SAndy Fiddaman this.val = work[sym];
1895*b30d1939SAndy Fiddaman }
1896*b30d1939SAndy Fiddaman else if ((int)(work[sym]) > end) {
1897*b30d1939SAndy Fiddaman this.op = (unsigned char)(extra[work[sym]]);
1898*b30d1939SAndy Fiddaman this.val = base[work[sym]];
1899*b30d1939SAndy Fiddaman }
1900*b30d1939SAndy Fiddaman else {
1901*b30d1939SAndy Fiddaman this.op = (unsigned char)(32 + 64); /* end of block */
1902*b30d1939SAndy Fiddaman this.val = 0;
1903*b30d1939SAndy Fiddaman }
1904*b30d1939SAndy Fiddaman
1905*b30d1939SAndy Fiddaman /* replicate for those indices with low len bits equal to huff */
1906*b30d1939SAndy Fiddaman incr = ((unsigned int)1) << (len - drop);
1907*b30d1939SAndy Fiddaman fill = ((unsigned int)1) << curr;
1908*b30d1939SAndy Fiddaman min = fill; /* save offset to next table */
1909*b30d1939SAndy Fiddaman do {
1910*b30d1939SAndy Fiddaman fill -= incr;
1911*b30d1939SAndy Fiddaman next[(huff >> drop) + fill] = this;
1912*b30d1939SAndy Fiddaman } while (fill != 0);
1913*b30d1939SAndy Fiddaman
1914*b30d1939SAndy Fiddaman /* backwards increment the len-bit code huff */
1915*b30d1939SAndy Fiddaman incr = ((unsigned int)1) << (len - 1);
1916*b30d1939SAndy Fiddaman while (huff & incr)
1917*b30d1939SAndy Fiddaman incr >>= 1;
1918*b30d1939SAndy Fiddaman if (incr != 0) {
1919*b30d1939SAndy Fiddaman huff &= incr - 1;
1920*b30d1939SAndy Fiddaman huff += incr;
1921*b30d1939SAndy Fiddaman }
1922*b30d1939SAndy Fiddaman else
1923*b30d1939SAndy Fiddaman huff = 0;
1924*b30d1939SAndy Fiddaman
1925*b30d1939SAndy Fiddaman /* go to next symbol, update count, len */
1926*b30d1939SAndy Fiddaman sym++;
1927*b30d1939SAndy Fiddaman if (--(count[len]) == 0) {
1928*b30d1939SAndy Fiddaman if (len == max) break;
1929*b30d1939SAndy Fiddaman len = lens[work[sym]];
1930*b30d1939SAndy Fiddaman }
1931*b30d1939SAndy Fiddaman
1932*b30d1939SAndy Fiddaman /* create new sub-table if needed */
1933*b30d1939SAndy Fiddaman if (len > root && (huff & mask) != low) {
1934*b30d1939SAndy Fiddaman /* if first time, transition to sub-tables */
1935*b30d1939SAndy Fiddaman if (drop == 0)
1936*b30d1939SAndy Fiddaman drop = root;
1937*b30d1939SAndy Fiddaman
1938*b30d1939SAndy Fiddaman /* increment past last table */
1939*b30d1939SAndy Fiddaman next += min; /* here min is 1 << curr */
1940*b30d1939SAndy Fiddaman
1941*b30d1939SAndy Fiddaman /* determine length of next table */
1942*b30d1939SAndy Fiddaman curr = len - drop;
1943*b30d1939SAndy Fiddaman left = (int)(1 << curr);
1944*b30d1939SAndy Fiddaman while (curr + drop < max) {
1945*b30d1939SAndy Fiddaman left -= count[curr + drop];
1946*b30d1939SAndy Fiddaman if (left <= 0) break;
1947*b30d1939SAndy Fiddaman curr++;
1948*b30d1939SAndy Fiddaman left <<= 1;
1949*b30d1939SAndy Fiddaman }
1950*b30d1939SAndy Fiddaman
1951*b30d1939SAndy Fiddaman /* check for enough space */
1952*b30d1939SAndy Fiddaman used += ((unsigned int)1) << curr;
1953*b30d1939SAndy Fiddaman if (type == LENS && used >= ENOUGH - MAXD)
1954*b30d1939SAndy Fiddaman return 1;
1955*b30d1939SAndy Fiddaman
1956*b30d1939SAndy Fiddaman /* point entry in root table to sub-table */
1957*b30d1939SAndy Fiddaman low = huff & mask;
1958*b30d1939SAndy Fiddaman (*table)[low].op = (unsigned char)curr;
1959*b30d1939SAndy Fiddaman (*table)[low].bits = (unsigned char)root;
1960*b30d1939SAndy Fiddaman (*table)[low].val = (unsigned short)(next - *table);
1961*b30d1939SAndy Fiddaman }
1962*b30d1939SAndy Fiddaman }
1963*b30d1939SAndy Fiddaman
1964*b30d1939SAndy Fiddaman /*
1965*b30d1939SAndy Fiddaman Fill in rest of table for incomplete codes. This loop is similar to the
1966*b30d1939SAndy Fiddaman loop above in incrementing huff for table indices. It is assumed that
1967*b30d1939SAndy Fiddaman len is equal to curr + drop, so there is no loop needed to increment
1968*b30d1939SAndy Fiddaman through high index bits. When the current sub-table is filled, the loop
1969*b30d1939SAndy Fiddaman drops back to the root table to fill in any remaining entries there.
1970*b30d1939SAndy Fiddaman */
1971*b30d1939SAndy Fiddaman this.op = (unsigned char)64; /* invalid code marker */
1972*b30d1939SAndy Fiddaman this.bits = (unsigned char)(len - drop);
1973*b30d1939SAndy Fiddaman this.val = (unsigned short)0;
1974*b30d1939SAndy Fiddaman while (huff != 0) {
1975*b30d1939SAndy Fiddaman /* when done with sub-table, drop back to root table */
1976*b30d1939SAndy Fiddaman if (drop != 0 && (huff & mask) != low) {
1977*b30d1939SAndy Fiddaman drop = 0;
1978*b30d1939SAndy Fiddaman len = root;
1979*b30d1939SAndy Fiddaman next = *table;
1980*b30d1939SAndy Fiddaman this.bits = (unsigned char)len;
1981*b30d1939SAndy Fiddaman }
1982*b30d1939SAndy Fiddaman
1983*b30d1939SAndy Fiddaman /* put invalid code marker in table */
1984*b30d1939SAndy Fiddaman next[huff >> drop] = this;
1985*b30d1939SAndy Fiddaman
1986*b30d1939SAndy Fiddaman /* backwards increment the len-bit code huff */
1987*b30d1939SAndy Fiddaman incr = ((unsigned int)1) << (len - 1);
1988*b30d1939SAndy Fiddaman while (huff & incr)
1989*b30d1939SAndy Fiddaman incr >>= 1;
1990*b30d1939SAndy Fiddaman if (incr != 0) {
1991*b30d1939SAndy Fiddaman huff &= incr - 1;
1992*b30d1939SAndy Fiddaman huff += incr;
1993*b30d1939SAndy Fiddaman }
1994*b30d1939SAndy Fiddaman else
1995*b30d1939SAndy Fiddaman huff = 0;
1996*b30d1939SAndy Fiddaman }
1997*b30d1939SAndy Fiddaman
1998*b30d1939SAndy Fiddaman /* set return parameters */
1999*b30d1939SAndy Fiddaman *table += used;
2000*b30d1939SAndy Fiddaman *bits = root;
2001*b30d1939SAndy Fiddaman return 0;
2002*b30d1939SAndy Fiddaman }
2003*b30d1939SAndy Fiddaman
2004*b30d1939SAndy Fiddaman #endif /* _INFTREES_C */
2005*b30d1939SAndy Fiddaman
2006*b30d1939SAndy Fiddaman #ifndef _INFFAST_C
2007*b30d1939SAndy Fiddaman #define _INFFAST_C 1
2008*b30d1939SAndy Fiddaman
2009*b30d1939SAndy Fiddaman /* Allow machine dependent optimization for post-increment or pre-increment.
2010*b30d1939SAndy Fiddaman Based on testing to date,
2011*b30d1939SAndy Fiddaman Pre-increment preferred for:
2012*b30d1939SAndy Fiddaman - PowerPC G3 (Adler)
2013*b30d1939SAndy Fiddaman - MIPS R5000 (Randers-Pehrson)
2014*b30d1939SAndy Fiddaman Post-increment preferred for:
2015*b30d1939SAndy Fiddaman - none
2016*b30d1939SAndy Fiddaman No measurable difference:
2017*b30d1939SAndy Fiddaman - Pentium III (Anderson)
2018*b30d1939SAndy Fiddaman - M68060 (Nikl)
2019*b30d1939SAndy Fiddaman */
2020*b30d1939SAndy Fiddaman #undef OFF /* (ancient) sunos <locale.h> */
2021*b30d1939SAndy Fiddaman #ifdef POSTINC
2022*b30d1939SAndy Fiddaman # define OFF 0
2023*b30d1939SAndy Fiddaman # define PUP(a) *(a)++
2024*b30d1939SAndy Fiddaman #else
2025*b30d1939SAndy Fiddaman # define OFF 1
2026*b30d1939SAndy Fiddaman # define PUP(a) *++(a)
2027*b30d1939SAndy Fiddaman #endif
2028*b30d1939SAndy Fiddaman
2029*b30d1939SAndy Fiddaman /*
2030*b30d1939SAndy Fiddaman Decode literal, length, and distance codes and write out the resulting
2031*b30d1939SAndy Fiddaman literal and match bytes until either not enough input or output is
2032*b30d1939SAndy Fiddaman available, an end-of-block is encountered, or a data error is encountered.
2033*b30d1939SAndy Fiddaman When large enough input and output buffers are supplied to inflate(), for
2034*b30d1939SAndy Fiddaman example, a 16K input buffer and a 64K output buffer, more than 95% of the
2035*b30d1939SAndy Fiddaman inflate execution time is spent in this routine.
2036*b30d1939SAndy Fiddaman
2037*b30d1939SAndy Fiddaman Entry assumptions:
2038*b30d1939SAndy Fiddaman
2039*b30d1939SAndy Fiddaman state->mode == LEN
2040*b30d1939SAndy Fiddaman strm->avail_in >= 6
2041*b30d1939SAndy Fiddaman strm->avail_out >= 258
2042*b30d1939SAndy Fiddaman start >= strm->avail_out
2043*b30d1939SAndy Fiddaman state->bits < 8
2044*b30d1939SAndy Fiddaman
2045*b30d1939SAndy Fiddaman On return, state->mode is one of:
2046*b30d1939SAndy Fiddaman
2047*b30d1939SAndy Fiddaman LEN -- ran out of enough output space or enough available input
2048*b30d1939SAndy Fiddaman TYPE -- reached end of block code, inflate() to interpret next block
2049*b30d1939SAndy Fiddaman BAD -- error in block data
2050*b30d1939SAndy Fiddaman
2051*b30d1939SAndy Fiddaman Notes:
2052*b30d1939SAndy Fiddaman
2053*b30d1939SAndy Fiddaman - The maximum input bits used by a length/distance pair is 15 bits for the
2054*b30d1939SAndy Fiddaman length code, 5 bits for the length extra, 15 bits for the distance code,
2055*b30d1939SAndy Fiddaman and 13 bits for the distance extra. This totals 48 bits, or six bytes.
2056*b30d1939SAndy Fiddaman Therefore if strm->avail_in >= 6, then there is enough input to avoid
2057*b30d1939SAndy Fiddaman checking for available input while decoding.
2058*b30d1939SAndy Fiddaman
2059*b30d1939SAndy Fiddaman - The maximum bytes that a single length/distance pair can output is 258
2060*b30d1939SAndy Fiddaman bytes, which is the maximum length that can be coded. inflate_fast()
2061*b30d1939SAndy Fiddaman requires strm->avail_out >= 258 for each loop to avoid checking for
2062*b30d1939SAndy Fiddaman output space.
2063*b30d1939SAndy Fiddaman */
inflate_fast(strm,start)2064*b30d1939SAndy Fiddaman void inflate_fast(strm, start)
2065*b30d1939SAndy Fiddaman z_streamp strm;
2066*b30d1939SAndy Fiddaman unsigned start; /* inflate()'s starting value for strm->avail_out */
2067*b30d1939SAndy Fiddaman {
2068*b30d1939SAndy Fiddaman struct inflate_state FAR *state;
2069*b30d1939SAndy Fiddaman unsigned char FAR *in; /* local strm->next_in */
2070*b30d1939SAndy Fiddaman unsigned char FAR *last; /* while in < last, enough input available */
2071*b30d1939SAndy Fiddaman unsigned char FAR *out; /* local strm->next_out */
2072*b30d1939SAndy Fiddaman unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
2073*b30d1939SAndy Fiddaman unsigned char FAR *end; /* while out < end, enough space available */
2074*b30d1939SAndy Fiddaman #ifdef INFLATE_STRICT
2075*b30d1939SAndy Fiddaman unsigned dmax; /* maximum distance from zlib header */
2076*b30d1939SAndy Fiddaman #endif
2077*b30d1939SAndy Fiddaman unsigned wsize; /* window size or zero if not using window */
2078*b30d1939SAndy Fiddaman unsigned whave; /* valid bytes in the window */
2079*b30d1939SAndy Fiddaman unsigned write; /* window write index */
2080*b30d1939SAndy Fiddaman unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
2081*b30d1939SAndy Fiddaman unsigned long hold; /* local strm->hold */
2082*b30d1939SAndy Fiddaman unsigned bits; /* local strm->bits */
2083*b30d1939SAndy Fiddaman code const FAR *lcode; /* local strm->lencode */
2084*b30d1939SAndy Fiddaman code const FAR *dcode; /* local strm->distcode */
2085*b30d1939SAndy Fiddaman unsigned lmask; /* mask for first level of length codes */
2086*b30d1939SAndy Fiddaman unsigned dmask; /* mask for first level of distance codes */
2087*b30d1939SAndy Fiddaman code this; /* retrieved table entry */
2088*b30d1939SAndy Fiddaman unsigned op; /* code bits, operation, extra bits, or */
2089*b30d1939SAndy Fiddaman /* window position, window bytes to copy */
2090*b30d1939SAndy Fiddaman unsigned len; /* match length, unused bytes */
2091*b30d1939SAndy Fiddaman unsigned dist; /* match distance */
2092*b30d1939SAndy Fiddaman unsigned char FAR *from; /* where to copy match from */
2093*b30d1939SAndy Fiddaman
2094*b30d1939SAndy Fiddaman /* copy state to local variables */
2095*b30d1939SAndy Fiddaman state = (struct inflate_state FAR *)strm->state;
2096*b30d1939SAndy Fiddaman in = strm->next_in - OFF;
2097*b30d1939SAndy Fiddaman last = in + (strm->avail_in - 5);
2098*b30d1939SAndy Fiddaman out = strm->next_out - OFF;
2099*b30d1939SAndy Fiddaman beg = out - (start - strm->avail_out);
2100*b30d1939SAndy Fiddaman end = out + (strm->avail_out - 257);
2101*b30d1939SAndy Fiddaman #ifdef INFLATE_STRICT
2102*b30d1939SAndy Fiddaman dmax = state->dmax;
2103*b30d1939SAndy Fiddaman #endif
2104*b30d1939SAndy Fiddaman wsize = state->wsize;
2105*b30d1939SAndy Fiddaman whave = state->whave;
2106*b30d1939SAndy Fiddaman write = state->write;
2107*b30d1939SAndy Fiddaman window = state->window;
2108*b30d1939SAndy Fiddaman hold = state->hold;
2109*b30d1939SAndy Fiddaman bits = state->bits;
2110*b30d1939SAndy Fiddaman lcode = state->lencode;
2111*b30d1939SAndy Fiddaman dcode = state->distcode;
2112*b30d1939SAndy Fiddaman lmask = (((unsigned int)1) << state->lenbits) - 1;
2113*b30d1939SAndy Fiddaman dmask = (((unsigned int)1) << state->distbits) - 1;
2114*b30d1939SAndy Fiddaman
2115*b30d1939SAndy Fiddaman /* decode literals and length/distances until end-of-block or not enough
2116*b30d1939SAndy Fiddaman input data or output space */
2117*b30d1939SAndy Fiddaman do {
2118*b30d1939SAndy Fiddaman if (bits < 15) {
2119*b30d1939SAndy Fiddaman hold += (unsigned long)(PUP(in)) << bits;
2120*b30d1939SAndy Fiddaman bits += 8;
2121*b30d1939SAndy Fiddaman hold += (unsigned long)(PUP(in)) << bits;
2122*b30d1939SAndy Fiddaman bits += 8;
2123*b30d1939SAndy Fiddaman }
2124*b30d1939SAndy Fiddaman this = lcode[hold & lmask];
2125*b30d1939SAndy Fiddaman dolen:
2126*b30d1939SAndy Fiddaman op = (unsigned)(this.bits);
2127*b30d1939SAndy Fiddaman hold >>= op;
2128*b30d1939SAndy Fiddaman bits -= op;
2129*b30d1939SAndy Fiddaman op = (unsigned)(this.op);
2130*b30d1939SAndy Fiddaman if (op == 0) { /* literal */
2131*b30d1939SAndy Fiddaman Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
2132*b30d1939SAndy Fiddaman "inflate: literal '%c'\n" :
2133*b30d1939SAndy Fiddaman "inflate: literal 0x%02x\n", this.val));
2134*b30d1939SAndy Fiddaman PUP(out) = (unsigned char)(this.val);
2135*b30d1939SAndy Fiddaman }
2136*b30d1939SAndy Fiddaman else if (op & 16) { /* length base */
2137*b30d1939SAndy Fiddaman len = (unsigned)(this.val);
2138*b30d1939SAndy Fiddaman op &= 15; /* number of extra bits */
2139*b30d1939SAndy Fiddaman if (op) {
2140*b30d1939SAndy Fiddaman if (bits < op) {
2141*b30d1939SAndy Fiddaman hold += (unsigned long)(PUP(in)) << bits;
2142*b30d1939SAndy Fiddaman bits += 8;
2143*b30d1939SAndy Fiddaman }
2144*b30d1939SAndy Fiddaman len += (unsigned)hold & ((((unsigned int)1) << op) - 1);
2145*b30d1939SAndy Fiddaman hold >>= op;
2146*b30d1939SAndy Fiddaman bits -= op;
2147*b30d1939SAndy Fiddaman }
2148*b30d1939SAndy Fiddaman Tracevv((stderr, "inflate: length %u\n", len));
2149*b30d1939SAndy Fiddaman if (bits < 15) {
2150*b30d1939SAndy Fiddaman hold += (unsigned long)(PUP(in)) << bits;
2151*b30d1939SAndy Fiddaman bits += 8;
2152*b30d1939SAndy Fiddaman hold += (unsigned long)(PUP(in)) << bits;
2153*b30d1939SAndy Fiddaman bits += 8;
2154*b30d1939SAndy Fiddaman }
2155*b30d1939SAndy Fiddaman this = dcode[hold & dmask];
2156*b30d1939SAndy Fiddaman dodist:
2157*b30d1939SAndy Fiddaman op = (unsigned)(this.bits);
2158*b30d1939SAndy Fiddaman hold >>= op;
2159*b30d1939SAndy Fiddaman bits -= op;
2160*b30d1939SAndy Fiddaman op = (unsigned)(this.op);
2161*b30d1939SAndy Fiddaman if (op & 16) { /* distance base */
2162*b30d1939SAndy Fiddaman dist = (unsigned)(this.val);
2163*b30d1939SAndy Fiddaman op &= 15; /* number of extra bits */
2164*b30d1939SAndy Fiddaman if (bits < op) {
2165*b30d1939SAndy Fiddaman hold += (unsigned long)(PUP(in)) << bits;
2166*b30d1939SAndy Fiddaman bits += 8;
2167*b30d1939SAndy Fiddaman if (bits < op) {
2168*b30d1939SAndy Fiddaman hold += (unsigned long)(PUP(in)) << bits;
2169*b30d1939SAndy Fiddaman bits += 8;
2170*b30d1939SAndy Fiddaman }
2171*b30d1939SAndy Fiddaman }
2172*b30d1939SAndy Fiddaman dist += (unsigned)hold & ((((unsigned int)1) << op) - 1);
2173*b30d1939SAndy Fiddaman #ifdef INFLATE_STRICT
2174*b30d1939SAndy Fiddaman if (dist > dmax) {
2175*b30d1939SAndy Fiddaman strm->msg = (char *)"invalid distance too far back";
2176*b30d1939SAndy Fiddaman state->mode = BAD;
2177*b30d1939SAndy Fiddaman break;
2178*b30d1939SAndy Fiddaman }
2179*b30d1939SAndy Fiddaman #endif
2180*b30d1939SAndy Fiddaman hold >>= op;
2181*b30d1939SAndy Fiddaman bits -= op;
2182*b30d1939SAndy Fiddaman Tracevv((stderr, "inflate: distance %u\n", dist));
2183*b30d1939SAndy Fiddaman op = (unsigned)(out - beg); /* max distance in output */
2184*b30d1939SAndy Fiddaman if (dist > op) { /* see if copy from window */
2185*b30d1939SAndy Fiddaman op = dist - op; /* distance back in window */
2186*b30d1939SAndy Fiddaman if (op > whave) {
2187*b30d1939SAndy Fiddaman strm->msg = (char *)"invalid distance too far back";
2188*b30d1939SAndy Fiddaman state->mode = BAD;
2189*b30d1939SAndy Fiddaman break;
2190*b30d1939SAndy Fiddaman }
2191*b30d1939SAndy Fiddaman from = window - OFF;
2192*b30d1939SAndy Fiddaman if (write == 0) { /* very common case */
2193*b30d1939SAndy Fiddaman from += wsize - op;
2194*b30d1939SAndy Fiddaman if (op < len) { /* some from window */
2195*b30d1939SAndy Fiddaman len -= op;
2196*b30d1939SAndy Fiddaman do {
2197*b30d1939SAndy Fiddaman PUP(out) = PUP(from);
2198*b30d1939SAndy Fiddaman } while (--op);
2199*b30d1939SAndy Fiddaman from = out - dist; /* rest from output */
2200*b30d1939SAndy Fiddaman }
2201*b30d1939SAndy Fiddaman }
2202*b30d1939SAndy Fiddaman else if (write < op) { /* wrap around window */
2203*b30d1939SAndy Fiddaman from += wsize + write - op;
2204*b30d1939SAndy Fiddaman op -= write;
2205*b30d1939SAndy Fiddaman if (op < len) { /* some from end of window */
2206*b30d1939SAndy Fiddaman len -= op;
2207*b30d1939SAndy Fiddaman do {
2208*b30d1939SAndy Fiddaman PUP(out) = PUP(from);
2209*b30d1939SAndy Fiddaman } while (--op);
2210*b30d1939SAndy Fiddaman from = window - OFF;
2211*b30d1939SAndy Fiddaman if (write < len) { /* some from start of window */
2212*b30d1939SAndy Fiddaman op = write;
2213*b30d1939SAndy Fiddaman len -= op;
2214*b30d1939SAndy Fiddaman do {
2215*b30d1939SAndy Fiddaman PUP(out) = PUP(from);
2216*b30d1939SAndy Fiddaman } while (--op);
2217*b30d1939SAndy Fiddaman from = out - dist; /* rest from output */
2218*b30d1939SAndy Fiddaman }
2219*b30d1939SAndy Fiddaman }
2220*b30d1939SAndy Fiddaman }
2221*b30d1939SAndy Fiddaman else { /* contiguous in window */
2222*b30d1939SAndy Fiddaman from += write - op;
2223*b30d1939SAndy Fiddaman if (op < len) { /* some from window */
2224*b30d1939SAndy Fiddaman len -= op;
2225*b30d1939SAndy Fiddaman do {
2226*b30d1939SAndy Fiddaman PUP(out) = PUP(from);
2227*b30d1939SAndy Fiddaman } while (--op);
2228*b30d1939SAndy Fiddaman from = out - dist; /* rest from output */
2229*b30d1939SAndy Fiddaman }
2230*b30d1939SAndy Fiddaman }
2231*b30d1939SAndy Fiddaman while (len > 2) {
2232*b30d1939SAndy Fiddaman PUP(out) = PUP(from);
2233*b30d1939SAndy Fiddaman PUP(out) = PUP(from);
2234*b30d1939SAndy Fiddaman PUP(out) = PUP(from);
2235*b30d1939SAndy Fiddaman len -= 3;
2236*b30d1939SAndy Fiddaman }
2237*b30d1939SAndy Fiddaman if (len) {
2238*b30d1939SAndy Fiddaman PUP(out) = PUP(from);
2239*b30d1939SAndy Fiddaman if (len > 1)
2240*b30d1939SAndy Fiddaman PUP(out) = PUP(from);
2241*b30d1939SAndy Fiddaman }
2242*b30d1939SAndy Fiddaman }
2243*b30d1939SAndy Fiddaman else {
2244*b30d1939SAndy Fiddaman from = out - dist; /* copy direct from output */
2245*b30d1939SAndy Fiddaman do { /* minimum length is three */
2246*b30d1939SAndy Fiddaman PUP(out) = PUP(from);
2247*b30d1939SAndy Fiddaman PUP(out) = PUP(from);
2248*b30d1939SAndy Fiddaman PUP(out) = PUP(from);
2249*b30d1939SAndy Fiddaman len -= 3;
2250*b30d1939SAndy Fiddaman } while (len > 2);
2251*b30d1939SAndy Fiddaman if (len) {
2252*b30d1939SAndy Fiddaman PUP(out) = PUP(from);
2253*b30d1939SAndy Fiddaman if (len > 1)
2254*b30d1939SAndy Fiddaman PUP(out) = PUP(from);
2255*b30d1939SAndy Fiddaman }
2256*b30d1939SAndy Fiddaman }
2257*b30d1939SAndy Fiddaman }
2258*b30d1939SAndy Fiddaman else if ((op & 64) == 0) { /* 2nd level distance code */
2259*b30d1939SAndy Fiddaman this = dcode[this.val + (hold & ((((unsigned int)1) << op) - 1))];
2260*b30d1939SAndy Fiddaman goto dodist;
2261*b30d1939SAndy Fiddaman }
2262*b30d1939SAndy Fiddaman else {
2263*b30d1939SAndy Fiddaman strm->msg = (char *)"invalid distance code";
2264*b30d1939SAndy Fiddaman state->mode = BAD;
2265*b30d1939SAndy Fiddaman break;
2266*b30d1939SAndy Fiddaman }
2267*b30d1939SAndy Fiddaman }
2268*b30d1939SAndy Fiddaman else if ((op & 64) == 0) { /* 2nd level length code */
2269*b30d1939SAndy Fiddaman this = lcode[this.val + (hold & ((((unsigned int)1) << op) - 1))];
2270*b30d1939SAndy Fiddaman goto dolen;
2271*b30d1939SAndy Fiddaman }
2272*b30d1939SAndy Fiddaman else if (op & 32) { /* end-of-block */
2273*b30d1939SAndy Fiddaman Tracevv((stderr, "inflate: end of block\n"));
2274*b30d1939SAndy Fiddaman state->mode = TYPE;
2275*b30d1939SAndy Fiddaman break;
2276*b30d1939SAndy Fiddaman }
2277*b30d1939SAndy Fiddaman else {
2278*b30d1939SAndy Fiddaman strm->msg = (char *)"invalid literal/length code";
2279*b30d1939SAndy Fiddaman state->mode = BAD;
2280*b30d1939SAndy Fiddaman break;
2281*b30d1939SAndy Fiddaman }
2282*b30d1939SAndy Fiddaman } while (in < last && out < end);
2283*b30d1939SAndy Fiddaman
2284*b30d1939SAndy Fiddaman /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
2285*b30d1939SAndy Fiddaman len = bits >> 3;
2286*b30d1939SAndy Fiddaman in -= len;
2287*b30d1939SAndy Fiddaman bits -= len << 3;
2288*b30d1939SAndy Fiddaman hold &= (((unsigned int)1) << bits) - 1;
2289*b30d1939SAndy Fiddaman
2290*b30d1939SAndy Fiddaman /* update state and return */
2291*b30d1939SAndy Fiddaman strm->next_in = in + OFF;
2292*b30d1939SAndy Fiddaman strm->next_out = out + OFF;
2293*b30d1939SAndy Fiddaman strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
2294*b30d1939SAndy Fiddaman strm->avail_out = (unsigned)(out < end ?
2295*b30d1939SAndy Fiddaman 257 + (end - out) : 257 - (out - end));
2296*b30d1939SAndy Fiddaman state->hold = hold;
2297*b30d1939SAndy Fiddaman state->bits = bits;
2298*b30d1939SAndy Fiddaman return;
2299*b30d1939SAndy Fiddaman }
2300*b30d1939SAndy Fiddaman
2301*b30d1939SAndy Fiddaman /*
2302*b30d1939SAndy Fiddaman inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
2303*b30d1939SAndy Fiddaman - Using bit fields for code structure
2304*b30d1939SAndy Fiddaman - Different op definition to avoid & for extra bits (do & for table bits)
2305*b30d1939SAndy Fiddaman - Three separate decoding do-loops for direct, window, and write == 0
2306*b30d1939SAndy Fiddaman - Special case for distance > 1 copies to do overlapped load and store copy
2307*b30d1939SAndy Fiddaman - Explicit branch predictions (based on measured branch probabilities)
2308*b30d1939SAndy Fiddaman - Deferring match copy and interspersed it with decoding subsequent codes
2309*b30d1939SAndy Fiddaman - Swapping literal/length else
2310*b30d1939SAndy Fiddaman - Swapping window/direct else
2311*b30d1939SAndy Fiddaman - Larger unrolled copy loops (three is about right)
2312*b30d1939SAndy Fiddaman - Moving len -= 3 statement into middle of loop
2313*b30d1939SAndy Fiddaman */
2314*b30d1939SAndy Fiddaman
2315*b30d1939SAndy Fiddaman #endif /* _INFFAST_C */
2316*b30d1939SAndy Fiddaman
2317*b30d1939SAndy Fiddaman #ifndef _INFLATE_C
2318*b30d1939SAndy Fiddaman #define _INFLATE_C 1
2319*b30d1939SAndy Fiddaman
2320*b30d1939SAndy Fiddaman /* function prototypes */
2321*b30d1939SAndy Fiddaman local void fixedtables OF((struct inflate_state FAR *state));
2322*b30d1939SAndy Fiddaman local int updatewindow OF((z_streamp strm, unsigned out));
2323*b30d1939SAndy Fiddaman #ifdef BUILDFIXED
2324*b30d1939SAndy Fiddaman void makefixed OF((void));
2325*b30d1939SAndy Fiddaman #endif
2326*b30d1939SAndy Fiddaman local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,
2327*b30d1939SAndy Fiddaman unsigned len));
2328*b30d1939SAndy Fiddaman
inflateReset(strm)2329*b30d1939SAndy Fiddaman int ZEXPORT inflateReset(strm)
2330*b30d1939SAndy Fiddaman z_streamp strm;
2331*b30d1939SAndy Fiddaman {
2332*b30d1939SAndy Fiddaman struct inflate_state FAR *state;
2333*b30d1939SAndy Fiddaman
2334*b30d1939SAndy Fiddaman if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
2335*b30d1939SAndy Fiddaman state = (struct inflate_state FAR *)strm->state;
2336*b30d1939SAndy Fiddaman strm->total_in = strm->total_out = state->total = 0;
2337*b30d1939SAndy Fiddaman strm->msg = Z_NULL;
2338*b30d1939SAndy Fiddaman strm->adler = 1; /* to support ill-conceived Java test suite */
2339*b30d1939SAndy Fiddaman state->mode = HEAD;
2340*b30d1939SAndy Fiddaman state->last = 0;
2341*b30d1939SAndy Fiddaman state->havedict = 0;
2342*b30d1939SAndy Fiddaman state->dmax = 32768;
2343*b30d1939SAndy Fiddaman state->head = Z_NULL;
2344*b30d1939SAndy Fiddaman state->wsize = 0;
2345*b30d1939SAndy Fiddaman state->whave = 0;
2346*b30d1939SAndy Fiddaman state->write = 0;
2347*b30d1939SAndy Fiddaman state->hold = 0;
2348*b30d1939SAndy Fiddaman state->bits = 0;
2349*b30d1939SAndy Fiddaman state->lencode = state->distcode = state->next = state->codes;
2350*b30d1939SAndy Fiddaman Tracev((stderr, "inflate: reset\n"));
2351*b30d1939SAndy Fiddaman return Z_OK;
2352*b30d1939SAndy Fiddaman }
2353*b30d1939SAndy Fiddaman
inflatePrime(strm,bits,value)2354*b30d1939SAndy Fiddaman int ZEXPORT inflatePrime(strm, bits, value)
2355*b30d1939SAndy Fiddaman z_streamp strm;
2356*b30d1939SAndy Fiddaman int bits;
2357*b30d1939SAndy Fiddaman int value;
2358*b30d1939SAndy Fiddaman {
2359*b30d1939SAndy Fiddaman struct inflate_state FAR *state;
2360*b30d1939SAndy Fiddaman
2361*b30d1939SAndy Fiddaman if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
2362*b30d1939SAndy Fiddaman state = (struct inflate_state FAR *)strm->state;
2363*b30d1939SAndy Fiddaman if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
2364*b30d1939SAndy Fiddaman value &= (1L << bits) - 1;
2365*b30d1939SAndy Fiddaman state->hold += value << state->bits;
2366*b30d1939SAndy Fiddaman state->bits += bits;
2367*b30d1939SAndy Fiddaman return Z_OK;
2368*b30d1939SAndy Fiddaman }
2369*b30d1939SAndy Fiddaman
inflateInit2_(strm,windowBits,version,stream_size)2370*b30d1939SAndy Fiddaman int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
2371*b30d1939SAndy Fiddaman z_streamp strm;
2372*b30d1939SAndy Fiddaman int windowBits;
2373*b30d1939SAndy Fiddaman const char *version;
2374*b30d1939SAndy Fiddaman int stream_size;
2375*b30d1939SAndy Fiddaman {
2376*b30d1939SAndy Fiddaman struct inflate_state FAR *state;
2377*b30d1939SAndy Fiddaman
2378*b30d1939SAndy Fiddaman if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
2379*b30d1939SAndy Fiddaman stream_size != (int)(sizeof(z_stream)))
2380*b30d1939SAndy Fiddaman return Z_VERSION_ERROR;
2381*b30d1939SAndy Fiddaman if (strm == Z_NULL) return Z_STREAM_ERROR;
2382*b30d1939SAndy Fiddaman strm->msg = Z_NULL; /* in case we return an error */
2383*b30d1939SAndy Fiddaman if (strm->zalloc == (alloc_func)0) {
2384*b30d1939SAndy Fiddaman strm->zalloc = zcalloc;
2385*b30d1939SAndy Fiddaman strm->opaque = (voidpf)0;
2386*b30d1939SAndy Fiddaman }
2387*b30d1939SAndy Fiddaman if (strm->zfree == (free_func)0) strm->zfree = zcfree;
2388*b30d1939SAndy Fiddaman state = (struct inflate_state FAR *)
2389*b30d1939SAndy Fiddaman ZALLOC(strm, 1, sizeof(struct inflate_state));
2390*b30d1939SAndy Fiddaman if (state == Z_NULL) return Z_MEM_ERROR;
2391*b30d1939SAndy Fiddaman Tracev((stderr, "inflate: allocated\n"));
2392*b30d1939SAndy Fiddaman strm->state = (struct internal_state FAR *)state;
2393*b30d1939SAndy Fiddaman if (windowBits < 0) {
2394*b30d1939SAndy Fiddaman state->wrap = 0;
2395*b30d1939SAndy Fiddaman windowBits = -windowBits;
2396*b30d1939SAndy Fiddaman }
2397*b30d1939SAndy Fiddaman else {
2398*b30d1939SAndy Fiddaman state->wrap = (windowBits >> 4) + 1;
2399*b30d1939SAndy Fiddaman #ifdef GUNZIP
2400*b30d1939SAndy Fiddaman if (windowBits < 48) windowBits &= 15;
2401*b30d1939SAndy Fiddaman #endif
2402*b30d1939SAndy Fiddaman }
2403*b30d1939SAndy Fiddaman if (windowBits < 8 || windowBits > 15) {
2404*b30d1939SAndy Fiddaman ZFREE(strm, state);
2405*b30d1939SAndy Fiddaman strm->state = Z_NULL;
2406*b30d1939SAndy Fiddaman return Z_STREAM_ERROR;
2407*b30d1939SAndy Fiddaman }
2408*b30d1939SAndy Fiddaman state->wbits = (unsigned)windowBits;
2409*b30d1939SAndy Fiddaman state->window = Z_NULL;
2410*b30d1939SAndy Fiddaman return inflateReset(strm);
2411*b30d1939SAndy Fiddaman }
2412*b30d1939SAndy Fiddaman
inflateInit_(strm,version,stream_size)2413*b30d1939SAndy Fiddaman int ZEXPORT inflateInit_(strm, version, stream_size)
2414*b30d1939SAndy Fiddaman z_streamp strm;
2415*b30d1939SAndy Fiddaman const char *version;
2416*b30d1939SAndy Fiddaman int stream_size;
2417*b30d1939SAndy Fiddaman {
2418*b30d1939SAndy Fiddaman return inflateInit2_(strm, DEF_WBITS, version, stream_size);
2419*b30d1939SAndy Fiddaman }
2420*b30d1939SAndy Fiddaman
2421*b30d1939SAndy Fiddaman /*
2422*b30d1939SAndy Fiddaman Return state with length and distance decoding tables and index sizes set to
2423*b30d1939SAndy Fiddaman fixed code decoding. Normally this returns fixed tables from inffixed.h.
2424*b30d1939SAndy Fiddaman If BUILDFIXED is defined, then instead this routine builds the tables the
2425*b30d1939SAndy Fiddaman first time it's called, and returns those tables the first time and
2426*b30d1939SAndy Fiddaman thereafter. This reduces the size of the code by about 2K bytes, in
2427*b30d1939SAndy Fiddaman exchange for a little execution time. However, BUILDFIXED should not be
2428*b30d1939SAndy Fiddaman used for threaded applications, since the rewriting of the tables and virgin
2429*b30d1939SAndy Fiddaman may not be thread-safe.
2430*b30d1939SAndy Fiddaman */
fixedtables(state)2431*b30d1939SAndy Fiddaman local void fixedtables(state)
2432*b30d1939SAndy Fiddaman struct inflate_state FAR *state;
2433*b30d1939SAndy Fiddaman {
2434*b30d1939SAndy Fiddaman #ifndef _INFFIXED_H
2435*b30d1939SAndy Fiddaman #define _INFFIXED_H 1
2436*b30d1939SAndy Fiddaman static const code lenfix[512] = {
2437*b30d1939SAndy Fiddaman {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
2438*b30d1939SAndy Fiddaman {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
2439*b30d1939SAndy Fiddaman {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
2440*b30d1939SAndy Fiddaman {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
2441*b30d1939SAndy Fiddaman {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
2442*b30d1939SAndy Fiddaman {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
2443*b30d1939SAndy Fiddaman {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
2444*b30d1939SAndy Fiddaman {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
2445*b30d1939SAndy Fiddaman {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
2446*b30d1939SAndy Fiddaman {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
2447*b30d1939SAndy Fiddaman {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
2448*b30d1939SAndy Fiddaman {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
2449*b30d1939SAndy Fiddaman {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
2450*b30d1939SAndy Fiddaman {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
2451*b30d1939SAndy Fiddaman {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
2452*b30d1939SAndy Fiddaman {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
2453*b30d1939SAndy Fiddaman {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
2454*b30d1939SAndy Fiddaman {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
2455*b30d1939SAndy Fiddaman {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
2456*b30d1939SAndy Fiddaman {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
2457*b30d1939SAndy Fiddaman {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
2458*b30d1939SAndy Fiddaman {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
2459*b30d1939SAndy Fiddaman {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
2460*b30d1939SAndy Fiddaman {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
2461*b30d1939SAndy Fiddaman {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
2462*b30d1939SAndy Fiddaman {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
2463*b30d1939SAndy Fiddaman {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
2464*b30d1939SAndy Fiddaman {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
2465*b30d1939SAndy Fiddaman {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
2466*b30d1939SAndy Fiddaman {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
2467*b30d1939SAndy Fiddaman {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
2468*b30d1939SAndy Fiddaman {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
2469*b30d1939SAndy Fiddaman {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
2470*b30d1939SAndy Fiddaman {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
2471*b30d1939SAndy Fiddaman {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
2472*b30d1939SAndy Fiddaman {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
2473*b30d1939SAndy Fiddaman {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
2474*b30d1939SAndy Fiddaman {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
2475*b30d1939SAndy Fiddaman {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
2476*b30d1939SAndy Fiddaman {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
2477*b30d1939SAndy Fiddaman {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
2478*b30d1939SAndy Fiddaman {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
2479*b30d1939SAndy Fiddaman {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
2480*b30d1939SAndy Fiddaman {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
2481*b30d1939SAndy Fiddaman {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
2482*b30d1939SAndy Fiddaman {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
2483*b30d1939SAndy Fiddaman {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
2484*b30d1939SAndy Fiddaman {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
2485*b30d1939SAndy Fiddaman {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
2486*b30d1939SAndy Fiddaman {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
2487*b30d1939SAndy Fiddaman {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
2488*b30d1939SAndy Fiddaman {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
2489*b30d1939SAndy Fiddaman {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
2490*b30d1939SAndy Fiddaman {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
2491*b30d1939SAndy Fiddaman {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
2492*b30d1939SAndy Fiddaman {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
2493*b30d1939SAndy Fiddaman {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
2494*b30d1939SAndy Fiddaman {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
2495*b30d1939SAndy Fiddaman {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
2496*b30d1939SAndy Fiddaman {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
2497*b30d1939SAndy Fiddaman {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
2498*b30d1939SAndy Fiddaman {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
2499*b30d1939SAndy Fiddaman {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
2500*b30d1939SAndy Fiddaman {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
2501*b30d1939SAndy Fiddaman {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
2502*b30d1939SAndy Fiddaman {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
2503*b30d1939SAndy Fiddaman {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
2504*b30d1939SAndy Fiddaman {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
2505*b30d1939SAndy Fiddaman {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
2506*b30d1939SAndy Fiddaman {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
2507*b30d1939SAndy Fiddaman {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
2508*b30d1939SAndy Fiddaman {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
2509*b30d1939SAndy Fiddaman {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
2510*b30d1939SAndy Fiddaman {0,9,255}
2511*b30d1939SAndy Fiddaman };
2512*b30d1939SAndy Fiddaman
2513*b30d1939SAndy Fiddaman static const code distfix[32] = {
2514*b30d1939SAndy Fiddaman {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
2515*b30d1939SAndy Fiddaman {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
2516*b30d1939SAndy Fiddaman {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
2517*b30d1939SAndy Fiddaman {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
2518*b30d1939SAndy Fiddaman {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
2519*b30d1939SAndy Fiddaman {22,5,193},{64,5,0}
2520*b30d1939SAndy Fiddaman };
2521*b30d1939SAndy Fiddaman #endif /* _INFFIXED_H */
2522*b30d1939SAndy Fiddaman state->lencode = lenfix;
2523*b30d1939SAndy Fiddaman state->lenbits = 9;
2524*b30d1939SAndy Fiddaman state->distcode = distfix;
2525*b30d1939SAndy Fiddaman state->distbits = 5;
2526*b30d1939SAndy Fiddaman }
2527*b30d1939SAndy Fiddaman
2528*b30d1939SAndy Fiddaman /*
2529*b30d1939SAndy Fiddaman Update the window with the last wsize (normally 32K) bytes written before
2530*b30d1939SAndy Fiddaman returning. If window does not exist yet, create it. This is only called
2531*b30d1939SAndy Fiddaman when a window is already in use, or when output has been written during this
2532*b30d1939SAndy Fiddaman inflate call, but the end of the deflate stream has not been reached yet.
2533*b30d1939SAndy Fiddaman It is also called to create a window for dictionary data when a dictionary
2534*b30d1939SAndy Fiddaman is loaded.
2535*b30d1939SAndy Fiddaman
2536*b30d1939SAndy Fiddaman Providing output buffers larger than 32K to inflate() should provide a speed
2537*b30d1939SAndy Fiddaman advantage, since only the last 32K of output is copied to the sliding window
2538*b30d1939SAndy Fiddaman upon return from inflate(), and since all distances after the first 32K of
2539*b30d1939SAndy Fiddaman output will fall in the output data, making match copies simpler and faster.
2540*b30d1939SAndy Fiddaman The advantage may be dependent on the size of the processor's data caches.
2541*b30d1939SAndy Fiddaman */
updatewindow(strm,out)2542*b30d1939SAndy Fiddaman local int updatewindow(strm, out)
2543*b30d1939SAndy Fiddaman z_streamp strm;
2544*b30d1939SAndy Fiddaman unsigned out;
2545*b30d1939SAndy Fiddaman {
2546*b30d1939SAndy Fiddaman struct inflate_state FAR *state;
2547*b30d1939SAndy Fiddaman unsigned copy, dist;
2548*b30d1939SAndy Fiddaman
2549*b30d1939SAndy Fiddaman state = (struct inflate_state FAR *)strm->state;
2550*b30d1939SAndy Fiddaman
2551*b30d1939SAndy Fiddaman /* if it hasn't been done already, allocate space for the window */
2552*b30d1939SAndy Fiddaman if (state->window == Z_NULL) {
2553*b30d1939SAndy Fiddaman state->window = (unsigned char FAR *)
2554*b30d1939SAndy Fiddaman ZALLOC(strm, ((unsigned int)1) << state->wbits,
2555*b30d1939SAndy Fiddaman sizeof(unsigned char));
2556*b30d1939SAndy Fiddaman if (state->window == Z_NULL) return 1;
2557*b30d1939SAndy Fiddaman }
2558*b30d1939SAndy Fiddaman
2559*b30d1939SAndy Fiddaman /* if window not in use yet, initialize */
2560*b30d1939SAndy Fiddaman if (state->wsize == 0) {
2561*b30d1939SAndy Fiddaman state->wsize = ((unsigned int)1) << state->wbits;
2562*b30d1939SAndy Fiddaman state->write = 0;
2563*b30d1939SAndy Fiddaman state->whave = 0;
2564*b30d1939SAndy Fiddaman }
2565*b30d1939SAndy Fiddaman
2566*b30d1939SAndy Fiddaman /* copy state->wsize or less output bytes into the circular window */
2567*b30d1939SAndy Fiddaman copy = out - strm->avail_out;
2568*b30d1939SAndy Fiddaman if (copy >= state->wsize) {
2569*b30d1939SAndy Fiddaman zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
2570*b30d1939SAndy Fiddaman state->write = 0;
2571*b30d1939SAndy Fiddaman state->whave = state->wsize;
2572*b30d1939SAndy Fiddaman }
2573*b30d1939SAndy Fiddaman else {
2574*b30d1939SAndy Fiddaman dist = state->wsize - state->write;
2575*b30d1939SAndy Fiddaman if (dist > copy) dist = copy;
2576*b30d1939SAndy Fiddaman zmemcpy(state->window + state->write, strm->next_out - copy, dist);
2577*b30d1939SAndy Fiddaman copy -= dist;
2578*b30d1939SAndy Fiddaman if (copy) {
2579*b30d1939SAndy Fiddaman zmemcpy(state->window, strm->next_out - copy, copy);
2580*b30d1939SAndy Fiddaman state->write = copy;
2581*b30d1939SAndy Fiddaman state->whave = state->wsize;
2582*b30d1939SAndy Fiddaman }
2583*b30d1939SAndy Fiddaman else {
2584*b30d1939SAndy Fiddaman state->write += dist;
2585*b30d1939SAndy Fiddaman if (state->write == state->wsize) state->write = 0;
2586*b30d1939SAndy Fiddaman if (state->whave < state->wsize) state->whave += dist;
2587*b30d1939SAndy Fiddaman }
2588*b30d1939SAndy Fiddaman }
2589*b30d1939SAndy Fiddaman return 0;
2590*b30d1939SAndy Fiddaman }
2591*b30d1939SAndy Fiddaman
2592*b30d1939SAndy Fiddaman /* Macros for inflate(): */
2593*b30d1939SAndy Fiddaman
2594*b30d1939SAndy Fiddaman /* check function to use adler32() for zlib or crc32() for gzip */
2595*b30d1939SAndy Fiddaman #ifdef GUNZIP
2596*b30d1939SAndy Fiddaman # define UPDATE(check, buf, len) \
2597*b30d1939SAndy Fiddaman (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
2598*b30d1939SAndy Fiddaman #else
2599*b30d1939SAndy Fiddaman # define UPDATE(check, buf, len) adler32(check, buf, len)
2600*b30d1939SAndy Fiddaman #endif
2601*b30d1939SAndy Fiddaman
2602*b30d1939SAndy Fiddaman /* check macros for header crc */
2603*b30d1939SAndy Fiddaman #ifdef GUNZIP
2604*b30d1939SAndy Fiddaman # define CRC2(check, word) \
2605*b30d1939SAndy Fiddaman do { \
2606*b30d1939SAndy Fiddaman hbuf[0] = (unsigned char)(word); \
2607*b30d1939SAndy Fiddaman hbuf[1] = (unsigned char)((word) >> 8); \
2608*b30d1939SAndy Fiddaman check = crc32(check, hbuf, 2); \
2609*b30d1939SAndy Fiddaman } while (0)
2610*b30d1939SAndy Fiddaman
2611*b30d1939SAndy Fiddaman # define CRC4(check, word) \
2612*b30d1939SAndy Fiddaman do { \
2613*b30d1939SAndy Fiddaman hbuf[0] = (unsigned char)(word); \
2614*b30d1939SAndy Fiddaman hbuf[1] = (unsigned char)((word) >> 8); \
2615*b30d1939SAndy Fiddaman hbuf[2] = (unsigned char)((word) >> 16); \
2616*b30d1939SAndy Fiddaman hbuf[3] = (unsigned char)((word) >> 24); \
2617*b30d1939SAndy Fiddaman check = crc32(check, hbuf, 4); \
2618*b30d1939SAndy Fiddaman } while (0)
2619*b30d1939SAndy Fiddaman #endif
2620*b30d1939SAndy Fiddaman
2621*b30d1939SAndy Fiddaman /* Load registers with state in inflate() for speed */
2622*b30d1939SAndy Fiddaman #define LOAD() \
2623*b30d1939SAndy Fiddaman do { \
2624*b30d1939SAndy Fiddaman put = strm->next_out; \
2625*b30d1939SAndy Fiddaman left = strm->avail_out; \
2626*b30d1939SAndy Fiddaman next = strm->next_in; \
2627*b30d1939SAndy Fiddaman have = strm->avail_in; \
2628*b30d1939SAndy Fiddaman hold = state->hold; \
2629*b30d1939SAndy Fiddaman bits = state->bits; \
2630*b30d1939SAndy Fiddaman } while (0)
2631*b30d1939SAndy Fiddaman
2632*b30d1939SAndy Fiddaman /* Restore state from registers in inflate() */
2633*b30d1939SAndy Fiddaman #define RESTORE() \
2634*b30d1939SAndy Fiddaman do { \
2635*b30d1939SAndy Fiddaman strm->next_out = put; \
2636*b30d1939SAndy Fiddaman strm->avail_out = left; \
2637*b30d1939SAndy Fiddaman strm->next_in = next; \
2638*b30d1939SAndy Fiddaman strm->avail_in = have; \
2639*b30d1939SAndy Fiddaman state->hold = hold; \
2640*b30d1939SAndy Fiddaman state->bits = bits; \
2641*b30d1939SAndy Fiddaman } while (0)
2642*b30d1939SAndy Fiddaman
2643*b30d1939SAndy Fiddaman /* Clear the input bit accumulator */
2644*b30d1939SAndy Fiddaman #define INITBITS() \
2645*b30d1939SAndy Fiddaman do { \
2646*b30d1939SAndy Fiddaman hold = 0; \
2647*b30d1939SAndy Fiddaman bits = 0; \
2648*b30d1939SAndy Fiddaman } while (0)
2649*b30d1939SAndy Fiddaman
2650*b30d1939SAndy Fiddaman /* Get a byte of input into the bit accumulator, or return from inflate()
2651*b30d1939SAndy Fiddaman if there is no input available. */
2652*b30d1939SAndy Fiddaman #define PULLBYTE() \
2653*b30d1939SAndy Fiddaman do { \
2654*b30d1939SAndy Fiddaman if (have == 0) goto inf_leave; \
2655*b30d1939SAndy Fiddaman have--; \
2656*b30d1939SAndy Fiddaman hold += (unsigned long)(*next++) << bits; \
2657*b30d1939SAndy Fiddaman bits += 8; \
2658*b30d1939SAndy Fiddaman } while (0)
2659*b30d1939SAndy Fiddaman
2660*b30d1939SAndy Fiddaman /* Assure that there are at least n bits in the bit accumulator. If there is
2661*b30d1939SAndy Fiddaman not enough available input to do that, then return from inflate(). */
2662*b30d1939SAndy Fiddaman #define NEEDBITS(n) \
2663*b30d1939SAndy Fiddaman do { \
2664*b30d1939SAndy Fiddaman while (bits < (unsigned)(n)) \
2665*b30d1939SAndy Fiddaman PULLBYTE(); \
2666*b30d1939SAndy Fiddaman } while (0)
2667*b30d1939SAndy Fiddaman
2668*b30d1939SAndy Fiddaman /* Return the low n bits of the bit accumulator (n < 16) */
2669*b30d1939SAndy Fiddaman #define BITS(n) \
2670*b30d1939SAndy Fiddaman ((unsigned)hold & ((((unsigned int)1) << (n)) - 1))
2671*b30d1939SAndy Fiddaman
2672*b30d1939SAndy Fiddaman /* Remove n bits from the bit accumulator */
2673*b30d1939SAndy Fiddaman #define DROPBITS(n) \
2674*b30d1939SAndy Fiddaman do { \
2675*b30d1939SAndy Fiddaman hold >>= (n); \
2676*b30d1939SAndy Fiddaman bits -= (unsigned)(n); \
2677*b30d1939SAndy Fiddaman } while (0)
2678*b30d1939SAndy Fiddaman
2679*b30d1939SAndy Fiddaman /* Remove zero to seven bits as needed to go to a byte boundary */
2680*b30d1939SAndy Fiddaman #define BYTEBITS() \
2681*b30d1939SAndy Fiddaman do { \
2682*b30d1939SAndy Fiddaman hold >>= bits & 7; \
2683*b30d1939SAndy Fiddaman bits -= bits & 7; \
2684*b30d1939SAndy Fiddaman } while (0)
2685*b30d1939SAndy Fiddaman
2686*b30d1939SAndy Fiddaman /* Reverse the bytes in a 32-bit value */
2687*b30d1939SAndy Fiddaman #define REVERSE(q) \
2688*b30d1939SAndy Fiddaman ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
2689*b30d1939SAndy Fiddaman (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
2690*b30d1939SAndy Fiddaman
2691*b30d1939SAndy Fiddaman /*
2692*b30d1939SAndy Fiddaman inflate() uses a state machine to process as much input data and generate as
2693*b30d1939SAndy Fiddaman much output data as possible before returning. The state machine is
2694*b30d1939SAndy Fiddaman structured roughly as follows:
2695*b30d1939SAndy Fiddaman
2696*b30d1939SAndy Fiddaman for (;;) switch (state) {
2697*b30d1939SAndy Fiddaman ...
2698*b30d1939SAndy Fiddaman case STATEn:
2699*b30d1939SAndy Fiddaman if (not enough input data or output space to make progress)
2700*b30d1939SAndy Fiddaman return;
2701*b30d1939SAndy Fiddaman ... make progress ...
2702*b30d1939SAndy Fiddaman state = STATEm;
2703*b30d1939SAndy Fiddaman break;
2704*b30d1939SAndy Fiddaman ...
2705*b30d1939SAndy Fiddaman }
2706*b30d1939SAndy Fiddaman
2707*b30d1939SAndy Fiddaman so when inflate() is called again, the same case is attempted again, and
2708*b30d1939SAndy Fiddaman if the appropriate resources are provided, the machine proceeds to the
2709*b30d1939SAndy Fiddaman next state. The NEEDBITS() macro is usually the way the state evaluates
2710*b30d1939SAndy Fiddaman whether it can proceed or should return. NEEDBITS() does the return if
2711*b30d1939SAndy Fiddaman the requested bits are not available. The typical use of the BITS macros
2712*b30d1939SAndy Fiddaman is:
2713*b30d1939SAndy Fiddaman
2714*b30d1939SAndy Fiddaman NEEDBITS(n);
2715*b30d1939SAndy Fiddaman ... do something with BITS(n) ...
2716*b30d1939SAndy Fiddaman DROPBITS(n);
2717*b30d1939SAndy Fiddaman
2718*b30d1939SAndy Fiddaman where NEEDBITS(n) either returns from inflate() if there isn't enough
2719*b30d1939SAndy Fiddaman input left to load n bits into the accumulator, or it continues. BITS(n)
2720*b30d1939SAndy Fiddaman gives the low n bits in the accumulator. When done, DROPBITS(n) drops
2721*b30d1939SAndy Fiddaman the low n bits off the accumulator. INITBITS() clears the accumulator
2722*b30d1939SAndy Fiddaman and sets the number of available bits to zero. BYTEBITS() discards just
2723*b30d1939SAndy Fiddaman enough bits to put the accumulator on a byte boundary. After BYTEBITS()
2724*b30d1939SAndy Fiddaman and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
2725*b30d1939SAndy Fiddaman
2726*b30d1939SAndy Fiddaman NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
2727*b30d1939SAndy Fiddaman if there is no input available. The decoding of variable length codes uses
2728*b30d1939SAndy Fiddaman PULLBYTE() directly in order to pull just enough bytes to decode the next
2729*b30d1939SAndy Fiddaman code, and no more.
2730*b30d1939SAndy Fiddaman
2731*b30d1939SAndy Fiddaman Some states loop until they get enough input, making sure that enough
2732*b30d1939SAndy Fiddaman state information is maintained to continue the loop where it left off
2733*b30d1939SAndy Fiddaman if NEEDBITS() returns in the loop. For example, want, need, and keep
2734*b30d1939SAndy Fiddaman would all have to actually be part of the saved state in case NEEDBITS()
2735*b30d1939SAndy Fiddaman returns:
2736*b30d1939SAndy Fiddaman
2737*b30d1939SAndy Fiddaman case STATEw:
2738*b30d1939SAndy Fiddaman while (want < need) {
2739*b30d1939SAndy Fiddaman NEEDBITS(n);
2740*b30d1939SAndy Fiddaman keep[want++] = BITS(n);
2741*b30d1939SAndy Fiddaman DROPBITS(n);
2742*b30d1939SAndy Fiddaman }
2743*b30d1939SAndy Fiddaman state = STATEx;
2744*b30d1939SAndy Fiddaman case STATEx:
2745*b30d1939SAndy Fiddaman
2746*b30d1939SAndy Fiddaman As shown above, if the next state is also the next case, then the break
2747*b30d1939SAndy Fiddaman is omitted.
2748*b30d1939SAndy Fiddaman
2749*b30d1939SAndy Fiddaman A state may also return if there is not enough output space available to
2750*b30d1939SAndy Fiddaman complete that state. Those states are copying stored data, writing a
2751*b30d1939SAndy Fiddaman literal byte, and copying a matching string.
2752*b30d1939SAndy Fiddaman
2753*b30d1939SAndy Fiddaman When returning, a "goto inf_leave" is used to update the total counters,
2754*b30d1939SAndy Fiddaman update the check value, and determine whether any progress has been made
2755*b30d1939SAndy Fiddaman during that inflate() call in order to return the proper return code.
2756*b30d1939SAndy Fiddaman Progress is defined as a change in either strm->avail_in or strm->avail_out.
2757*b30d1939SAndy Fiddaman When there is a window, goto inf_leave will update the window with the last
2758*b30d1939SAndy Fiddaman output written. If a goto inf_leave occurs in the middle of decompression
2759*b30d1939SAndy Fiddaman and there is no window currently, goto inf_leave will create one and copy
2760*b30d1939SAndy Fiddaman output to the window for the next call of inflate().
2761*b30d1939SAndy Fiddaman
2762*b30d1939SAndy Fiddaman In this implementation, the flush parameter of inflate() only affects the
2763*b30d1939SAndy Fiddaman return code (per zlib.h). inflate() always writes as much as possible to
2764*b30d1939SAndy Fiddaman strm->next_out, given the space available and the provided input--the effect
2765*b30d1939SAndy Fiddaman documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers
2766*b30d1939SAndy Fiddaman the allocation of and copying into a sliding window until necessary, which
2767*b30d1939SAndy Fiddaman provides the effect documented in zlib.h for Z_FINISH when the entire input
2768*b30d1939SAndy Fiddaman stream available. So the only thing the flush parameter actually does is:
2769*b30d1939SAndy Fiddaman when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it
2770*b30d1939SAndy Fiddaman will return Z_BUF_ERROR if it has not reached the end of the stream.
2771*b30d1939SAndy Fiddaman */
2772*b30d1939SAndy Fiddaman
inflate(strm,flush)2773*b30d1939SAndy Fiddaman int ZEXPORT inflate(strm, flush)
2774*b30d1939SAndy Fiddaman z_streamp strm;
2775*b30d1939SAndy Fiddaman int flush;
2776*b30d1939SAndy Fiddaman {
2777*b30d1939SAndy Fiddaman struct inflate_state FAR *state;
2778*b30d1939SAndy Fiddaman unsigned char FAR *next; /* next input */
2779*b30d1939SAndy Fiddaman unsigned char FAR *put; /* next output */
2780*b30d1939SAndy Fiddaman unsigned have, left; /* available input and output */
2781*b30d1939SAndy Fiddaman unsigned long hold; /* bit buffer */
2782*b30d1939SAndy Fiddaman unsigned bits; /* bits in bit buffer */
2783*b30d1939SAndy Fiddaman unsigned in, out; /* save starting available input and output */
2784*b30d1939SAndy Fiddaman unsigned copy; /* number of stored or match bytes to copy */
2785*b30d1939SAndy Fiddaman unsigned char FAR *from; /* where to copy match bytes from */
2786*b30d1939SAndy Fiddaman code this; /* current decoding table entry */
2787*b30d1939SAndy Fiddaman code last; /* parent table entry */
2788*b30d1939SAndy Fiddaman unsigned len; /* length to copy for repeats, bits to drop */
2789*b30d1939SAndy Fiddaman int ret; /* return code */
2790*b30d1939SAndy Fiddaman #ifdef GUNZIP
2791*b30d1939SAndy Fiddaman unsigned char hbuf[4]; /* buffer for gzip header crc calculation */
2792*b30d1939SAndy Fiddaman #endif
2793*b30d1939SAndy Fiddaman static const unsigned short order[19] = /* permutation of code lengths */
2794*b30d1939SAndy Fiddaman {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
2795*b30d1939SAndy Fiddaman
2796*b30d1939SAndy Fiddaman if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
2797*b30d1939SAndy Fiddaman (strm->next_in == Z_NULL && strm->avail_in != 0))
2798*b30d1939SAndy Fiddaman return Z_STREAM_ERROR;
2799*b30d1939SAndy Fiddaman
2800*b30d1939SAndy Fiddaman state = (struct inflate_state FAR *)strm->state;
2801*b30d1939SAndy Fiddaman if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */
2802*b30d1939SAndy Fiddaman LOAD();
2803*b30d1939SAndy Fiddaman in = have;
2804*b30d1939SAndy Fiddaman out = left;
2805*b30d1939SAndy Fiddaman ret = Z_OK;
2806*b30d1939SAndy Fiddaman for (;;)
2807*b30d1939SAndy Fiddaman switch (state->mode) {
2808*b30d1939SAndy Fiddaman case HEAD:
2809*b30d1939SAndy Fiddaman if (state->wrap == 0) {
2810*b30d1939SAndy Fiddaman state->mode = TYPEDO;
2811*b30d1939SAndy Fiddaman break;
2812*b30d1939SAndy Fiddaman }
2813*b30d1939SAndy Fiddaman NEEDBITS(16);
2814*b30d1939SAndy Fiddaman #ifdef GUNZIP
2815*b30d1939SAndy Fiddaman if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */
2816*b30d1939SAndy Fiddaman state->check = crc32(0L, Z_NULL, 0);
2817*b30d1939SAndy Fiddaman CRC2(state->check, hold);
2818*b30d1939SAndy Fiddaman INITBITS();
2819*b30d1939SAndy Fiddaman state->mode = FLAGS;
2820*b30d1939SAndy Fiddaman break;
2821*b30d1939SAndy Fiddaman }
2822*b30d1939SAndy Fiddaman state->flags = 0; /* expect zlib header */
2823*b30d1939SAndy Fiddaman if (state->head != Z_NULL)
2824*b30d1939SAndy Fiddaman state->head->done = -1;
2825*b30d1939SAndy Fiddaman if (!(state->wrap & 1) || /* check if zlib header allowed */
2826*b30d1939SAndy Fiddaman #else
2827*b30d1939SAndy Fiddaman if (
2828*b30d1939SAndy Fiddaman #endif
2829*b30d1939SAndy Fiddaman ((BITS(8) << 8) + (hold >> 8)) % 31) {
2830*b30d1939SAndy Fiddaman strm->msg = (char *)"incorrect header check";
2831*b30d1939SAndy Fiddaman state->mode = BAD;
2832*b30d1939SAndy Fiddaman break;
2833*b30d1939SAndy Fiddaman }
2834*b30d1939SAndy Fiddaman if (BITS(4) != Z_DEFLATED) {
2835*b30d1939SAndy Fiddaman strm->msg = (char *)"unknown compression method";
2836*b30d1939SAndy Fiddaman state->mode = BAD;
2837*b30d1939SAndy Fiddaman break;
2838*b30d1939SAndy Fiddaman }
2839*b30d1939SAndy Fiddaman DROPBITS(4);
2840*b30d1939SAndy Fiddaman len = BITS(4) + 8;
2841*b30d1939SAndy Fiddaman if (len > state->wbits) {
2842*b30d1939SAndy Fiddaman strm->msg = (char *)"invalid window size";
2843*b30d1939SAndy Fiddaman state->mode = BAD;
2844*b30d1939SAndy Fiddaman break;
2845*b30d1939SAndy Fiddaman }
2846*b30d1939SAndy Fiddaman state->dmax = ((unsigned int)1) << len;
2847*b30d1939SAndy Fiddaman Tracev((stderr, "inflate: zlib header ok\n"));
2848*b30d1939SAndy Fiddaman strm->adler = state->check = adler32(0L, Z_NULL, 0);
2849*b30d1939SAndy Fiddaman state->mode = hold & 0x200 ? DICTID : TYPE;
2850*b30d1939SAndy Fiddaman INITBITS();
2851*b30d1939SAndy Fiddaman break;
2852*b30d1939SAndy Fiddaman #ifdef GUNZIP
2853*b30d1939SAndy Fiddaman case FLAGS:
2854*b30d1939SAndy Fiddaman NEEDBITS(16);
2855*b30d1939SAndy Fiddaman state->flags = (int)(hold);
2856*b30d1939SAndy Fiddaman if ((state->flags & 0xff) != Z_DEFLATED) {
2857*b30d1939SAndy Fiddaman strm->msg = (char *)"unknown compression method";
2858*b30d1939SAndy Fiddaman state->mode = BAD;
2859*b30d1939SAndy Fiddaman break;
2860*b30d1939SAndy Fiddaman }
2861*b30d1939SAndy Fiddaman if (state->flags & 0xe000) {
2862*b30d1939SAndy Fiddaman strm->msg = (char *)"unknown header flags set";
2863*b30d1939SAndy Fiddaman state->mode = BAD;
2864*b30d1939SAndy Fiddaman break;
2865*b30d1939SAndy Fiddaman }
2866*b30d1939SAndy Fiddaman if (state->head != Z_NULL)
2867*b30d1939SAndy Fiddaman state->head->text = (int)((hold >> 8) & 1);
2868*b30d1939SAndy Fiddaman if (state->flags & 0x0200) CRC2(state->check, hold);
2869*b30d1939SAndy Fiddaman INITBITS();
2870*b30d1939SAndy Fiddaman state->mode = TIME;
2871*b30d1939SAndy Fiddaman case TIME:
2872*b30d1939SAndy Fiddaman NEEDBITS(32);
2873*b30d1939SAndy Fiddaman if (state->head != Z_NULL)
2874*b30d1939SAndy Fiddaman state->head->time = hold;
2875*b30d1939SAndy Fiddaman if (state->flags & 0x0200) CRC4(state->check, hold);
2876*b30d1939SAndy Fiddaman INITBITS();
2877*b30d1939SAndy Fiddaman state->mode = OS;
2878*b30d1939SAndy Fiddaman case OS:
2879*b30d1939SAndy Fiddaman NEEDBITS(16);
2880*b30d1939SAndy Fiddaman if (state->head != Z_NULL) {
2881*b30d1939SAndy Fiddaman state->head->xflags = (int)(hold & 0xff);
2882*b30d1939SAndy Fiddaman state->head->os = (int)(hold >> 8);
2883*b30d1939SAndy Fiddaman }
2884*b30d1939SAndy Fiddaman if (state->flags & 0x0200) CRC2(state->check, hold);
2885*b30d1939SAndy Fiddaman INITBITS();
2886*b30d1939SAndy Fiddaman state->mode = EXLEN;
2887*b30d1939SAndy Fiddaman case EXLEN:
2888*b30d1939SAndy Fiddaman if (state->flags & 0x0400) {
2889*b30d1939SAndy Fiddaman NEEDBITS(16);
2890*b30d1939SAndy Fiddaman state->length = (unsigned)(hold);
2891*b30d1939SAndy Fiddaman if (state->head != Z_NULL)
2892*b30d1939SAndy Fiddaman state->head->extra_len = (unsigned)hold;
2893*b30d1939SAndy Fiddaman if (state->flags & 0x0200) CRC2(state->check, hold);
2894*b30d1939SAndy Fiddaman INITBITS();
2895*b30d1939SAndy Fiddaman }
2896*b30d1939SAndy Fiddaman else if (state->head != Z_NULL)
2897*b30d1939SAndy Fiddaman state->head->extra = Z_NULL;
2898*b30d1939SAndy Fiddaman state->mode = EXTRA;
2899*b30d1939SAndy Fiddaman case EXTRA:
2900*b30d1939SAndy Fiddaman if (state->flags & 0x0400) {
2901*b30d1939SAndy Fiddaman copy = state->length;
2902*b30d1939SAndy Fiddaman if (copy > have) copy = have;
2903*b30d1939SAndy Fiddaman if (copy) {
2904*b30d1939SAndy Fiddaman if (state->head != Z_NULL &&
2905*b30d1939SAndy Fiddaman state->head->extra != Z_NULL) {
2906*b30d1939SAndy Fiddaman len = state->head->extra_len - state->length;
2907*b30d1939SAndy Fiddaman zmemcpy(state->head->extra + len, next,
2908*b30d1939SAndy Fiddaman len + copy > state->head->extra_max ?
2909*b30d1939SAndy Fiddaman state->head->extra_max - len : copy);
2910*b30d1939SAndy Fiddaman }
2911*b30d1939SAndy Fiddaman if (state->flags & 0x0200)
2912*b30d1939SAndy Fiddaman state->check = crc32(state->check, next, copy);
2913*b30d1939SAndy Fiddaman have -= copy;
2914*b30d1939SAndy Fiddaman next += copy;
2915*b30d1939SAndy Fiddaman state->length -= copy;
2916*b30d1939SAndy Fiddaman }
2917*b30d1939SAndy Fiddaman if (state->length) goto inf_leave;
2918*b30d1939SAndy Fiddaman }
2919*b30d1939SAndy Fiddaman state->length = 0;
2920*b30d1939SAndy Fiddaman state->mode = NAME;
2921*b30d1939SAndy Fiddaman case NAME:
2922*b30d1939SAndy Fiddaman if (state->flags & 0x0800) {
2923*b30d1939SAndy Fiddaman if (have == 0) goto inf_leave;
2924*b30d1939SAndy Fiddaman copy = 0;
2925*b30d1939SAndy Fiddaman do {
2926*b30d1939SAndy Fiddaman len = (unsigned)(next[copy++]);
2927*b30d1939SAndy Fiddaman if (state->head != Z_NULL &&
2928*b30d1939SAndy Fiddaman state->head->name != Z_NULL &&
2929*b30d1939SAndy Fiddaman state->length < state->head->name_max)
2930*b30d1939SAndy Fiddaman state->head->name[state->length++] = len;
2931*b30d1939SAndy Fiddaman } while (len && copy < have);
2932*b30d1939SAndy Fiddaman if (state->flags & 0x0200)
2933*b30d1939SAndy Fiddaman state->check = crc32(state->check, next, copy);
2934*b30d1939SAndy Fiddaman have -= copy;
2935*b30d1939SAndy Fiddaman next += copy;
2936*b30d1939SAndy Fiddaman if (len) goto inf_leave;
2937*b30d1939SAndy Fiddaman }
2938*b30d1939SAndy Fiddaman else if (state->head != Z_NULL)
2939*b30d1939SAndy Fiddaman state->head->name = Z_NULL;
2940*b30d1939SAndy Fiddaman state->length = 0;
2941*b30d1939SAndy Fiddaman state->mode = COMMENT;
2942*b30d1939SAndy Fiddaman case COMMENT:
2943*b30d1939SAndy Fiddaman if (state->flags & 0x1000) {
2944*b30d1939SAndy Fiddaman if (have == 0) goto inf_leave;
2945*b30d1939SAndy Fiddaman copy = 0;
2946*b30d1939SAndy Fiddaman do {
2947*b30d1939SAndy Fiddaman len = (unsigned)(next[copy++]);
2948*b30d1939SAndy Fiddaman if (state->head != Z_NULL &&
2949*b30d1939SAndy Fiddaman state->head->comment != Z_NULL &&
2950*b30d1939SAndy Fiddaman state->length < state->head->comm_max)
2951*b30d1939SAndy Fiddaman state->head->comment[state->length++] = len;
2952*b30d1939SAndy Fiddaman } while (len && copy < have);
2953*b30d1939SAndy Fiddaman if (state->flags & 0x0200)
2954*b30d1939SAndy Fiddaman state->check = crc32(state->check, next, copy);
2955*b30d1939SAndy Fiddaman have -= copy;
2956*b30d1939SAndy Fiddaman next += copy;
2957*b30d1939SAndy Fiddaman if (len) goto inf_leave;
2958*b30d1939SAndy Fiddaman }
2959*b30d1939SAndy Fiddaman else if (state->head != Z_NULL)
2960*b30d1939SAndy Fiddaman state->head->comment = Z_NULL;
2961*b30d1939SAndy Fiddaman state->mode = HCRC;
2962*b30d1939SAndy Fiddaman case HCRC:
2963*b30d1939SAndy Fiddaman if (state->flags & 0x0200) {
2964*b30d1939SAndy Fiddaman NEEDBITS(16);
2965*b30d1939SAndy Fiddaman if (hold != (state->check & 0xffff)) {
2966*b30d1939SAndy Fiddaman strm->msg = (char *)"header crc mismatch";
2967*b30d1939SAndy Fiddaman state->mode = BAD;
2968*b30d1939SAndy Fiddaman break;
2969*b30d1939SAndy Fiddaman }
2970*b30d1939SAndy Fiddaman INITBITS();
2971*b30d1939SAndy Fiddaman }
2972*b30d1939SAndy Fiddaman if (state->head != Z_NULL) {
2973*b30d1939SAndy Fiddaman state->head->hcrc = (int)((state->flags >> 9) & 1);
2974*b30d1939SAndy Fiddaman state->head->done = 1;
2975*b30d1939SAndy Fiddaman }
2976*b30d1939SAndy Fiddaman strm->adler = state->check = crc32(0L, Z_NULL, 0);
2977*b30d1939SAndy Fiddaman state->mode = TYPE;
2978*b30d1939SAndy Fiddaman break;
2979*b30d1939SAndy Fiddaman #endif
2980*b30d1939SAndy Fiddaman case DICTID:
2981*b30d1939SAndy Fiddaman NEEDBITS(32);
2982*b30d1939SAndy Fiddaman strm->adler = state->check = REVERSE(hold);
2983*b30d1939SAndy Fiddaman INITBITS();
2984*b30d1939SAndy Fiddaman state->mode = DICT;
2985*b30d1939SAndy Fiddaman case DICT:
2986*b30d1939SAndy Fiddaman if (state->havedict == 0) {
2987*b30d1939SAndy Fiddaman RESTORE();
2988*b30d1939SAndy Fiddaman return Z_NEED_DICT;
2989*b30d1939SAndy Fiddaman }
2990*b30d1939SAndy Fiddaman strm->adler = state->check = adler32(0L, Z_NULL, 0);
2991*b30d1939SAndy Fiddaman state->mode = TYPE;
2992*b30d1939SAndy Fiddaman case TYPE:
2993*b30d1939SAndy Fiddaman if (flush == Z_BLOCK) goto inf_leave;
2994*b30d1939SAndy Fiddaman case TYPEDO:
2995*b30d1939SAndy Fiddaman if (state->last) {
2996*b30d1939SAndy Fiddaman BYTEBITS();
2997*b30d1939SAndy Fiddaman state->mode = CHECK;
2998*b30d1939SAndy Fiddaman break;
2999*b30d1939SAndy Fiddaman }
3000*b30d1939SAndy Fiddaman NEEDBITS(3);
3001*b30d1939SAndy Fiddaman state->last = BITS(1);
3002*b30d1939SAndy Fiddaman DROPBITS(1);
3003*b30d1939SAndy Fiddaman switch (BITS(2)) {
3004*b30d1939SAndy Fiddaman case 0: /* stored block */
3005*b30d1939SAndy Fiddaman Tracev((stderr, "inflate: stored block%s\n",
3006*b30d1939SAndy Fiddaman state->last ? " (last)" : ""));
3007*b30d1939SAndy Fiddaman state->mode = STORED;
3008*b30d1939SAndy Fiddaman break;
3009*b30d1939SAndy Fiddaman case 1: /* fixed block */
3010*b30d1939SAndy Fiddaman fixedtables(state);
3011*b30d1939SAndy Fiddaman Tracev((stderr, "inflate: fixed codes block%s\n",
3012*b30d1939SAndy Fiddaman state->last ? " (last)" : ""));
3013*b30d1939SAndy Fiddaman state->mode = LEN; /* decode codes */
3014*b30d1939SAndy Fiddaman break;
3015*b30d1939SAndy Fiddaman case 2: /* dynamic block */
3016*b30d1939SAndy Fiddaman Tracev((stderr, "inflate: dynamic codes block%s\n",
3017*b30d1939SAndy Fiddaman state->last ? " (last)" : ""));
3018*b30d1939SAndy Fiddaman state->mode = TABLE;
3019*b30d1939SAndy Fiddaman break;
3020*b30d1939SAndy Fiddaman case 3:
3021*b30d1939SAndy Fiddaman strm->msg = (char *)"invalid block type";
3022*b30d1939SAndy Fiddaman state->mode = BAD;
3023*b30d1939SAndy Fiddaman }
3024*b30d1939SAndy Fiddaman DROPBITS(2);
3025*b30d1939SAndy Fiddaman break;
3026*b30d1939SAndy Fiddaman case STORED:
3027*b30d1939SAndy Fiddaman BYTEBITS(); /* go to byte boundary */
3028*b30d1939SAndy Fiddaman NEEDBITS(32);
3029*b30d1939SAndy Fiddaman if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
3030*b30d1939SAndy Fiddaman strm->msg = (char *)"invalid stored block lengths";
3031*b30d1939SAndy Fiddaman state->mode = BAD;
3032*b30d1939SAndy Fiddaman break;
3033*b30d1939SAndy Fiddaman }
3034*b30d1939SAndy Fiddaman state->length = (unsigned)hold & 0xffff;
3035*b30d1939SAndy Fiddaman Tracev((stderr, "inflate: stored length %u\n",
3036*b30d1939SAndy Fiddaman state->length));
3037*b30d1939SAndy Fiddaman INITBITS();
3038*b30d1939SAndy Fiddaman state->mode = COPY;
3039*b30d1939SAndy Fiddaman case COPY:
3040*b30d1939SAndy Fiddaman copy = state->length;
3041*b30d1939SAndy Fiddaman if (copy) {
3042*b30d1939SAndy Fiddaman if (copy > have) copy = have;
3043*b30d1939SAndy Fiddaman if (copy > left) copy = left;
3044*b30d1939SAndy Fiddaman if (copy == 0) goto inf_leave;
3045*b30d1939SAndy Fiddaman zmemcpy(put, next, copy);
3046*b30d1939SAndy Fiddaman have -= copy;
3047*b30d1939SAndy Fiddaman next += copy;
3048*b30d1939SAndy Fiddaman left -= copy;
3049*b30d1939SAndy Fiddaman put += copy;
3050*b30d1939SAndy Fiddaman state->length -= copy;
3051*b30d1939SAndy Fiddaman break;
3052*b30d1939SAndy Fiddaman }
3053*b30d1939SAndy Fiddaman Tracev((stderr, "inflate: stored end\n"));
3054*b30d1939SAndy Fiddaman state->mode = TYPE;
3055*b30d1939SAndy Fiddaman break;
3056*b30d1939SAndy Fiddaman case TABLE:
3057*b30d1939SAndy Fiddaman NEEDBITS(14);
3058*b30d1939SAndy Fiddaman state->nlen = BITS(5) + 257;
3059*b30d1939SAndy Fiddaman DROPBITS(5);
3060*b30d1939SAndy Fiddaman state->ndist = BITS(5) + 1;
3061*b30d1939SAndy Fiddaman DROPBITS(5);
3062*b30d1939SAndy Fiddaman state->ncode = BITS(4) + 4;
3063*b30d1939SAndy Fiddaman DROPBITS(4);
3064*b30d1939SAndy Fiddaman #ifndef PKZIP_BUG_WORKAROUND
3065*b30d1939SAndy Fiddaman if (state->nlen > 286 || state->ndist > 30) {
3066*b30d1939SAndy Fiddaman strm->msg = (char *)"too many length or distance symbols";
3067*b30d1939SAndy Fiddaman state->mode = BAD;
3068*b30d1939SAndy Fiddaman break;
3069*b30d1939SAndy Fiddaman }
3070*b30d1939SAndy Fiddaman #endif
3071*b30d1939SAndy Fiddaman Tracev((stderr, "inflate: table sizes ok\n"));
3072*b30d1939SAndy Fiddaman state->have = 0;
3073*b30d1939SAndy Fiddaman state->mode = LENLENS;
3074*b30d1939SAndy Fiddaman case LENLENS:
3075*b30d1939SAndy Fiddaman while (state->have < state->ncode) {
3076*b30d1939SAndy Fiddaman NEEDBITS(3);
3077*b30d1939SAndy Fiddaman state->lens[order[state->have++]] = (unsigned short)BITS(3);
3078*b30d1939SAndy Fiddaman DROPBITS(3);
3079*b30d1939SAndy Fiddaman }
3080*b30d1939SAndy Fiddaman while (state->have < 19)
3081*b30d1939SAndy Fiddaman state->lens[order[state->have++]] = 0;
3082*b30d1939SAndy Fiddaman state->next = state->codes;
3083*b30d1939SAndy Fiddaman state->lencode = (code const FAR *)(state->next);
3084*b30d1939SAndy Fiddaman state->lenbits = 7;
3085*b30d1939SAndy Fiddaman ret = inflate_table(CODES, state->lens, 19, &(state->next),
3086*b30d1939SAndy Fiddaman &(state->lenbits), state->work);
3087*b30d1939SAndy Fiddaman if (ret) {
3088*b30d1939SAndy Fiddaman strm->msg = (char *)"invalid code lengths set";
3089*b30d1939SAndy Fiddaman state->mode = BAD;
3090*b30d1939SAndy Fiddaman break;
3091*b30d1939SAndy Fiddaman }
3092*b30d1939SAndy Fiddaman Tracev((stderr, "inflate: code lengths ok\n"));
3093*b30d1939SAndy Fiddaman state->have = 0;
3094*b30d1939SAndy Fiddaman state->mode = CODELENS;
3095*b30d1939SAndy Fiddaman case CODELENS:
3096*b30d1939SAndy Fiddaman while (state->have < state->nlen + state->ndist) {
3097*b30d1939SAndy Fiddaman for (;;) {
3098*b30d1939SAndy Fiddaman this = state->lencode[BITS(state->lenbits)];
3099*b30d1939SAndy Fiddaman if ((unsigned)(this.bits) <= bits) break;
3100*b30d1939SAndy Fiddaman PULLBYTE();
3101*b30d1939SAndy Fiddaman }
3102*b30d1939SAndy Fiddaman if (this.val < 16) {
3103*b30d1939SAndy Fiddaman NEEDBITS(this.bits);
3104*b30d1939SAndy Fiddaman DROPBITS(this.bits);
3105*b30d1939SAndy Fiddaman state->lens[state->have++] = this.val;
3106*b30d1939SAndy Fiddaman }
3107*b30d1939SAndy Fiddaman else {
3108*b30d1939SAndy Fiddaman if (this.val == 16) {
3109*b30d1939SAndy Fiddaman NEEDBITS(this.bits + 2);
3110*b30d1939SAndy Fiddaman DROPBITS(this.bits);
3111*b30d1939SAndy Fiddaman if (state->have == 0) {
3112*b30d1939SAndy Fiddaman strm->msg = (char *)"invalid bit length repeat";
3113*b30d1939SAndy Fiddaman state->mode = BAD;
3114*b30d1939SAndy Fiddaman break;
3115*b30d1939SAndy Fiddaman }
3116*b30d1939SAndy Fiddaman len = state->lens[state->have - 1];
3117*b30d1939SAndy Fiddaman copy = 3 + BITS(2);
3118*b30d1939SAndy Fiddaman DROPBITS(2);
3119*b30d1939SAndy Fiddaman }
3120*b30d1939SAndy Fiddaman else if (this.val == 17) {
3121*b30d1939SAndy Fiddaman NEEDBITS(this.bits + 3);
3122*b30d1939SAndy Fiddaman DROPBITS(this.bits);
3123*b30d1939SAndy Fiddaman len = 0;
3124*b30d1939SAndy Fiddaman copy = 3 + BITS(3);
3125*b30d1939SAndy Fiddaman DROPBITS(3);
3126*b30d1939SAndy Fiddaman }
3127*b30d1939SAndy Fiddaman else {
3128*b30d1939SAndy Fiddaman NEEDBITS(this.bits + 7);
3129*b30d1939SAndy Fiddaman DROPBITS(this.bits);
3130*b30d1939SAndy Fiddaman len = 0;
3131*b30d1939SAndy Fiddaman copy = 11 + BITS(7);
3132*b30d1939SAndy Fiddaman DROPBITS(7);
3133*b30d1939SAndy Fiddaman }
3134*b30d1939SAndy Fiddaman if (state->have + copy > state->nlen + state->ndist) {
3135*b30d1939SAndy Fiddaman strm->msg = (char *)"invalid bit length repeat";
3136*b30d1939SAndy Fiddaman state->mode = BAD;
3137*b30d1939SAndy Fiddaman break;
3138*b30d1939SAndy Fiddaman }
3139*b30d1939SAndy Fiddaman while (copy--)
3140*b30d1939SAndy Fiddaman state->lens[state->have++] = (unsigned short)len;
3141*b30d1939SAndy Fiddaman }
3142*b30d1939SAndy Fiddaman }
3143*b30d1939SAndy Fiddaman
3144*b30d1939SAndy Fiddaman /* handle error breaks in while */
3145*b30d1939SAndy Fiddaman if (state->mode == BAD) break;
3146*b30d1939SAndy Fiddaman
3147*b30d1939SAndy Fiddaman /* build code tables */
3148*b30d1939SAndy Fiddaman state->next = state->codes;
3149*b30d1939SAndy Fiddaman state->lencode = (code const FAR *)(state->next);
3150*b30d1939SAndy Fiddaman state->lenbits = 9;
3151*b30d1939SAndy Fiddaman ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
3152*b30d1939SAndy Fiddaman &(state->lenbits), state->work);
3153*b30d1939SAndy Fiddaman if (ret) {
3154*b30d1939SAndy Fiddaman strm->msg = (char *)"invalid literal/lengths set";
3155*b30d1939SAndy Fiddaman state->mode = BAD;
3156*b30d1939SAndy Fiddaman break;
3157*b30d1939SAndy Fiddaman }
3158*b30d1939SAndy Fiddaman state->distcode = (code const FAR *)(state->next);
3159*b30d1939SAndy Fiddaman state->distbits = 6;
3160*b30d1939SAndy Fiddaman ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
3161*b30d1939SAndy Fiddaman &(state->next), &(state->distbits), state->work);
3162*b30d1939SAndy Fiddaman if (ret) {
3163*b30d1939SAndy Fiddaman strm->msg = (char *)"invalid distances set";
3164*b30d1939SAndy Fiddaman state->mode = BAD;
3165*b30d1939SAndy Fiddaman break;
3166*b30d1939SAndy Fiddaman }
3167*b30d1939SAndy Fiddaman Tracev((stderr, "inflate: codes ok\n"));
3168*b30d1939SAndy Fiddaman state->mode = LEN;
3169*b30d1939SAndy Fiddaman case LEN:
3170*b30d1939SAndy Fiddaman if (have >= 6 && left >= 258) {
3171*b30d1939SAndy Fiddaman RESTORE();
3172*b30d1939SAndy Fiddaman inflate_fast(strm, out);
3173*b30d1939SAndy Fiddaman LOAD();
3174*b30d1939SAndy Fiddaman break;
3175*b30d1939SAndy Fiddaman }
3176*b30d1939SAndy Fiddaman for (;;) {
3177*b30d1939SAndy Fiddaman this = state->lencode[BITS(state->lenbits)];
3178*b30d1939SAndy Fiddaman if ((unsigned)(this.bits) <= bits) break;
3179*b30d1939SAndy Fiddaman PULLBYTE();
3180*b30d1939SAndy Fiddaman }
3181*b30d1939SAndy Fiddaman if (this.op && (this.op & 0xf0) == 0) {
3182*b30d1939SAndy Fiddaman last = this;
3183*b30d1939SAndy Fiddaman for (;;) {
3184*b30d1939SAndy Fiddaman this = state->lencode[last.val +
3185*b30d1939SAndy Fiddaman (BITS(last.bits + last.op) >> last.bits)];
3186*b30d1939SAndy Fiddaman if ((unsigned)(last.bits + this.bits) <= bits) break;
3187*b30d1939SAndy Fiddaman PULLBYTE();
3188*b30d1939SAndy Fiddaman }
3189*b30d1939SAndy Fiddaman DROPBITS(last.bits);
3190*b30d1939SAndy Fiddaman }
3191*b30d1939SAndy Fiddaman DROPBITS(this.bits);
3192*b30d1939SAndy Fiddaman state->length = (unsigned)this.val;
3193*b30d1939SAndy Fiddaman if ((int)(this.op) == 0) {
3194*b30d1939SAndy Fiddaman Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
3195*b30d1939SAndy Fiddaman "inflate: literal '%c'\n" :
3196*b30d1939SAndy Fiddaman "inflate: literal 0x%02x\n", this.val));
3197*b30d1939SAndy Fiddaman state->mode = LIT;
3198*b30d1939SAndy Fiddaman break;
3199*b30d1939SAndy Fiddaman }
3200*b30d1939SAndy Fiddaman if (this.op & 32) {
3201*b30d1939SAndy Fiddaman Tracevv((stderr, "inflate: end of block\n"));
3202*b30d1939SAndy Fiddaman state->mode = TYPE;
3203*b30d1939SAndy Fiddaman break;
3204*b30d1939SAndy Fiddaman }
3205*b30d1939SAndy Fiddaman if (this.op & 64) {
3206*b30d1939SAndy Fiddaman strm->msg = (char *)"invalid literal/length code";
3207*b30d1939SAndy Fiddaman state->mode = BAD;
3208*b30d1939SAndy Fiddaman break;
3209*b30d1939SAndy Fiddaman }
3210*b30d1939SAndy Fiddaman state->extra = (unsigned)(this.op) & 15;
3211*b30d1939SAndy Fiddaman state->mode = LENEXT;
3212*b30d1939SAndy Fiddaman case LENEXT:
3213*b30d1939SAndy Fiddaman if (state->extra) {
3214*b30d1939SAndy Fiddaman NEEDBITS(state->extra);
3215*b30d1939SAndy Fiddaman state->length += BITS(state->extra);
3216*b30d1939SAndy Fiddaman DROPBITS(state->extra);
3217*b30d1939SAndy Fiddaman }
3218*b30d1939SAndy Fiddaman Tracevv((stderr, "inflate: length %u\n", state->length));
3219*b30d1939SAndy Fiddaman state->mode = DIST;
3220*b30d1939SAndy Fiddaman case DIST:
3221*b30d1939SAndy Fiddaman for (;;) {
3222*b30d1939SAndy Fiddaman this = state->distcode[BITS(state->distbits)];
3223*b30d1939SAndy Fiddaman if ((unsigned)(this.bits) <= bits) break;
3224*b30d1939SAndy Fiddaman PULLBYTE();
3225*b30d1939SAndy Fiddaman }
3226*b30d1939SAndy Fiddaman if ((this.op & 0xf0) == 0) {
3227*b30d1939SAndy Fiddaman last = this;
3228*b30d1939SAndy Fiddaman for (;;) {
3229*b30d1939SAndy Fiddaman this = state->distcode[last.val +
3230*b30d1939SAndy Fiddaman (BITS(last.bits + last.op) >> last.bits)];
3231*b30d1939SAndy Fiddaman if ((unsigned)(last.bits + this.bits) <= bits) break;
3232*b30d1939SAndy Fiddaman PULLBYTE();
3233*b30d1939SAndy Fiddaman }
3234*b30d1939SAndy Fiddaman DROPBITS(last.bits);
3235*b30d1939SAndy Fiddaman }
3236*b30d1939SAndy Fiddaman DROPBITS(this.bits);
3237*b30d1939SAndy Fiddaman if (this.op & 64) {
3238*b30d1939SAndy Fiddaman strm->msg = (char *)"invalid distance code";
3239*b30d1939SAndy Fiddaman state->mode = BAD;
3240*b30d1939SAndy Fiddaman break;
3241*b30d1939SAndy Fiddaman }
3242*b30d1939SAndy Fiddaman state->offset = (unsigned)this.val;
3243*b30d1939SAndy Fiddaman state->extra = (unsigned)(this.op) & 15;
3244*b30d1939SAndy Fiddaman state->mode = DISTEXT;
3245*b30d1939SAndy Fiddaman case DISTEXT:
3246*b30d1939SAndy Fiddaman if (state->extra) {
3247*b30d1939SAndy Fiddaman NEEDBITS(state->extra);
3248*b30d1939SAndy Fiddaman state->offset += BITS(state->extra);
3249*b30d1939SAndy Fiddaman DROPBITS(state->extra);
3250*b30d1939SAndy Fiddaman }
3251*b30d1939SAndy Fiddaman #ifdef INFLATE_STRICT
3252*b30d1939SAndy Fiddaman if (state->offset > state->dmax) {
3253*b30d1939SAndy Fiddaman strm->msg = (char *)"invalid distance too far back";
3254*b30d1939SAndy Fiddaman state->mode = BAD;
3255*b30d1939SAndy Fiddaman break;
3256*b30d1939SAndy Fiddaman }
3257*b30d1939SAndy Fiddaman #endif
3258*b30d1939SAndy Fiddaman if (state->offset > state->whave + out - left) {
3259*b30d1939SAndy Fiddaman strm->msg = (char *)"invalid distance too far back";
3260*b30d1939SAndy Fiddaman state->mode = BAD;
3261*b30d1939SAndy Fiddaman break;
3262*b30d1939SAndy Fiddaman }
3263*b30d1939SAndy Fiddaman Tracevv((stderr, "inflate: distance %u\n", state->offset));
3264*b30d1939SAndy Fiddaman state->mode = MATCH;
3265*b30d1939SAndy Fiddaman case MATCH:
3266*b30d1939SAndy Fiddaman if (left == 0) goto inf_leave;
3267*b30d1939SAndy Fiddaman copy = out - left;
3268*b30d1939SAndy Fiddaman if (state->offset > copy) { /* copy from window */
3269*b30d1939SAndy Fiddaman copy = state->offset - copy;
3270*b30d1939SAndy Fiddaman if (copy > state->write) {
3271*b30d1939SAndy Fiddaman copy -= state->write;
3272*b30d1939SAndy Fiddaman from = state->window + (state->wsize - copy);
3273*b30d1939SAndy Fiddaman }
3274*b30d1939SAndy Fiddaman else
3275*b30d1939SAndy Fiddaman from = state->window + (state->write - copy);
3276*b30d1939SAndy Fiddaman if (copy > state->length) copy = state->length;
3277*b30d1939SAndy Fiddaman }
3278*b30d1939SAndy Fiddaman else { /* copy from output */
3279*b30d1939SAndy Fiddaman from = put - state->offset;
3280*b30d1939SAndy Fiddaman copy = state->length;
3281*b30d1939SAndy Fiddaman }
3282*b30d1939SAndy Fiddaman if (copy > left) copy = left;
3283*b30d1939SAndy Fiddaman left -= copy;
3284*b30d1939SAndy Fiddaman state->length -= copy;
3285*b30d1939SAndy Fiddaman do {
3286*b30d1939SAndy Fiddaman *put++ = *from++;
3287*b30d1939SAndy Fiddaman } while (--copy);
3288*b30d1939SAndy Fiddaman if (state->length == 0) state->mode = LEN;
3289*b30d1939SAndy Fiddaman break;
3290*b30d1939SAndy Fiddaman case LIT:
3291*b30d1939SAndy Fiddaman if (left == 0) goto inf_leave;
3292*b30d1939SAndy Fiddaman *put++ = (unsigned char)(state->length);
3293*b30d1939SAndy Fiddaman left--;
3294*b30d1939SAndy Fiddaman state->mode = LEN;
3295*b30d1939SAndy Fiddaman break;
3296*b30d1939SAndy Fiddaman case CHECK:
3297*b30d1939SAndy Fiddaman if (state->wrap) {
3298*b30d1939SAndy Fiddaman NEEDBITS(32);
3299*b30d1939SAndy Fiddaman out -= left;
3300*b30d1939SAndy Fiddaman strm->total_out += out;
3301*b30d1939SAndy Fiddaman state->total += out;
3302*b30d1939SAndy Fiddaman if (out)
3303*b30d1939SAndy Fiddaman strm->adler = state->check =
3304*b30d1939SAndy Fiddaman UPDATE(state->check, put - out, out);
3305*b30d1939SAndy Fiddaman out = left;
3306*b30d1939SAndy Fiddaman if ((
3307*b30d1939SAndy Fiddaman #ifdef GUNZIP
3308*b30d1939SAndy Fiddaman state->flags ? hold :
3309*b30d1939SAndy Fiddaman #endif
3310*b30d1939SAndy Fiddaman REVERSE(hold)) != state->check) {
3311*b30d1939SAndy Fiddaman strm->msg = (char *)"incorrect data check";
3312*b30d1939SAndy Fiddaman state->mode = BAD;
3313*b30d1939SAndy Fiddaman break;
3314*b30d1939SAndy Fiddaman }
3315*b30d1939SAndy Fiddaman INITBITS();
3316*b30d1939SAndy Fiddaman Tracev((stderr, "inflate: check matches trailer\n"));
3317*b30d1939SAndy Fiddaman }
3318*b30d1939SAndy Fiddaman #ifdef GUNZIP
3319*b30d1939SAndy Fiddaman state->mode = LENGTH;
3320*b30d1939SAndy Fiddaman case LENGTH:
3321*b30d1939SAndy Fiddaman if (state->wrap && state->flags) {
3322*b30d1939SAndy Fiddaman NEEDBITS(32);
3323*b30d1939SAndy Fiddaman if (hold != (state->total & 0xffffffff)) {
3324*b30d1939SAndy Fiddaman strm->msg = (char *)"incorrect length check";
3325*b30d1939SAndy Fiddaman state->mode = BAD;
3326*b30d1939SAndy Fiddaman break;
3327*b30d1939SAndy Fiddaman }
3328*b30d1939SAndy Fiddaman INITBITS();
3329*b30d1939SAndy Fiddaman Tracev((stderr, "inflate: length matches trailer\n"));
3330*b30d1939SAndy Fiddaman }
3331*b30d1939SAndy Fiddaman #endif
3332*b30d1939SAndy Fiddaman state->mode = DONE;
3333*b30d1939SAndy Fiddaman case DONE:
3334*b30d1939SAndy Fiddaman ret = Z_STREAM_END;
3335*b30d1939SAndy Fiddaman goto inf_leave;
3336*b30d1939SAndy Fiddaman case BAD:
3337*b30d1939SAndy Fiddaman ret = Z_DATA_ERROR;
3338*b30d1939SAndy Fiddaman goto inf_leave;
3339*b30d1939SAndy Fiddaman case MEM:
3340*b30d1939SAndy Fiddaman return Z_MEM_ERROR;
3341*b30d1939SAndy Fiddaman case SYNC:
3342*b30d1939SAndy Fiddaman default:
3343*b30d1939SAndy Fiddaman return Z_STREAM_ERROR;
3344*b30d1939SAndy Fiddaman }
3345*b30d1939SAndy Fiddaman
3346*b30d1939SAndy Fiddaman /*
3347*b30d1939SAndy Fiddaman Return from inflate(), updating the total counts and the check value.
3348*b30d1939SAndy Fiddaman If there was no progress during the inflate() call, return a buffer
3349*b30d1939SAndy Fiddaman error. Call updatewindow() to create and/or update the window state.
3350*b30d1939SAndy Fiddaman Note: a memory error from inflate() is non-recoverable.
3351*b30d1939SAndy Fiddaman */
3352*b30d1939SAndy Fiddaman inf_leave:
3353*b30d1939SAndy Fiddaman RESTORE();
3354*b30d1939SAndy Fiddaman if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
3355*b30d1939SAndy Fiddaman if (updatewindow(strm, out)) {
3356*b30d1939SAndy Fiddaman state->mode = MEM;
3357*b30d1939SAndy Fiddaman return Z_MEM_ERROR;
3358*b30d1939SAndy Fiddaman }
3359*b30d1939SAndy Fiddaman in -= strm->avail_in;
3360*b30d1939SAndy Fiddaman out -= strm->avail_out;
3361*b30d1939SAndy Fiddaman strm->total_in += in;
3362*b30d1939SAndy Fiddaman strm->total_out += out;
3363*b30d1939SAndy Fiddaman state->total += out;
3364*b30d1939SAndy Fiddaman if (state->wrap && out)
3365*b30d1939SAndy Fiddaman strm->adler = state->check =
3366*b30d1939SAndy Fiddaman UPDATE(state->check, strm->next_out - out, out);
3367*b30d1939SAndy Fiddaman strm->data_type = state->bits + (state->last ? 64 : 0) +
3368*b30d1939SAndy Fiddaman (state->mode == TYPE ? 128 : 0);
3369*b30d1939SAndy Fiddaman if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
3370*b30d1939SAndy Fiddaman ret = Z_BUF_ERROR;
3371*b30d1939SAndy Fiddaman return ret;
3372*b30d1939SAndy Fiddaman }
3373*b30d1939SAndy Fiddaman
inflateEnd(strm)3374*b30d1939SAndy Fiddaman int ZEXPORT inflateEnd(strm)
3375*b30d1939SAndy Fiddaman z_streamp strm;
3376*b30d1939SAndy Fiddaman {
3377*b30d1939SAndy Fiddaman struct inflate_state FAR *state;
3378*b30d1939SAndy Fiddaman if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
3379*b30d1939SAndy Fiddaman return Z_STREAM_ERROR;
3380*b30d1939SAndy Fiddaman state = (struct inflate_state FAR *)strm->state;
3381*b30d1939SAndy Fiddaman if (state->window != Z_NULL) ZFREE(strm, state->window);
3382*b30d1939SAndy Fiddaman ZFREE(strm, strm->state);
3383*b30d1939SAndy Fiddaman strm->state = Z_NULL;
3384*b30d1939SAndy Fiddaman Tracev((stderr, "inflate: end\n"));
3385*b30d1939SAndy Fiddaman return Z_OK;
3386*b30d1939SAndy Fiddaman }
3387*b30d1939SAndy Fiddaman
inflateSetDictionary(strm,dictionary,dictLength)3388*b30d1939SAndy Fiddaman int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
3389*b30d1939SAndy Fiddaman z_streamp strm;
3390*b30d1939SAndy Fiddaman const Bytef *dictionary;
3391*b30d1939SAndy Fiddaman uInt dictLength;
3392*b30d1939SAndy Fiddaman {
3393*b30d1939SAndy Fiddaman struct inflate_state FAR *state;
3394*b30d1939SAndy Fiddaman unsigned long id;
3395*b30d1939SAndy Fiddaman
3396*b30d1939SAndy Fiddaman /* check state */
3397*b30d1939SAndy Fiddaman if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
3398*b30d1939SAndy Fiddaman state = (struct inflate_state FAR *)strm->state;
3399*b30d1939SAndy Fiddaman if (state->wrap != 0 && state->mode != DICT)
3400*b30d1939SAndy Fiddaman return Z_STREAM_ERROR;
3401*b30d1939SAndy Fiddaman
3402*b30d1939SAndy Fiddaman /* check for correct dictionary id */
3403*b30d1939SAndy Fiddaman if (state->mode == DICT) {
3404*b30d1939SAndy Fiddaman id = adler32(0L, Z_NULL, 0);
3405*b30d1939SAndy Fiddaman id = adler32(id, dictionary, dictLength);
3406*b30d1939SAndy Fiddaman if (id != state->check)
3407*b30d1939SAndy Fiddaman return Z_DATA_ERROR;
3408*b30d1939SAndy Fiddaman }
3409*b30d1939SAndy Fiddaman
3410*b30d1939SAndy Fiddaman /* copy dictionary to window */
3411*b30d1939SAndy Fiddaman if (updatewindow(strm, strm->avail_out)) {
3412*b30d1939SAndy Fiddaman state->mode = MEM;
3413*b30d1939SAndy Fiddaman return Z_MEM_ERROR;
3414*b30d1939SAndy Fiddaman }
3415*b30d1939SAndy Fiddaman if (dictLength > state->wsize) {
3416*b30d1939SAndy Fiddaman zmemcpy(state->window, dictionary + dictLength - state->wsize,
3417*b30d1939SAndy Fiddaman state->wsize);
3418*b30d1939SAndy Fiddaman state->whave = state->wsize;
3419*b30d1939SAndy Fiddaman }
3420*b30d1939SAndy Fiddaman else {
3421*b30d1939SAndy Fiddaman zmemcpy(state->window + state->wsize - dictLength, dictionary,
3422*b30d1939SAndy Fiddaman dictLength);
3423*b30d1939SAndy Fiddaman state->whave = dictLength;
3424*b30d1939SAndy Fiddaman }
3425*b30d1939SAndy Fiddaman state->havedict = 1;
3426*b30d1939SAndy Fiddaman Tracev((stderr, "inflate: dictionary set\n"));
3427*b30d1939SAndy Fiddaman return Z_OK;
3428*b30d1939SAndy Fiddaman }
3429*b30d1939SAndy Fiddaman
inflateGetHeader(strm,head)3430*b30d1939SAndy Fiddaman int ZEXPORT inflateGetHeader(strm, head)
3431*b30d1939SAndy Fiddaman z_streamp strm;
3432*b30d1939SAndy Fiddaman gz_headerp head;
3433*b30d1939SAndy Fiddaman {
3434*b30d1939SAndy Fiddaman struct inflate_state FAR *state;
3435*b30d1939SAndy Fiddaman
3436*b30d1939SAndy Fiddaman /* check state */
3437*b30d1939SAndy Fiddaman if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
3438*b30d1939SAndy Fiddaman state = (struct inflate_state FAR *)strm->state;
3439*b30d1939SAndy Fiddaman if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
3440*b30d1939SAndy Fiddaman
3441*b30d1939SAndy Fiddaman /* save header structure */
3442*b30d1939SAndy Fiddaman state->head = head;
3443*b30d1939SAndy Fiddaman #ifdef GUNZIP
3444*b30d1939SAndy Fiddaman head->done = 0;
3445*b30d1939SAndy Fiddaman #endif
3446*b30d1939SAndy Fiddaman return Z_OK;
3447*b30d1939SAndy Fiddaman }
3448*b30d1939SAndy Fiddaman
3449*b30d1939SAndy Fiddaman /*
3450*b30d1939SAndy Fiddaman Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found
3451*b30d1939SAndy Fiddaman or when out of input. When called, *have is the number of pattern bytes
3452*b30d1939SAndy Fiddaman found in order so far, in 0..3. On return *have is updated to the new
3453*b30d1939SAndy Fiddaman state. If on return *have equals four, then the pattern was found and the
3454*b30d1939SAndy Fiddaman return value is how many bytes were read including the last byte of the
3455*b30d1939SAndy Fiddaman pattern. If *have is less than four, then the pattern has not been found
3456*b30d1939SAndy Fiddaman yet and the return value is len. In the latter case, syncsearch() can be
3457*b30d1939SAndy Fiddaman called again with more data and the *have state. *have is initialized to
3458*b30d1939SAndy Fiddaman zero for the first call.
3459*b30d1939SAndy Fiddaman */
syncsearch(have,buf,len)3460*b30d1939SAndy Fiddaman local unsigned syncsearch(have, buf, len)
3461*b30d1939SAndy Fiddaman unsigned FAR *have;
3462*b30d1939SAndy Fiddaman unsigned char FAR *buf;
3463*b30d1939SAndy Fiddaman unsigned len;
3464*b30d1939SAndy Fiddaman {
3465*b30d1939SAndy Fiddaman unsigned got;
3466*b30d1939SAndy Fiddaman unsigned next;
3467*b30d1939SAndy Fiddaman
3468*b30d1939SAndy Fiddaman got = *have;
3469*b30d1939SAndy Fiddaman next = 0;
3470*b30d1939SAndy Fiddaman while (next < len && got < 4) {
3471*b30d1939SAndy Fiddaman if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
3472*b30d1939SAndy Fiddaman got++;
3473*b30d1939SAndy Fiddaman else if (buf[next])
3474*b30d1939SAndy Fiddaman got = 0;
3475*b30d1939SAndy Fiddaman else
3476*b30d1939SAndy Fiddaman got = 4 - got;
3477*b30d1939SAndy Fiddaman next++;
3478*b30d1939SAndy Fiddaman }
3479*b30d1939SAndy Fiddaman *have = got;
3480*b30d1939SAndy Fiddaman return next;
3481*b30d1939SAndy Fiddaman }
3482*b30d1939SAndy Fiddaman
inflateSync(strm)3483*b30d1939SAndy Fiddaman int ZEXPORT inflateSync(strm)
3484*b30d1939SAndy Fiddaman z_streamp strm;
3485*b30d1939SAndy Fiddaman {
3486*b30d1939SAndy Fiddaman unsigned len; /* number of bytes to look at or looked at */
3487*b30d1939SAndy Fiddaman unsigned long in, out; /* temporary to save total_in and total_out */
3488*b30d1939SAndy Fiddaman unsigned char buf[4]; /* to restore bit buffer to byte string */
3489*b30d1939SAndy Fiddaman struct inflate_state FAR *state;
3490*b30d1939SAndy Fiddaman
3491*b30d1939SAndy Fiddaman /* check parameters */
3492*b30d1939SAndy Fiddaman if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
3493*b30d1939SAndy Fiddaman state = (struct inflate_state FAR *)strm->state;
3494*b30d1939SAndy Fiddaman if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
3495*b30d1939SAndy Fiddaman
3496*b30d1939SAndy Fiddaman /* if first time, start search in bit buffer */
3497*b30d1939SAndy Fiddaman if (state->mode != SYNC) {
3498*b30d1939SAndy Fiddaman state->mode = SYNC;
3499*b30d1939SAndy Fiddaman state->hold <<= state->bits & 7;
3500*b30d1939SAndy Fiddaman state->bits -= state->bits & 7;
3501*b30d1939SAndy Fiddaman len = 0;
3502*b30d1939SAndy Fiddaman while (state->bits >= 8) {
3503*b30d1939SAndy Fiddaman buf[len++] = (unsigned char)(state->hold);
3504*b30d1939SAndy Fiddaman state->hold >>= 8;
3505*b30d1939SAndy Fiddaman state->bits -= 8;
3506*b30d1939SAndy Fiddaman }
3507*b30d1939SAndy Fiddaman state->have = 0;
3508*b30d1939SAndy Fiddaman syncsearch(&(state->have), buf, len);
3509*b30d1939SAndy Fiddaman }
3510*b30d1939SAndy Fiddaman
3511*b30d1939SAndy Fiddaman /* search available input */
3512*b30d1939SAndy Fiddaman len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
3513*b30d1939SAndy Fiddaman strm->avail_in -= len;
3514*b30d1939SAndy Fiddaman strm->next_in += len;
3515*b30d1939SAndy Fiddaman strm->total_in += len;
3516*b30d1939SAndy Fiddaman
3517*b30d1939SAndy Fiddaman /* return no joy or set up to restart inflate() on a new block */
3518*b30d1939SAndy Fiddaman if (state->have != 4) return Z_DATA_ERROR;
3519*b30d1939SAndy Fiddaman in = strm->total_in; out = strm->total_out;
3520*b30d1939SAndy Fiddaman inflateReset(strm);
3521*b30d1939SAndy Fiddaman strm->total_in = in; strm->total_out = out;
3522*b30d1939SAndy Fiddaman state->mode = TYPE;
3523*b30d1939SAndy Fiddaman return Z_OK;
3524*b30d1939SAndy Fiddaman }
3525*b30d1939SAndy Fiddaman
3526*b30d1939SAndy Fiddaman /*
3527*b30d1939SAndy Fiddaman Returns true if inflate is currently at the end of a block generated by
3528*b30d1939SAndy Fiddaman Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
3529*b30d1939SAndy Fiddaman implementation to provide an additional safety check. PPP uses
3530*b30d1939SAndy Fiddaman Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
3531*b30d1939SAndy Fiddaman block. When decompressing, PPP checks that at the end of input packet,
3532*b30d1939SAndy Fiddaman inflate is waiting for these length bytes.
3533*b30d1939SAndy Fiddaman */
inflateSyncPoint(strm)3534*b30d1939SAndy Fiddaman int ZEXPORT inflateSyncPoint(strm)
3535*b30d1939SAndy Fiddaman z_streamp strm;
3536*b30d1939SAndy Fiddaman {
3537*b30d1939SAndy Fiddaman struct inflate_state FAR *state;
3538*b30d1939SAndy Fiddaman
3539*b30d1939SAndy Fiddaman if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
3540*b30d1939SAndy Fiddaman state = (struct inflate_state FAR *)strm->state;
3541*b30d1939SAndy Fiddaman return state->mode == STORED && state->bits == 0;
3542*b30d1939SAndy Fiddaman }
3543*b30d1939SAndy Fiddaman
inflateCopy(dest,source)3544*b30d1939SAndy Fiddaman int ZEXPORT inflateCopy(dest, source)
3545*b30d1939SAndy Fiddaman z_streamp dest;
3546*b30d1939SAndy Fiddaman z_streamp source;
3547*b30d1939SAndy Fiddaman {
3548*b30d1939SAndy Fiddaman struct inflate_state FAR *state;
3549*b30d1939SAndy Fiddaman struct inflate_state FAR *copy;
3550*b30d1939SAndy Fiddaman unsigned char FAR *window;
3551*b30d1939SAndy Fiddaman unsigned wsize;
3552*b30d1939SAndy Fiddaman
3553*b30d1939SAndy Fiddaman /* check input */
3554*b30d1939SAndy Fiddaman if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
3555*b30d1939SAndy Fiddaman source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
3556*b30d1939SAndy Fiddaman return Z_STREAM_ERROR;
3557*b30d1939SAndy Fiddaman state = (struct inflate_state FAR *)source->state;
3558*b30d1939SAndy Fiddaman
3559*b30d1939SAndy Fiddaman /* allocate space */
3560*b30d1939SAndy Fiddaman copy = (struct inflate_state FAR *)
3561*b30d1939SAndy Fiddaman ZALLOC(source, 1, sizeof(struct inflate_state));
3562*b30d1939SAndy Fiddaman if (copy == Z_NULL) return Z_MEM_ERROR;
3563*b30d1939SAndy Fiddaman window = Z_NULL;
3564*b30d1939SAndy Fiddaman if (state->window != Z_NULL) {
3565*b30d1939SAndy Fiddaman window = (unsigned char FAR *)
3566*b30d1939SAndy Fiddaman ZALLOC(source, ((unsigned int)1) << state->wbits, sizeof(unsigned char));
3567*b30d1939SAndy Fiddaman if (window == Z_NULL) {
3568*b30d1939SAndy Fiddaman ZFREE(source, copy);
3569*b30d1939SAndy Fiddaman return Z_MEM_ERROR;
3570*b30d1939SAndy Fiddaman }
3571*b30d1939SAndy Fiddaman }
3572*b30d1939SAndy Fiddaman
3573*b30d1939SAndy Fiddaman /* copy state */
3574*b30d1939SAndy Fiddaman zmemcpy(dest, source, sizeof(z_stream));
3575*b30d1939SAndy Fiddaman zmemcpy(copy, state, sizeof(struct inflate_state));
3576*b30d1939SAndy Fiddaman if (state->lencode >= state->codes &&
3577*b30d1939SAndy Fiddaman state->lencode <= state->codes + ENOUGH - 1) {
3578*b30d1939SAndy Fiddaman copy->lencode = copy->codes + (state->lencode - state->codes);
3579*b30d1939SAndy Fiddaman copy->distcode = copy->codes + (state->distcode - state->codes);
3580*b30d1939SAndy Fiddaman }
3581*b30d1939SAndy Fiddaman copy->next = copy->codes + (state->next - state->codes);
3582*b30d1939SAndy Fiddaman if (window != Z_NULL) {
3583*b30d1939SAndy Fiddaman wsize = ((unsigned int)1) << state->wbits;
3584*b30d1939SAndy Fiddaman zmemcpy(window, state->window, wsize);
3585*b30d1939SAndy Fiddaman }
3586*b30d1939SAndy Fiddaman copy->window = window;
3587*b30d1939SAndy Fiddaman dest->state = (struct internal_state FAR *)copy;
3588*b30d1939SAndy Fiddaman return Z_OK;
3589*b30d1939SAndy Fiddaman }
3590*b30d1939SAndy Fiddaman
3591*b30d1939SAndy Fiddaman #endif /* _INFLATE_C */
3592*b30d1939SAndy Fiddaman
3593*b30d1939SAndy Fiddaman #ifndef _GZIO_C
3594*b30d1939SAndy Fiddaman #define _GZIO_C 1
3595*b30d1939SAndy Fiddaman
3596*b30d1939SAndy Fiddaman typedef voidp gzFile;
3597*b30d1939SAndy Fiddaman
3598*b30d1939SAndy Fiddaman #ifndef Z_BUFSIZE
3599*b30d1939SAndy Fiddaman # ifdef MAXSEG_64K
3600*b30d1939SAndy Fiddaman # define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
3601*b30d1939SAndy Fiddaman # else
3602*b30d1939SAndy Fiddaman # define Z_BUFSIZE 16384
3603*b30d1939SAndy Fiddaman # endif
3604*b30d1939SAndy Fiddaman #endif
3605*b30d1939SAndy Fiddaman #ifndef Z_PRINTF_BUFSIZE
3606*b30d1939SAndy Fiddaman # define Z_PRINTF_BUFSIZE 4096
3607*b30d1939SAndy Fiddaman #endif
3608*b30d1939SAndy Fiddaman
3609*b30d1939SAndy Fiddaman #ifdef __MVS__
3610*b30d1939SAndy Fiddaman # pragma map (fdopen , "\174\174FDOPEN")
3611*b30d1939SAndy Fiddaman FILE *fdopen(int, const char *);
3612*b30d1939SAndy Fiddaman #endif
3613*b30d1939SAndy Fiddaman
3614*b30d1939SAndy Fiddaman #if 0 && !_PACKAGE_ast
3615*b30d1939SAndy Fiddaman #ifndef STDC
3616*b30d1939SAndy Fiddaman extern voidp malloc OF((uInt size));
3617*b30d1939SAndy Fiddaman extern void free OF((voidpf ptr));
3618*b30d1939SAndy Fiddaman #endif
3619*b30d1939SAndy Fiddaman #endif
3620*b30d1939SAndy Fiddaman
3621*b30d1939SAndy Fiddaman #define ALLOC(size) malloc(size)
3622*b30d1939SAndy Fiddaman #define TRYFREE(p) {if (p) free(p);}
3623*b30d1939SAndy Fiddaman
3624*b30d1939SAndy Fiddaman static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
3625*b30d1939SAndy Fiddaman
3626*b30d1939SAndy Fiddaman /* gzip flag byte */
3627*b30d1939SAndy Fiddaman #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
3628*b30d1939SAndy Fiddaman #define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
3629*b30d1939SAndy Fiddaman #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
3630*b30d1939SAndy Fiddaman #define ORIG_NAME 0x08 /* bit 3 set: original file name present */
3631*b30d1939SAndy Fiddaman #define COMMENT 0x10 /* bit 4 set: file comment present */
3632*b30d1939SAndy Fiddaman #define RESERVED 0xE0 /* bits 5..7: reserved */
3633*b30d1939SAndy Fiddaman
3634*b30d1939SAndy Fiddaman typedef struct gz_stream {
3635*b30d1939SAndy Fiddaman z_stream stream;
3636*b30d1939SAndy Fiddaman int z_err; /* error code for last stream operation */
3637*b30d1939SAndy Fiddaman int z_eof; /* set if end of input file */
3638*b30d1939SAndy Fiddaman FILE *file; /* .gz file */
3639*b30d1939SAndy Fiddaman Byte *inbuf; /* input buffer */
3640*b30d1939SAndy Fiddaman Byte *outbuf; /* output buffer */
3641*b30d1939SAndy Fiddaman uLong crc; /* crc32 of uncompressed data */
3642*b30d1939SAndy Fiddaman char *msg; /* error message */
3643*b30d1939SAndy Fiddaman char *path; /* path name for debugging only */
3644*b30d1939SAndy Fiddaman int transparent; /* 1 if input file is not a .gz file */
3645*b30d1939SAndy Fiddaman #if _PACKAGE_ast
3646*b30d1939SAndy Fiddaman int fatal; /* fatal stream error => all other ops fail */
3647*b30d1939SAndy Fiddaman int nocrc; /* 1 to skip 'r' crc checks */
3648*b30d1939SAndy Fiddaman int noclose; /* 1 to skip destroy fclose */
3649*b30d1939SAndy Fiddaman int verified;/* 2-byte magic read and verified ('v') */
3650*b30d1939SAndy Fiddaman #endif
3651*b30d1939SAndy Fiddaman char mode; /* 'w' or 'r' */
3652*b30d1939SAndy Fiddaman z_off_t start; /* start of compressed data in file (header skipped) */
3653*b30d1939SAndy Fiddaman z_off_t in; /* bytes into deflate or inflate */
3654*b30d1939SAndy Fiddaman z_off_t out; /* bytes out of deflate or inflate */
3655*b30d1939SAndy Fiddaman int back; /* one character push-back */
3656*b30d1939SAndy Fiddaman int last; /* true if push-back is last character */
3657*b30d1939SAndy Fiddaman } gz_stream;
3658*b30d1939SAndy Fiddaman
3659*b30d1939SAndy Fiddaman
3660*b30d1939SAndy Fiddaman local gzFile gz_open OF((const char *path, const char *mode, FILE* fp));
3661*b30d1939SAndy Fiddaman local int get_byte OF((gz_stream *s));
3662*b30d1939SAndy Fiddaman local void check_header OF((gz_stream *s));
3663*b30d1939SAndy Fiddaman local int destroy OF((gz_stream *s));
3664*b30d1939SAndy Fiddaman local uLong getLong OF((gz_stream *s));
3665*b30d1939SAndy Fiddaman
3666*b30d1939SAndy Fiddaman /* ===========================================================================
3667*b30d1939SAndy Fiddaman Opens a gzip (.gz) file for reading or writing. The mode parameter
3668*b30d1939SAndy Fiddaman is as in fopen ("rb" or "wb"). The file is given either by FILE pointer
3669*b30d1939SAndy Fiddaman or path name (if fp == 0).
3670*b30d1939SAndy Fiddaman gz_open returns NULL if the file could not be opened or if there was
3671*b30d1939SAndy Fiddaman insufficient memory to allocate the (de)compression state; errno
3672*b30d1939SAndy Fiddaman can be checked to distinguish the two cases (if errno is zero, the
3673*b30d1939SAndy Fiddaman zlib error is Z_MEM_ERROR).
3674*b30d1939SAndy Fiddaman */
gz_open(path,mode,fp)3675*b30d1939SAndy Fiddaman local gzFile gz_open (path, mode, fp)
3676*b30d1939SAndy Fiddaman const char *path;
3677*b30d1939SAndy Fiddaman const char *mode;
3678*b30d1939SAndy Fiddaman FILE *fp;
3679*b30d1939SAndy Fiddaman {
3680*b30d1939SAndy Fiddaman int err;
3681*b30d1939SAndy Fiddaman int level = Z_DEFAULT_COMPRESSION; /* compression level */
3682*b30d1939SAndy Fiddaman int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
3683*b30d1939SAndy Fiddaman char *p = (char*)mode;
3684*b30d1939SAndy Fiddaman gz_stream *s;
3685*b30d1939SAndy Fiddaman char fmode[80]; /* copy of mode, without the compression level */
3686*b30d1939SAndy Fiddaman char *m = fmode;
3687*b30d1939SAndy Fiddaman
3688*b30d1939SAndy Fiddaman if (!path || !mode) return Z_NULL;
3689*b30d1939SAndy Fiddaman
3690*b30d1939SAndy Fiddaman s = (gz_stream *)ALLOC(sizeof(gz_stream));
3691*b30d1939SAndy Fiddaman if (!s) return Z_NULL;
3692*b30d1939SAndy Fiddaman
3693*b30d1939SAndy Fiddaman s->stream.zalloc = (alloc_func)0;
3694*b30d1939SAndy Fiddaman s->stream.zfree = (free_func)0;
3695*b30d1939SAndy Fiddaman s->stream.opaque = (voidpf)0;
3696*b30d1939SAndy Fiddaman s->stream.next_in = s->inbuf = Z_NULL;
3697*b30d1939SAndy Fiddaman s->stream.next_out = s->outbuf = Z_NULL;
3698*b30d1939SAndy Fiddaman s->stream.avail_in = s->stream.avail_out = 0;
3699*b30d1939SAndy Fiddaman s->file = NULL;
3700*b30d1939SAndy Fiddaman s->z_err = Z_OK;
3701*b30d1939SAndy Fiddaman s->z_eof = 0;
3702*b30d1939SAndy Fiddaman s->in = 0;
3703*b30d1939SAndy Fiddaman s->out = 0;
3704*b30d1939SAndy Fiddaman s->back = EOF;
3705*b30d1939SAndy Fiddaman s->crc = crc32(0L, Z_NULL, 0);
3706*b30d1939SAndy Fiddaman #if _PACKAGE_ast
3707*b30d1939SAndy Fiddaman s->fatal = 0;
3708*b30d1939SAndy Fiddaman s->nocrc = 0;
3709*b30d1939SAndy Fiddaman s->verified = 0;
3710*b30d1939SAndy Fiddaman #endif
3711*b30d1939SAndy Fiddaman s->msg = NULL;
3712*b30d1939SAndy Fiddaman s->transparent = 0;
3713*b30d1939SAndy Fiddaman
3714*b30d1939SAndy Fiddaman s->path = (char*)ALLOC(strlen(path)+1);
3715*b30d1939SAndy Fiddaman if (s->path == NULL) {
3716*b30d1939SAndy Fiddaman return destroy(s), (gzFile)Z_NULL;
3717*b30d1939SAndy Fiddaman }
3718*b30d1939SAndy Fiddaman strcpy(s->path, path); /* do this early for debugging */
3719*b30d1939SAndy Fiddaman
3720*b30d1939SAndy Fiddaman s->mode = '\0';
3721*b30d1939SAndy Fiddaman do {
3722*b30d1939SAndy Fiddaman if (*p == 'r') s->mode = 'r';
3723*b30d1939SAndy Fiddaman if (*p == 'w' || *p == 'a') s->mode = 'w';
3724*b30d1939SAndy Fiddaman if (*p >= '0' && *p <= '9') {
3725*b30d1939SAndy Fiddaman level = *p - '0';
3726*b30d1939SAndy Fiddaman } else if (*p == 'f') {
3727*b30d1939SAndy Fiddaman strategy = Z_FILTERED;
3728*b30d1939SAndy Fiddaman } else if (*p == 'h') {
3729*b30d1939SAndy Fiddaman strategy = Z_HUFFMAN_ONLY;
3730*b30d1939SAndy Fiddaman } else if (*p == 'R') {
3731*b30d1939SAndy Fiddaman strategy = Z_RLE;
3732*b30d1939SAndy Fiddaman #if _PACKAGE_ast
3733*b30d1939SAndy Fiddaman } else if (*p == 'n') {
3734*b30d1939SAndy Fiddaman s->nocrc = 1;
3735*b30d1939SAndy Fiddaman } else if (*p == 'o') {
3736*b30d1939SAndy Fiddaman s->noclose = 1;
3737*b30d1939SAndy Fiddaman } else if (*p == 'v') {
3738*b30d1939SAndy Fiddaman s->verified = 1;
3739*b30d1939SAndy Fiddaman #endif
3740*b30d1939SAndy Fiddaman } else {
3741*b30d1939SAndy Fiddaman *m++ = *p; /* copy the mode */
3742*b30d1939SAndy Fiddaman }
3743*b30d1939SAndy Fiddaman } while (*p++ && m != fmode + sizeof(fmode));
3744*b30d1939SAndy Fiddaman if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
3745*b30d1939SAndy Fiddaman
3746*b30d1939SAndy Fiddaman if (s->mode == 'w') {
3747*b30d1939SAndy Fiddaman #ifdef NO_GZCOMPRESS
3748*b30d1939SAndy Fiddaman err = Z_STREAM_ERROR;
3749*b30d1939SAndy Fiddaman #else
3750*b30d1939SAndy Fiddaman #if _PACKAGE_ast
3751*b30d1939SAndy Fiddaman s->nocrc = 0;
3752*b30d1939SAndy Fiddaman #endif
3753*b30d1939SAndy Fiddaman err = deflateInit2(&(s->stream), level,
3754*b30d1939SAndy Fiddaman Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
3755*b30d1939SAndy Fiddaman /* windowBits is passed < 0 to suppress zlib header */
3756*b30d1939SAndy Fiddaman
3757*b30d1939SAndy Fiddaman s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
3758*b30d1939SAndy Fiddaman #endif
3759*b30d1939SAndy Fiddaman if (err != Z_OK || s->outbuf == Z_NULL) {
3760*b30d1939SAndy Fiddaman return destroy(s), (gzFile)Z_NULL;
3761*b30d1939SAndy Fiddaman }
3762*b30d1939SAndy Fiddaman } else {
3763*b30d1939SAndy Fiddaman s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
3764*b30d1939SAndy Fiddaman
3765*b30d1939SAndy Fiddaman err = inflateInit2(&(s->stream), -MAX_WBITS);
3766*b30d1939SAndy Fiddaman /* windowBits is passed < 0 to tell that there is no zlib header.
3767*b30d1939SAndy Fiddaman * Note that in this case inflate *requires* an extra "dummy" byte
3768*b30d1939SAndy Fiddaman * after the compressed stream in order to complete decompression and
3769*b30d1939SAndy Fiddaman * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
3770*b30d1939SAndy Fiddaman * present after the compressed stream.
3771*b30d1939SAndy Fiddaman */
3772*b30d1939SAndy Fiddaman if (err != Z_OK || s->inbuf == Z_NULL) {
3773*b30d1939SAndy Fiddaman return destroy(s), (gzFile)Z_NULL;
3774*b30d1939SAndy Fiddaman }
3775*b30d1939SAndy Fiddaman }
3776*b30d1939SAndy Fiddaman s->stream.avail_out = Z_BUFSIZE;
3777*b30d1939SAndy Fiddaman
3778*b30d1939SAndy Fiddaman errno = 0;
3779*b30d1939SAndy Fiddaman
3780*b30d1939SAndy Fiddaman if (!(s->file = fp) && !(s->file = F_OPEN(path, fmode))) {
3781*b30d1939SAndy Fiddaman return destroy(s), (gzFile)Z_NULL;
3782*b30d1939SAndy Fiddaman }
3783*b30d1939SAndy Fiddaman if (s->mode == 'w') {
3784*b30d1939SAndy Fiddaman /* Write a very simple .gz header:
3785*b30d1939SAndy Fiddaman */
3786*b30d1939SAndy Fiddaman fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
3787*b30d1939SAndy Fiddaman Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
3788*b30d1939SAndy Fiddaman s->start = 10L;
3789*b30d1939SAndy Fiddaman /* We use 10L instead of ftell(s->file) to because ftell causes an
3790*b30d1939SAndy Fiddaman * fflush on some systems. This version of the library doesn't use
3791*b30d1939SAndy Fiddaman * start anyway in write mode, so this initialization is not
3792*b30d1939SAndy Fiddaman * necessary.
3793*b30d1939SAndy Fiddaman */
3794*b30d1939SAndy Fiddaman } else {
3795*b30d1939SAndy Fiddaman #if _PACKAGE_ast
3796*b30d1939SAndy Fiddaman sfsetbuf(s->file, (void*)s->file, SF_UNBOUND);
3797*b30d1939SAndy Fiddaman #endif
3798*b30d1939SAndy Fiddaman check_header(s); /* skip the .gz header */
3799*b30d1939SAndy Fiddaman s->start = (z_off_t)(ftell(s->file) - s->stream.avail_in);
3800*b30d1939SAndy Fiddaman }
3801*b30d1939SAndy Fiddaman
3802*b30d1939SAndy Fiddaman return (gzFile)s;
3803*b30d1939SAndy Fiddaman }
3804*b30d1939SAndy Fiddaman
3805*b30d1939SAndy Fiddaman /* ===========================================================================
3806*b30d1939SAndy Fiddaman Associate a gzFile with the stdio stream fp.
3807*b30d1939SAndy Fiddaman */
gzfopen(fp,mode)3808*b30d1939SAndy Fiddaman gzFile ZEXPORT gzfopen (fp, mode)
3809*b30d1939SAndy Fiddaman FILE* fp;
3810*b30d1939SAndy Fiddaman const char *mode;
3811*b30d1939SAndy Fiddaman {
3812*b30d1939SAndy Fiddaman FILE* sp = (FILE*)fp;
3813*b30d1939SAndy Fiddaman char name[20];
3814*b30d1939SAndy Fiddaman
3815*b30d1939SAndy Fiddaman if (!sp)
3816*b30d1939SAndy Fiddaman return (gzFile)Z_NULL;
3817*b30d1939SAndy Fiddaman sprintf(name, "<fd:%d>", fileno(sp)); /* for debugging */
3818*b30d1939SAndy Fiddaman
3819*b30d1939SAndy Fiddaman return gz_open (name, mode, sp);
3820*b30d1939SAndy Fiddaman }
3821*b30d1939SAndy Fiddaman
3822*b30d1939SAndy Fiddaman /* ===========================================================================
3823*b30d1939SAndy Fiddaman Read a byte from a gz_stream; update next_in and avail_in. Return EOF
3824*b30d1939SAndy Fiddaman for end of file.
3825*b30d1939SAndy Fiddaman IN assertion: the stream s has been sucessfully opened for reading.
3826*b30d1939SAndy Fiddaman */
get_byte(s)3827*b30d1939SAndy Fiddaman local int get_byte(s)
3828*b30d1939SAndy Fiddaman gz_stream *s;
3829*b30d1939SAndy Fiddaman {
3830*b30d1939SAndy Fiddaman if (s->z_eof) return EOF;
3831*b30d1939SAndy Fiddaman if (s->stream.avail_in == 0) {
3832*b30d1939SAndy Fiddaman errno = 0;
3833*b30d1939SAndy Fiddaman s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
3834*b30d1939SAndy Fiddaman if (s->stream.avail_in == 0) {
3835*b30d1939SAndy Fiddaman s->z_eof = 1;
3836*b30d1939SAndy Fiddaman if (ferror(s->file)) s->z_err = Z_ERRNO;
3837*b30d1939SAndy Fiddaman return EOF;
3838*b30d1939SAndy Fiddaman }
3839*b30d1939SAndy Fiddaman s->stream.next_in = s->inbuf;
3840*b30d1939SAndy Fiddaman }
3841*b30d1939SAndy Fiddaman s->stream.avail_in--;
3842*b30d1939SAndy Fiddaman return *(s->stream.next_in)++;
3843*b30d1939SAndy Fiddaman }
3844*b30d1939SAndy Fiddaman
3845*b30d1939SAndy Fiddaman /* ===========================================================================
3846*b30d1939SAndy Fiddaman Check the gzip header of a gz_stream opened for reading. Set the stream
3847*b30d1939SAndy Fiddaman mode to transparent if the gzip magic header is not present; set s->err
3848*b30d1939SAndy Fiddaman to Z_DATA_ERROR if the magic header is present but the rest of the header
3849*b30d1939SAndy Fiddaman is incorrect.
3850*b30d1939SAndy Fiddaman IN assertion: the stream s has already been created sucessfully;
3851*b30d1939SAndy Fiddaman s->stream.avail_in is zero for the first time, but may be non-zero
3852*b30d1939SAndy Fiddaman for concatenated .gz files.
3853*b30d1939SAndy Fiddaman */
check_header(s)3854*b30d1939SAndy Fiddaman local void check_header(s)
3855*b30d1939SAndy Fiddaman gz_stream *s;
3856*b30d1939SAndy Fiddaman {
3857*b30d1939SAndy Fiddaman int method; /* method byte */
3858*b30d1939SAndy Fiddaman int flags; /* flags byte */
3859*b30d1939SAndy Fiddaman uInt len;
3860*b30d1939SAndy Fiddaman int c;
3861*b30d1939SAndy Fiddaman
3862*b30d1939SAndy Fiddaman #if _PACKAGE_ast
3863*b30d1939SAndy Fiddaman if (!s->verified)
3864*b30d1939SAndy Fiddaman for (len = 0; len < 2; len++) {
3865*b30d1939SAndy Fiddaman c = get_byte(s);
3866*b30d1939SAndy Fiddaman if (c != gz_magic[len]) {
3867*b30d1939SAndy Fiddaman if (len != 0) s->stream.avail_in++, s->stream.next_in--;
3868*b30d1939SAndy Fiddaman if (c != EOF) {
3869*b30d1939SAndy Fiddaman s->stream.avail_in++, s->stream.next_in--;
3870*b30d1939SAndy Fiddaman s->transparent = 1;
3871*b30d1939SAndy Fiddaman }
3872*b30d1939SAndy Fiddaman s->z_err = s->stream.avail_in != 0 ? Z_OK : Z_STREAM_END;
3873*b30d1939SAndy Fiddaman return;
3874*b30d1939SAndy Fiddaman }
3875*b30d1939SAndy Fiddaman }
3876*b30d1939SAndy Fiddaman #else
3877*b30d1939SAndy Fiddaman /* Assure two bytes in the buffer so we can peek ahead -- handle case
3878*b30d1939SAndy Fiddaman where first byte of header is at the end of the buffer after the last
3879*b30d1939SAndy Fiddaman gzip segment */
3880*b30d1939SAndy Fiddaman len = s->stream.avail_in;
3881*b30d1939SAndy Fiddaman if (len < 2) {
3882*b30d1939SAndy Fiddaman if (len) s->inbuf[0] = s->stream.next_in[0];
3883*b30d1939SAndy Fiddaman errno = 0;
3884*b30d1939SAndy Fiddaman len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file);
3885*b30d1939SAndy Fiddaman if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO;
3886*b30d1939SAndy Fiddaman s->stream.avail_in += len;
3887*b30d1939SAndy Fiddaman s->stream.next_in = s->inbuf;
3888*b30d1939SAndy Fiddaman if (s->stream.avail_in < 2) {
3889*b30d1939SAndy Fiddaman s->transparent = s->stream.avail_in;
3890*b30d1939SAndy Fiddaman return;
3891*b30d1939SAndy Fiddaman }
3892*b30d1939SAndy Fiddaman }
3893*b30d1939SAndy Fiddaman
3894*b30d1939SAndy Fiddaman /* Peek ahead to check the gzip magic header */
3895*b30d1939SAndy Fiddaman if (s->stream.next_in[0] != gz_magic[0] ||
3896*b30d1939SAndy Fiddaman s->stream.next_in[1] != gz_magic[1]) {
3897*b30d1939SAndy Fiddaman s->transparent = 1;
3898*b30d1939SAndy Fiddaman return;
3899*b30d1939SAndy Fiddaman }
3900*b30d1939SAndy Fiddaman s->stream.avail_in -= 2;
3901*b30d1939SAndy Fiddaman s->stream.next_in += 2;
3902*b30d1939SAndy Fiddaman #endif
3903*b30d1939SAndy Fiddaman
3904*b30d1939SAndy Fiddaman /* Check the rest of the gzip header */
3905*b30d1939SAndy Fiddaman method = get_byte(s);
3906*b30d1939SAndy Fiddaman flags = get_byte(s);
3907*b30d1939SAndy Fiddaman if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
3908*b30d1939SAndy Fiddaman s->z_err = Z_DATA_ERROR;
3909*b30d1939SAndy Fiddaman return;
3910*b30d1939SAndy Fiddaman }
3911*b30d1939SAndy Fiddaman
3912*b30d1939SAndy Fiddaman /* Discard time, xflags and OS code: */
3913*b30d1939SAndy Fiddaman for (len = 0; len < 6; len++) (void)get_byte(s);
3914*b30d1939SAndy Fiddaman
3915*b30d1939SAndy Fiddaman if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
3916*b30d1939SAndy Fiddaman len = (uInt)get_byte(s);
3917*b30d1939SAndy Fiddaman len += ((uInt)get_byte(s))<<8;
3918*b30d1939SAndy Fiddaman /* len is garbage if EOF but the loop below will quit anyway */
3919*b30d1939SAndy Fiddaman while (len-- != 0 && get_byte(s) != EOF) ;
3920*b30d1939SAndy Fiddaman }
3921*b30d1939SAndy Fiddaman if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
3922*b30d1939SAndy Fiddaman while ((c = get_byte(s)) != 0 && c != EOF) ;
3923*b30d1939SAndy Fiddaman }
3924*b30d1939SAndy Fiddaman if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
3925*b30d1939SAndy Fiddaman while ((c = get_byte(s)) != 0 && c != EOF) ;
3926*b30d1939SAndy Fiddaman }
3927*b30d1939SAndy Fiddaman if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
3928*b30d1939SAndy Fiddaman for (len = 0; len < 2; len++) (void)get_byte(s);
3929*b30d1939SAndy Fiddaman }
3930*b30d1939SAndy Fiddaman s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
3931*b30d1939SAndy Fiddaman }
3932*b30d1939SAndy Fiddaman
3933*b30d1939SAndy Fiddaman /* ===========================================================================
3934*b30d1939SAndy Fiddaman * Cleanup then free the given gz_stream. Return a zlib error code.
3935*b30d1939SAndy Fiddaman Try freeing in the reverse order of allocations.
3936*b30d1939SAndy Fiddaman */
destroy(s)3937*b30d1939SAndy Fiddaman local int destroy (s)
3938*b30d1939SAndy Fiddaman gz_stream *s;
3939*b30d1939SAndy Fiddaman {
3940*b30d1939SAndy Fiddaman int err = Z_OK;
3941*b30d1939SAndy Fiddaman
3942*b30d1939SAndy Fiddaman if (!s) return Z_STREAM_ERROR;
3943*b30d1939SAndy Fiddaman
3944*b30d1939SAndy Fiddaman TRYFREE(s->msg);
3945*b30d1939SAndy Fiddaman
3946*b30d1939SAndy Fiddaman if (s->stream.state != NULL) {
3947*b30d1939SAndy Fiddaman if (s->mode == 'w') {
3948*b30d1939SAndy Fiddaman #ifdef NO_GZCOMPRESS
3949*b30d1939SAndy Fiddaman err = Z_STREAM_ERROR;
3950*b30d1939SAndy Fiddaman #else
3951*b30d1939SAndy Fiddaman err = deflateEnd(&(s->stream));
3952*b30d1939SAndy Fiddaman #endif
3953*b30d1939SAndy Fiddaman } else if (s->mode == 'r') {
3954*b30d1939SAndy Fiddaman err = inflateEnd(&(s->stream));
3955*b30d1939SAndy Fiddaman }
3956*b30d1939SAndy Fiddaman }
3957*b30d1939SAndy Fiddaman #if _PACKAGE_ast
3958*b30d1939SAndy Fiddaman if (s->file != NULL && (s->noclose ? (s->mode == 'r' ? 0 : fflush(s->file)) : fclose(s->file))) {
3959*b30d1939SAndy Fiddaman #else
3960*b30d1939SAndy Fiddaman if (s->file != NULL && fclose(s->file)) {
3961*b30d1939SAndy Fiddaman #endif
3962*b30d1939SAndy Fiddaman #ifdef ESPIPE
3963*b30d1939SAndy Fiddaman if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
3964*b30d1939SAndy Fiddaman #endif
3965*b30d1939SAndy Fiddaman err = Z_ERRNO;
3966*b30d1939SAndy Fiddaman }
3967*b30d1939SAndy Fiddaman if (s->z_err < 0) err = s->z_err;
3968*b30d1939SAndy Fiddaman
3969*b30d1939SAndy Fiddaman TRYFREE(s->inbuf);
3970*b30d1939SAndy Fiddaman TRYFREE(s->outbuf);
3971*b30d1939SAndy Fiddaman TRYFREE(s->path);
3972*b30d1939SAndy Fiddaman TRYFREE(s);
3973*b30d1939SAndy Fiddaman return err;
3974*b30d1939SAndy Fiddaman }
3975*b30d1939SAndy Fiddaman
3976*b30d1939SAndy Fiddaman /* ===========================================================================
3977*b30d1939SAndy Fiddaman Reads the given number of uncompressed bytes from the compressed file.
3978*b30d1939SAndy Fiddaman gzread returns the number of bytes actually read (0 for end of file).
3979*b30d1939SAndy Fiddaman */
gzread(file,buf,len)3980*b30d1939SAndy Fiddaman int ZEXPORT gzread (file, buf, len)
3981*b30d1939SAndy Fiddaman gzFile file;
3982*b30d1939SAndy Fiddaman voidp buf;
3983*b30d1939SAndy Fiddaman unsigned len;
3984*b30d1939SAndy Fiddaman {
3985*b30d1939SAndy Fiddaman gz_stream *s = (gz_stream*)file;
3986*b30d1939SAndy Fiddaman Bytef *start = (Bytef*)buf; /* starting point for crc computation */
3987*b30d1939SAndy Fiddaman Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */
3988*b30d1939SAndy Fiddaman
3989*b30d1939SAndy Fiddaman if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
3990*b30d1939SAndy Fiddaman
3991*b30d1939SAndy Fiddaman if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
3992*b30d1939SAndy Fiddaman if (s->z_err == Z_STREAM_END) return 0; /* EOF */
3993*b30d1939SAndy Fiddaman
3994*b30d1939SAndy Fiddaman next_out = (Byte*)buf;
3995*b30d1939SAndy Fiddaman s->stream.next_out = (Bytef*)buf;
3996*b30d1939SAndy Fiddaman s->stream.avail_out = len;
3997*b30d1939SAndy Fiddaman
3998*b30d1939SAndy Fiddaman if (s->stream.avail_out && s->back != EOF) {
3999*b30d1939SAndy Fiddaman *next_out++ = s->back;
4000*b30d1939SAndy Fiddaman s->stream.next_out++;
4001*b30d1939SAndy Fiddaman s->stream.avail_out--;
4002*b30d1939SAndy Fiddaman s->back = EOF;
4003*b30d1939SAndy Fiddaman s->out++;
4004*b30d1939SAndy Fiddaman start++;
4005*b30d1939SAndy Fiddaman if (s->last) {
4006*b30d1939SAndy Fiddaman s->z_err = Z_STREAM_END;
4007*b30d1939SAndy Fiddaman return 1;
4008*b30d1939SAndy Fiddaman }
4009*b30d1939SAndy Fiddaman }
4010*b30d1939SAndy Fiddaman
4011*b30d1939SAndy Fiddaman while (s->stream.avail_out != 0) {
4012*b30d1939SAndy Fiddaman
4013*b30d1939SAndy Fiddaman if (s->transparent) {
4014*b30d1939SAndy Fiddaman /* Copy first the lookahead bytes: */
4015*b30d1939SAndy Fiddaman uInt n = s->stream.avail_in;
4016*b30d1939SAndy Fiddaman if (n > s->stream.avail_out) n = s->stream.avail_out;
4017*b30d1939SAndy Fiddaman if (n > 0) {
4018*b30d1939SAndy Fiddaman zmemcpy(s->stream.next_out, s->stream.next_in, n);
4019*b30d1939SAndy Fiddaman next_out += n;
4020*b30d1939SAndy Fiddaman s->stream.next_out = next_out;
4021*b30d1939SAndy Fiddaman s->stream.next_in += n;
4022*b30d1939SAndy Fiddaman s->stream.avail_out -= n;
4023*b30d1939SAndy Fiddaman s->stream.avail_in -= n;
4024*b30d1939SAndy Fiddaman }
4025*b30d1939SAndy Fiddaman if (s->stream.avail_out > 0) {
4026*b30d1939SAndy Fiddaman s->stream.avail_out -=
4027*b30d1939SAndy Fiddaman (uInt)fread(next_out, 1, s->stream.avail_out, s->file);
4028*b30d1939SAndy Fiddaman }
4029*b30d1939SAndy Fiddaman len -= s->stream.avail_out;
4030*b30d1939SAndy Fiddaman s->in += len;
4031*b30d1939SAndy Fiddaman s->out += len;
4032*b30d1939SAndy Fiddaman if (len == 0) s->z_eof = 1;
4033*b30d1939SAndy Fiddaman return (int)len;
4034*b30d1939SAndy Fiddaman }
4035*b30d1939SAndy Fiddaman if (s->stream.avail_in == 0 && !s->z_eof) {
4036*b30d1939SAndy Fiddaman
4037*b30d1939SAndy Fiddaman errno = 0;
4038*b30d1939SAndy Fiddaman s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
4039*b30d1939SAndy Fiddaman if (s->stream.avail_in == 0) {
4040*b30d1939SAndy Fiddaman s->z_eof = 1;
4041*b30d1939SAndy Fiddaman if (ferror(s->file)) {
4042*b30d1939SAndy Fiddaman s->z_err = Z_ERRNO;
4043*b30d1939SAndy Fiddaman break;
4044*b30d1939SAndy Fiddaman }
4045*b30d1939SAndy Fiddaman }
4046*b30d1939SAndy Fiddaman s->stream.next_in = s->inbuf;
4047*b30d1939SAndy Fiddaman }
4048*b30d1939SAndy Fiddaman s->in += s->stream.avail_in;
4049*b30d1939SAndy Fiddaman s->out += s->stream.avail_out;
4050*b30d1939SAndy Fiddaman s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
4051*b30d1939SAndy Fiddaman s->in -= s->stream.avail_in;
4052*b30d1939SAndy Fiddaman s->out -= s->stream.avail_out;
4053*b30d1939SAndy Fiddaman
4054*b30d1939SAndy Fiddaman if (s->z_err == Z_STREAM_END) {
4055*b30d1939SAndy Fiddaman /* Check CRC and original size */
4056*b30d1939SAndy Fiddaman #if _PACKAGE_ast
4057*b30d1939SAndy Fiddaman if (!s->nocrc)
4058*b30d1939SAndy Fiddaman #endif
4059*b30d1939SAndy Fiddaman s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
4060*b30d1939SAndy Fiddaman start = s->stream.next_out;
4061*b30d1939SAndy Fiddaman
4062*b30d1939SAndy Fiddaman #if _PACKAGE_ast
4063*b30d1939SAndy Fiddaman if (getLong(s) != s->crc && !s->nocrc) {
4064*b30d1939SAndy Fiddaman #else
4065*b30d1939SAndy Fiddaman if (getLong(s) != s->crc) {
4066*b30d1939SAndy Fiddaman #endif
4067*b30d1939SAndy Fiddaman s->z_err = Z_DATA_ERROR;
4068*b30d1939SAndy Fiddaman } else {
4069*b30d1939SAndy Fiddaman (void)getLong(s);
4070*b30d1939SAndy Fiddaman /* The uncompressed length returned by above getlong() may be
4071*b30d1939SAndy Fiddaman * different from s->out in case of concatenated .gz files.
4072*b30d1939SAndy Fiddaman * Check for such files:
4073*b30d1939SAndy Fiddaman */
4074*b30d1939SAndy Fiddaman check_header(s);
4075*b30d1939SAndy Fiddaman if (s->z_err == Z_OK) {
4076*b30d1939SAndy Fiddaman inflateReset(&(s->stream));
4077*b30d1939SAndy Fiddaman #if _PACKAGE_ast
4078*b30d1939SAndy Fiddaman if (!s->nocrc)
4079*b30d1939SAndy Fiddaman #endif
4080*b30d1939SAndy Fiddaman s->crc = crc32(0L, Z_NULL, 0);
4081*b30d1939SAndy Fiddaman #if _PACKAGE_ast
4082*b30d1939SAndy Fiddaman else
4083*b30d1939SAndy Fiddaman s->z_err = Z_STREAM_END;
4084*b30d1939SAndy Fiddaman #endif
4085*b30d1939SAndy Fiddaman }
4086*b30d1939SAndy Fiddaman }
4087*b30d1939SAndy Fiddaman }
4088*b30d1939SAndy Fiddaman if (s->z_err != Z_OK || s->z_eof) break;
4089*b30d1939SAndy Fiddaman }
4090*b30d1939SAndy Fiddaman #if _PACKAGE_ast
4091*b30d1939SAndy Fiddaman if (!s->nocrc)
4092*b30d1939SAndy Fiddaman #endif
4093*b30d1939SAndy Fiddaman s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
4094*b30d1939SAndy Fiddaman
4095*b30d1939SAndy Fiddaman if (len == s->stream.avail_out &&
4096*b30d1939SAndy Fiddaman (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO))
4097*b30d1939SAndy Fiddaman return -1;
4098*b30d1939SAndy Fiddaman return (int)(len - s->stream.avail_out);
4099*b30d1939SAndy Fiddaman }
4100*b30d1939SAndy Fiddaman
4101*b30d1939SAndy Fiddaman /* ===========================================================================
4102*b30d1939SAndy Fiddaman Reads a long in LSB order from the given gz_stream. Sets z_err in case
4103*b30d1939SAndy Fiddaman of error.
4104*b30d1939SAndy Fiddaman */
getLong(s)4105*b30d1939SAndy Fiddaman local uLong getLong (s)
4106*b30d1939SAndy Fiddaman gz_stream *s;
4107*b30d1939SAndy Fiddaman {
4108*b30d1939SAndy Fiddaman uLong x = (uLong)get_byte(s);
4109*b30d1939SAndy Fiddaman int c;
4110*b30d1939SAndy Fiddaman
4111*b30d1939SAndy Fiddaman x += ((uLong)get_byte(s))<<8;
4112*b30d1939SAndy Fiddaman x += ((uLong)get_byte(s))<<16;
4113*b30d1939SAndy Fiddaman c = get_byte(s);
4114*b30d1939SAndy Fiddaman if (c == EOF) s->z_err = Z_DATA_ERROR;
4115*b30d1939SAndy Fiddaman x += ((uLong)c)<<24;
4116*b30d1939SAndy Fiddaman return x;
4117*b30d1939SAndy Fiddaman }
4118*b30d1939SAndy Fiddaman
4119*b30d1939SAndy Fiddaman #endif /* _GZIO_C */
4120*b30d1939SAndy Fiddaman
4121*b30d1939SAndy Fiddaman #endif /* _GUNZIP_H */
4122*b30d1939SAndy Fiddaman
4123*b30d1939SAndy Fiddaman #undef local
4124*b30d1939SAndy Fiddaman
4125*b30d1939SAndy Fiddaman #ifndef _RATZ_C
4126*b30d1939SAndy Fiddaman #define _RATZ_C 1
4127*b30d1939SAndy Fiddaman
4128*b30d1939SAndy Fiddaman #include <sys/stat.h>
4129*b30d1939SAndy Fiddaman
4130*b30d1939SAndy Fiddaman #ifndef S_IRUSR
4131*b30d1939SAndy Fiddaman #define S_IRUSR 0400
4132*b30d1939SAndy Fiddaman #endif
4133*b30d1939SAndy Fiddaman #ifndef S_IWUSR
4134*b30d1939SAndy Fiddaman #define S_IWUSR 0200
4135*b30d1939SAndy Fiddaman #endif
4136*b30d1939SAndy Fiddaman #ifndef S_IXUSR
4137*b30d1939SAndy Fiddaman #define S_IXUSR 0100
4138*b30d1939SAndy Fiddaman #endif
4139*b30d1939SAndy Fiddaman #ifndef S_IRGRP
4140*b30d1939SAndy Fiddaman #define S_IRGRP 0040
4141*b30d1939SAndy Fiddaman #endif
4142*b30d1939SAndy Fiddaman #ifndef S_IWGRP
4143*b30d1939SAndy Fiddaman #define S_IWGRP 0020
4144*b30d1939SAndy Fiddaman #endif
4145*b30d1939SAndy Fiddaman #ifndef S_IXGRP
4146*b30d1939SAndy Fiddaman #define S_IXGRP 0010
4147*b30d1939SAndy Fiddaman #endif
4148*b30d1939SAndy Fiddaman #ifndef S_IROTH
4149*b30d1939SAndy Fiddaman #define S_IROTH 0004
4150*b30d1939SAndy Fiddaman #endif
4151*b30d1939SAndy Fiddaman #ifndef S_IWOTH
4152*b30d1939SAndy Fiddaman #define S_IWOTH 0002
4153*b30d1939SAndy Fiddaman #endif
4154*b30d1939SAndy Fiddaman #ifndef S_IXOTH
4155*b30d1939SAndy Fiddaman #define S_IXOTH 0001
4156*b30d1939SAndy Fiddaman #endif
4157*b30d1939SAndy Fiddaman
4158*b30d1939SAndy Fiddaman /*
4159*b30d1939SAndy Fiddaman * Standard Archive Format
4160*b30d1939SAndy Fiddaman * USTAR - Uniform Standard Tape ARchive
4161*b30d1939SAndy Fiddaman */
4162*b30d1939SAndy Fiddaman
4163*b30d1939SAndy Fiddaman #define TBLOCK 512
4164*b30d1939SAndy Fiddaman #define NAMSIZ 100
4165*b30d1939SAndy Fiddaman #define PFXSIZ 155
4166*b30d1939SAndy Fiddaman
4167*b30d1939SAndy Fiddaman #define TMODLEN 8
4168*b30d1939SAndy Fiddaman #define TUIDLEN 8
4169*b30d1939SAndy Fiddaman #define TGIDLEN 8
4170*b30d1939SAndy Fiddaman #define TSIZLEN 12
4171*b30d1939SAndy Fiddaman #define TMTMLEN 12
4172*b30d1939SAndy Fiddaman #define TCKSLEN 8
4173*b30d1939SAndy Fiddaman
4174*b30d1939SAndy Fiddaman #define TMAGIC "ustar" /* ustar and a null */
4175*b30d1939SAndy Fiddaman #define TMAGLEN 6
4176*b30d1939SAndy Fiddaman #define TVERSION "00" /* 00 and no null */
4177*b30d1939SAndy Fiddaman #define TVERSLEN 2
4178*b30d1939SAndy Fiddaman #define TUNMLEN 32
4179*b30d1939SAndy Fiddaman #define TGNMLEN 32
4180*b30d1939SAndy Fiddaman #define TDEVLEN 8
4181*b30d1939SAndy Fiddaman #define TPADLEN 12
4182*b30d1939SAndy Fiddaman
4183*b30d1939SAndy Fiddaman /*
4184*b30d1939SAndy Fiddaman * values used in typeflag field
4185*b30d1939SAndy Fiddaman */
4186*b30d1939SAndy Fiddaman
4187*b30d1939SAndy Fiddaman #define REGTYPE '0' /* regular file */
4188*b30d1939SAndy Fiddaman #define AREGTYPE 0 /* alternate REGTYPE */
4189*b30d1939SAndy Fiddaman #define LNKTYPE '1' /* hard link */
4190*b30d1939SAndy Fiddaman #define SYMTYPE '2' /* soft link */
4191*b30d1939SAndy Fiddaman #define CHRTYPE '3' /* character special */
4192*b30d1939SAndy Fiddaman #define BLKTYPE '4' /* block special */
4193*b30d1939SAndy Fiddaman #define DIRTYPE '5' /* directory */
4194*b30d1939SAndy Fiddaman #define FIFOTYPE '6' /* FIFO special */
4195*b30d1939SAndy Fiddaman #define CONTTYPE '7' /* reserved */
4196*b30d1939SAndy Fiddaman #define SOKTYPE '8' /* socket -- reserved */
4197*b30d1939SAndy Fiddaman #define VERTYPE 'V' /* version -- reserved */
4198*b30d1939SAndy Fiddaman #define EXTTYPE 'x' /* extended header -- reserved */
4199*b30d1939SAndy Fiddaman
4200*b30d1939SAndy Fiddaman /*
4201*b30d1939SAndy Fiddaman * bits used in mode field
4202*b30d1939SAndy Fiddaman */
4203*b30d1939SAndy Fiddaman
4204*b30d1939SAndy Fiddaman #define TSUID 04000 /* set uid on exec */
4205*b30d1939SAndy Fiddaman #define TSGID 02000 /* set gid on exec */
4206*b30d1939SAndy Fiddaman #define TSVTX 01000 /* sticky bit -- reserved */
4207*b30d1939SAndy Fiddaman
4208*b30d1939SAndy Fiddaman /*
4209*b30d1939SAndy Fiddaman * file permissions
4210*b30d1939SAndy Fiddaman */
4211*b30d1939SAndy Fiddaman
4212*b30d1939SAndy Fiddaman #define TUREAD 00400 /* read by owner */
4213*b30d1939SAndy Fiddaman #define TUWRITE 00200 /* write by owner */
4214*b30d1939SAndy Fiddaman #define TUEXEC 00100 /* execute by owner */
4215*b30d1939SAndy Fiddaman #define TGREAD 00040 /* read by group */
4216*b30d1939SAndy Fiddaman #define TGWRITE 00020 /* execute by group */
4217*b30d1939SAndy Fiddaman #define TGEXEC 00010 /* write by group */
4218*b30d1939SAndy Fiddaman #define TOREAD 00004 /* read by other */
4219*b30d1939SAndy Fiddaman #define TOWRITE 00002 /* write by other */
4220*b30d1939SAndy Fiddaman #define TOEXEC 00001 /* execute by other */
4221*b30d1939SAndy Fiddaman
4222*b30d1939SAndy Fiddaman #define TAR_SUMASK ((1L<<(TCKSLEN-1)*3)-1)
4223*b30d1939SAndy Fiddaman
4224*b30d1939SAndy Fiddaman typedef struct
4225*b30d1939SAndy Fiddaman {
4226*b30d1939SAndy Fiddaman char name[NAMSIZ];
4227*b30d1939SAndy Fiddaman char mode[TMODLEN];
4228*b30d1939SAndy Fiddaman char uid[TUIDLEN];
4229*b30d1939SAndy Fiddaman char gid[TGIDLEN];
4230*b30d1939SAndy Fiddaman char size[TSIZLEN];
4231*b30d1939SAndy Fiddaman char mtime[TMTMLEN];
4232*b30d1939SAndy Fiddaman char chksum[TCKSLEN];
4233*b30d1939SAndy Fiddaman char typeflag;
4234*b30d1939SAndy Fiddaman char linkname[NAMSIZ];
4235*b30d1939SAndy Fiddaman char magic[TMAGLEN];
4236*b30d1939SAndy Fiddaman char version[TVERSLEN];
4237*b30d1939SAndy Fiddaman char uname[TUNMLEN];
4238*b30d1939SAndy Fiddaman char gname[TGNMLEN];
4239*b30d1939SAndy Fiddaman char devmajor[TDEVLEN];
4240*b30d1939SAndy Fiddaman char devminor[TDEVLEN];
4241*b30d1939SAndy Fiddaman char prefix[PFXSIZ];
4242*b30d1939SAndy Fiddaman char pad[TPADLEN];
4243*b30d1939SAndy Fiddaman } Header_t;
4244*b30d1939SAndy Fiddaman
4245*b30d1939SAndy Fiddaman static struct
4246*b30d1939SAndy Fiddaman {
4247*b30d1939SAndy Fiddaman char* id;
4248*b30d1939SAndy Fiddaman unsigned long blocks;
4249*b30d1939SAndy Fiddaman unsigned long files;
4250*b30d1939SAndy Fiddaman } state;
4251*b30d1939SAndy Fiddaman
4252*b30d1939SAndy Fiddaman #if !_PACKAGE_ast
4253*b30d1939SAndy Fiddaman
4254*b30d1939SAndy Fiddaman static void
usage()4255*b30d1939SAndy Fiddaman usage()
4256*b30d1939SAndy Fiddaman {
4257*b30d1939SAndy Fiddaman #if defined(_SEAR_EXEC) || defined(_SEAR_SEEK)
4258*b30d1939SAndy Fiddaman fprintf(stderr, "Usage: %s [-ciklmntvV] [ [no]name[=value] ... ]\n", state.id);
4259*b30d1939SAndy Fiddaman #else
4260*b30d1939SAndy Fiddaman fprintf(stderr, "Usage: %s [-clmntvV] < input.tgz\n", state.id);
4261*b30d1939SAndy Fiddaman #endif
4262*b30d1939SAndy Fiddaman exit(2);
4263*b30d1939SAndy Fiddaman }
4264*b30d1939SAndy Fiddaman
4265*b30d1939SAndy Fiddaman #endif
4266*b30d1939SAndy Fiddaman
4267*b30d1939SAndy Fiddaman /*
4268*b30d1939SAndy Fiddaman * the X/Open dd EBCDIC table
4269*b30d1939SAndy Fiddaman */
4270*b30d1939SAndy Fiddaman
4271*b30d1939SAndy Fiddaman static const unsigned char a2e[] =
4272*b30d1939SAndy Fiddaman {
4273*b30d1939SAndy Fiddaman 0000,0001,0002,0003,0067,0055,0056,0057,
4274*b30d1939SAndy Fiddaman 0026,0005,0045,0013,0014,0015,0016,0017,
4275*b30d1939SAndy Fiddaman 0020,0021,0022,0023,0074,0075,0062,0046,
4276*b30d1939SAndy Fiddaman 0030,0031,0077,0047,0034,0035,0036,0037,
4277*b30d1939SAndy Fiddaman 0100,0132,0177,0173,0133,0154,0120,0175,
4278*b30d1939SAndy Fiddaman 0115,0135,0134,0116,0153,0140,0113,0141,
4279*b30d1939SAndy Fiddaman 0360,0361,0362,0363,0364,0365,0366,0367,
4280*b30d1939SAndy Fiddaman 0370,0371,0172,0136,0114,0176,0156,0157,
4281*b30d1939SAndy Fiddaman 0174,0301,0302,0303,0304,0305,0306,0307,
4282*b30d1939SAndy Fiddaman 0310,0311,0321,0322,0323,0324,0325,0326,
4283*b30d1939SAndy Fiddaman 0327,0330,0331,0342,0343,0344,0345,0346,
4284*b30d1939SAndy Fiddaman 0347,0350,0351,0255,0340,0275,0232,0155,
4285*b30d1939SAndy Fiddaman 0171,0201,0202,0203,0204,0205,0206,0207,
4286*b30d1939SAndy Fiddaman 0210,0211,0221,0222,0223,0224,0225,0226,
4287*b30d1939SAndy Fiddaman 0227,0230,0231,0242,0243,0244,0245,0246,
4288*b30d1939SAndy Fiddaman 0247,0250,0251,0300,0117,0320,0137,0007,
4289*b30d1939SAndy Fiddaman 0040,0041,0042,0043,0044,0025,0006,0027,
4290*b30d1939SAndy Fiddaman 0050,0051,0052,0053,0054,0011,0012,0033,
4291*b30d1939SAndy Fiddaman 0060,0061,0032,0063,0064,0065,0066,0010,
4292*b30d1939SAndy Fiddaman 0070,0071,0072,0073,0004,0024,0076,0341,
4293*b30d1939SAndy Fiddaman 0101,0102,0103,0104,0105,0106,0107,0110,
4294*b30d1939SAndy Fiddaman 0111,0121,0122,0123,0124,0125,0126,0127,
4295*b30d1939SAndy Fiddaman 0130,0131,0142,0143,0144,0145,0146,0147,
4296*b30d1939SAndy Fiddaman 0150,0151,0160,0161,0162,0163,0164,0165,
4297*b30d1939SAndy Fiddaman 0166,0167,0170,0200,0212,0213,0214,0215,
4298*b30d1939SAndy Fiddaman 0216,0217,0220,0152,0233,0234,0235,0236,
4299*b30d1939SAndy Fiddaman 0237,0240,0252,0253,0254,0112,0256,0257,
4300*b30d1939SAndy Fiddaman 0260,0261,0262,0263,0264,0265,0266,0267,
4301*b30d1939SAndy Fiddaman 0270,0271,0272,0273,0274,0241,0276,0277,
4302*b30d1939SAndy Fiddaman 0312,0313,0314,0315,0316,0317,0332,0333,
4303*b30d1939SAndy Fiddaman 0334,0335,0336,0337,0352,0353,0354,0355,
4304*b30d1939SAndy Fiddaman 0356,0357,0372,0373,0374,0375,0376,0377,
4305*b30d1939SAndy Fiddaman };
4306*b30d1939SAndy Fiddaman
4307*b30d1939SAndy Fiddaman /*
4308*b30d1939SAndy Fiddaman * the X/Open dd IBM table
4309*b30d1939SAndy Fiddaman */
4310*b30d1939SAndy Fiddaman
4311*b30d1939SAndy Fiddaman static const unsigned char a2i[] =
4312*b30d1939SAndy Fiddaman {
4313*b30d1939SAndy Fiddaman 0000,0001,0002,0003,0067,0055,0056,0057,
4314*b30d1939SAndy Fiddaman 0026,0005,0045,0013,0014,0015,0016,0017,
4315*b30d1939SAndy Fiddaman 0020,0021,0022,0023,0074,0075,0062,0046,
4316*b30d1939SAndy Fiddaman 0030,0031,0077,0047,0034,0035,0036,0037,
4317*b30d1939SAndy Fiddaman 0100,0132,0177,0173,0133,0154,0120,0175,
4318*b30d1939SAndy Fiddaman 0115,0135,0134,0116,0153,0140,0113,0141,
4319*b30d1939SAndy Fiddaman 0360,0361,0362,0363,0364,0365,0366,0367,
4320*b30d1939SAndy Fiddaman 0370,0371,0172,0136,0114,0176,0156,0157,
4321*b30d1939SAndy Fiddaman 0174,0301,0302,0303,0304,0305,0306,0307,
4322*b30d1939SAndy Fiddaman 0310,0311,0321,0322,0323,0324,0325,0326,
4323*b30d1939SAndy Fiddaman 0327,0330,0331,0342,0343,0344,0345,0346,
4324*b30d1939SAndy Fiddaman 0347,0350,0351,0255,0340,0275,0137,0155,
4325*b30d1939SAndy Fiddaman 0171,0201,0202,0203,0204,0205,0206,0207,
4326*b30d1939SAndy Fiddaman 0210,0211,0221,0222,0223,0224,0225,0226,
4327*b30d1939SAndy Fiddaman 0227,0230,0231,0242,0243,0244,0245,0246,
4328*b30d1939SAndy Fiddaman 0247,0250,0251,0300,0117,0320,0241,0007,
4329*b30d1939SAndy Fiddaman 0040,0041,0042,0043,0044,0025,0006,0027,
4330*b30d1939SAndy Fiddaman 0050,0051,0052,0053,0054,0011,0012,0033,
4331*b30d1939SAndy Fiddaman 0060,0061,0032,0063,0064,0065,0066,0010,
4332*b30d1939SAndy Fiddaman 0070,0071,0072,0073,0004,0024,0076,0341,
4333*b30d1939SAndy Fiddaman 0101,0102,0103,0104,0105,0106,0107,0110,
4334*b30d1939SAndy Fiddaman 0111,0121,0122,0123,0124,0125,0126,0127,
4335*b30d1939SAndy Fiddaman 0130,0131,0142,0143,0144,0145,0146,0147,
4336*b30d1939SAndy Fiddaman 0150,0151,0160,0161,0162,0163,0164,0165,
4337*b30d1939SAndy Fiddaman 0166,0167,0170,0200,0212,0213,0214,0215,
4338*b30d1939SAndy Fiddaman 0216,0217,0220,0232,0233,0234,0235,0236,
4339*b30d1939SAndy Fiddaman 0237,0240,0252,0253,0254,0255,0256,0257,
4340*b30d1939SAndy Fiddaman 0260,0261,0262,0263,0264,0265,0266,0267,
4341*b30d1939SAndy Fiddaman 0270,0271,0272,0273,0274,0275,0276,0277,
4342*b30d1939SAndy Fiddaman 0312,0313,0314,0315,0316,0317,0332,0333,
4343*b30d1939SAndy Fiddaman 0334,0335,0336,0337,0352,0353,0354,0355,
4344*b30d1939SAndy Fiddaman 0356,0357,0372,0373,0374,0375,0376,0377,
4345*b30d1939SAndy Fiddaman };
4346*b30d1939SAndy Fiddaman
4347*b30d1939SAndy Fiddaman /*
4348*b30d1939SAndy Fiddaman * the mvs OpenEdition EBCDIC table
4349*b30d1939SAndy Fiddaman */
4350*b30d1939SAndy Fiddaman
4351*b30d1939SAndy Fiddaman static const unsigned char a2o[] =
4352*b30d1939SAndy Fiddaman {
4353*b30d1939SAndy Fiddaman 0000,0001,0002,0003,0067,0055,0056,0057,
4354*b30d1939SAndy Fiddaman 0026,0005,0025,0013,0014,0015,0016,0017,
4355*b30d1939SAndy Fiddaman 0020,0021,0022,0023,0074,0075,0062,0046,
4356*b30d1939SAndy Fiddaman 0030,0031,0077,0047,0034,0035,0036,0037,
4357*b30d1939SAndy Fiddaman 0100,0132,0177,0173,0133,0154,0120,0175,
4358*b30d1939SAndy Fiddaman 0115,0135,0134,0116,0153,0140,0113,0141,
4359*b30d1939SAndy Fiddaman 0360,0361,0362,0363,0364,0365,0366,0367,
4360*b30d1939SAndy Fiddaman 0370,0371,0172,0136,0114,0176,0156,0157,
4361*b30d1939SAndy Fiddaman 0174,0301,0302,0303,0304,0305,0306,0307,
4362*b30d1939SAndy Fiddaman 0310,0311,0321,0322,0323,0324,0325,0326,
4363*b30d1939SAndy Fiddaman 0327,0330,0331,0342,0343,0344,0345,0346,
4364*b30d1939SAndy Fiddaman 0347,0350,0351,0255,0340,0275,0137,0155,
4365*b30d1939SAndy Fiddaman 0171,0201,0202,0203,0204,0205,0206,0207,
4366*b30d1939SAndy Fiddaman 0210,0211,0221,0222,0223,0224,0225,0226,
4367*b30d1939SAndy Fiddaman 0227,0230,0231,0242,0243,0244,0245,0246,
4368*b30d1939SAndy Fiddaman 0247,0250,0251,0300,0117,0320,0241,0007,
4369*b30d1939SAndy Fiddaman 0040,0041,0042,0043,0044,0045,0006,0027,
4370*b30d1939SAndy Fiddaman 0050,0051,0052,0053,0054,0011,0012,0033,
4371*b30d1939SAndy Fiddaman 0060,0061,0032,0063,0064,0065,0066,0010,
4372*b30d1939SAndy Fiddaman 0070,0071,0072,0073,0004,0024,0076,0377,
4373*b30d1939SAndy Fiddaman 0101,0252,0112,0261,0237,0262,0152,0265,
4374*b30d1939SAndy Fiddaman 0273,0264,0232,0212,0260,0312,0257,0274,
4375*b30d1939SAndy Fiddaman 0220,0217,0352,0372,0276,0240,0266,0263,
4376*b30d1939SAndy Fiddaman 0235,0332,0233,0213,0267,0270,0271,0253,
4377*b30d1939SAndy Fiddaman 0144,0145,0142,0146,0143,0147,0236,0150,
4378*b30d1939SAndy Fiddaman 0164,0161,0162,0163,0170,0165,0166,0167,
4379*b30d1939SAndy Fiddaman 0254,0151,0355,0356,0353,0357,0354,0277,
4380*b30d1939SAndy Fiddaman 0200,0375,0376,0373,0374,0272,0256,0131,
4381*b30d1939SAndy Fiddaman 0104,0105,0102,0106,0103,0107,0234,0110,
4382*b30d1939SAndy Fiddaman 0124,0121,0122,0123,0130,0125,0126,0127,
4383*b30d1939SAndy Fiddaman 0214,0111,0315,0316,0313,0317,0314,0341,
4384*b30d1939SAndy Fiddaman 0160,0335,0336,0333,0334,0215,0216,0337,
4385*b30d1939SAndy Fiddaman };
4386*b30d1939SAndy Fiddaman
4387*b30d1939SAndy Fiddaman /*
4388*b30d1939SAndy Fiddaman * ascii text vs. control
4389*b30d1939SAndy Fiddaman */
4390*b30d1939SAndy Fiddaman
4391*b30d1939SAndy Fiddaman static const unsigned char ascii_text[] =
4392*b30d1939SAndy Fiddaman {
4393*b30d1939SAndy Fiddaman 0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,
4394*b30d1939SAndy Fiddaman 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
4395*b30d1939SAndy Fiddaman 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
4396*b30d1939SAndy Fiddaman 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,
4397*b30d1939SAndy Fiddaman 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
4398*b30d1939SAndy Fiddaman 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
4399*b30d1939SAndy Fiddaman 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
4400*b30d1939SAndy Fiddaman 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
4401*b30d1939SAndy Fiddaman };
4402*b30d1939SAndy Fiddaman
4403*b30d1939SAndy Fiddaman static int
block(fp,gz,buf)4404*b30d1939SAndy Fiddaman block(fp, gz, buf)
4405*b30d1939SAndy Fiddaman FILE* fp;
4406*b30d1939SAndy Fiddaman gzFile gz;
4407*b30d1939SAndy Fiddaman char* buf;
4408*b30d1939SAndy Fiddaman {
4409*b30d1939SAndy Fiddaman int r;
4410*b30d1939SAndy Fiddaman
4411*b30d1939SAndy Fiddaman if (gz)
4412*b30d1939SAndy Fiddaman r = gzread(gz, buf, sizeof(Header_t)) == sizeof(Header_t);
4413*b30d1939SAndy Fiddaman else
4414*b30d1939SAndy Fiddaman r = fread(buf, sizeof(Header_t), 1, fp) == 1;
4415*b30d1939SAndy Fiddaman if (r)
4416*b30d1939SAndy Fiddaman state.blocks++;
4417*b30d1939SAndy Fiddaman return r;
4418*b30d1939SAndy Fiddaman }
4419*b30d1939SAndy Fiddaman
4420*b30d1939SAndy Fiddaman static int
skip(fp,gz,buf,n)4421*b30d1939SAndy Fiddaman skip(fp, gz, buf, n)
4422*b30d1939SAndy Fiddaman FILE* fp;
4423*b30d1939SAndy Fiddaman gzFile gz;
4424*b30d1939SAndy Fiddaman char* buf;
4425*b30d1939SAndy Fiddaman unsigned long n;
4426*b30d1939SAndy Fiddaman {
4427*b30d1939SAndy Fiddaman while (n > 0)
4428*b30d1939SAndy Fiddaman {
4429*b30d1939SAndy Fiddaman if (!block(fp, gz, buf))
4430*b30d1939SAndy Fiddaman {
4431*b30d1939SAndy Fiddaman fprintf(stderr, "%s: unexpected EOF\n", state.id);
4432*b30d1939SAndy Fiddaman return 1;
4433*b30d1939SAndy Fiddaman }
4434*b30d1939SAndy Fiddaman if (n <= sizeof(Header_t))
4435*b30d1939SAndy Fiddaman break;
4436*b30d1939SAndy Fiddaman n -= sizeof(Header_t);
4437*b30d1939SAndy Fiddaman }
4438*b30d1939SAndy Fiddaman return 0;
4439*b30d1939SAndy Fiddaman }
4440*b30d1939SAndy Fiddaman
4441*b30d1939SAndy Fiddaman static unsigned long
number(s)4442*b30d1939SAndy Fiddaman number(s)
4443*b30d1939SAndy Fiddaman register char* s;
4444*b30d1939SAndy Fiddaman {
4445*b30d1939SAndy Fiddaman unsigned long n = 0;
4446*b30d1939SAndy Fiddaman
4447*b30d1939SAndy Fiddaman while (*s == ' ')
4448*b30d1939SAndy Fiddaman s++;
4449*b30d1939SAndy Fiddaman while (*s >= '0' && *s <= '7')
4450*b30d1939SAndy Fiddaman n = (n << 3) + (*s++ - '0');
4451*b30d1939SAndy Fiddaman return n;
4452*b30d1939SAndy Fiddaman }
4453*b30d1939SAndy Fiddaman
4454*b30d1939SAndy Fiddaman #if defined(_SEAR_EXEC) || defined(_SEAR_SEEK)
4455*b30d1939SAndy Fiddaman
4456*b30d1939SAndy Fiddaman #ifndef PATH_MAX
4457*b30d1939SAndy Fiddaman #define PATH_MAX 256
4458*b30d1939SAndy Fiddaman #endif
4459*b30d1939SAndy Fiddaman
4460*b30d1939SAndy Fiddaman #define EXIT(n) return(sear_exec((char*)0,(char**)0,(char*)0,(n)))
4461*b30d1939SAndy Fiddaman
4462*b30d1939SAndy Fiddaman static int sear_stdin;
4463*b30d1939SAndy Fiddaman static char* sear_tmp;
4464*b30d1939SAndy Fiddaman static char sear_buf[PATH_MAX];
4465*b30d1939SAndy Fiddaman
4466*b30d1939SAndy Fiddaman static int
sear_seek(off_t offset,int tmp)4467*b30d1939SAndy Fiddaman sear_seek(off_t offset, int tmp)
4468*b30d1939SAndy Fiddaman {
4469*b30d1939SAndy Fiddaman int n;
4470*b30d1939SAndy Fiddaman char cmd[PATH_MAX];
4471*b30d1939SAndy Fiddaman
4472*b30d1939SAndy Fiddaman GetModuleFileName(NULL, cmd, sizeof(cmd));
4473*b30d1939SAndy Fiddaman sear_stdin = dup(0);
4474*b30d1939SAndy Fiddaman close(0);
4475*b30d1939SAndy Fiddaman if (open(cmd, O_BINARY|O_RDONLY) || lseek(0, offset, 0) != offset)
4476*b30d1939SAndy Fiddaman {
4477*b30d1939SAndy Fiddaman fprintf(stderr, "%s: %s: cannot seek to data offset\n", state.id, cmd);
4478*b30d1939SAndy Fiddaman return -1;
4479*b30d1939SAndy Fiddaman }
4480*b30d1939SAndy Fiddaman if (tmp)
4481*b30d1939SAndy Fiddaman {
4482*b30d1939SAndy Fiddaman if ((n = GetTempPath(sizeof(cmd), cmd)) <= 0 || n > sizeof(cmd))
4483*b30d1939SAndy Fiddaman {
4484*b30d1939SAndy Fiddaman fprintf(stderr, "%s: cannot determine temporary directory path\n", state.id);
4485*b30d1939SAndy Fiddaman return -1;
4486*b30d1939SAndy Fiddaman }
4487*b30d1939SAndy Fiddaman if (!GetTempFileName(cmd, "SEA", 0, sear_buf))
4488*b30d1939SAndy Fiddaman {
4489*b30d1939SAndy Fiddaman fprintf(stderr, "%s: cannot determine temporary file path\n", state.id);
4490*b30d1939SAndy Fiddaman return -1;
4491*b30d1939SAndy Fiddaman }
4492*b30d1939SAndy Fiddaman sear_tmp = sear_buf;
4493*b30d1939SAndy Fiddaman if (!DeleteFile(sear_tmp))
4494*b30d1939SAndy Fiddaman {
4495*b30d1939SAndy Fiddaman fprintf(stderr, "%s: %s: cannot initialize temporary directory\n", state.id, sear_tmp);
4496*b30d1939SAndy Fiddaman return -1;
4497*b30d1939SAndy Fiddaman }
4498*b30d1939SAndy Fiddaman if (!CreateDirectory(sear_tmp, NULL))
4499*b30d1939SAndy Fiddaman {
4500*b30d1939SAndy Fiddaman fprintf(stderr, "%s: %s: cannot create temporary directory\n", state.id, sear_tmp);
4501*b30d1939SAndy Fiddaman return -1;
4502*b30d1939SAndy Fiddaman }
4503*b30d1939SAndy Fiddaman if (!SetCurrentDirectory(sear_tmp))
4504*b30d1939SAndy Fiddaman {
4505*b30d1939SAndy Fiddaman fprintf(stderr, "%s: %s: cannot cd to temporary directory\n", state.id, sear_tmp);
4506*b30d1939SAndy Fiddaman return -1;
4507*b30d1939SAndy Fiddaman }
4508*b30d1939SAndy Fiddaman }
4509*b30d1939SAndy Fiddaman return 0;
4510*b30d1939SAndy Fiddaman }
4511*b30d1939SAndy Fiddaman
4512*b30d1939SAndy Fiddaman /*
4513*b30d1939SAndy Fiddaman * remove dir and its subdirs
4514*b30d1939SAndy Fiddaman */
4515*b30d1939SAndy Fiddaman
4516*b30d1939SAndy Fiddaman static void
sear_rm_r(char * dir)4517*b30d1939SAndy Fiddaman sear_rm_r(char* dir)
4518*b30d1939SAndy Fiddaman {
4519*b30d1939SAndy Fiddaman WIN32_FIND_DATA info;
4520*b30d1939SAndy Fiddaman HANDLE hp;
4521*b30d1939SAndy Fiddaman
4522*b30d1939SAndy Fiddaman if (!SetCurrentDirectory(dir))
4523*b30d1939SAndy Fiddaman return;
4524*b30d1939SAndy Fiddaman if ((hp = FindFirstFile("*.*", &info)) != INVALID_HANDLE_VALUE)
4525*b30d1939SAndy Fiddaman {
4526*b30d1939SAndy Fiddaman do
4527*b30d1939SAndy Fiddaman {
4528*b30d1939SAndy Fiddaman if (!(info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
4529*b30d1939SAndy Fiddaman {
4530*b30d1939SAndy Fiddaman if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
4531*b30d1939SAndy Fiddaman SetFileAttributes(info.cFileName, info.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY);
4532*b30d1939SAndy Fiddaman DeleteFile(info.cFileName);
4533*b30d1939SAndy Fiddaman }
4534*b30d1939SAndy Fiddaman else if (info.cFileName[0] != '.' || info.cFileName[1] != 0 && (info.cFileName[1] != '.' || info.cFileName[2] != 0))
4535*b30d1939SAndy Fiddaman sear_rm_r(info.cFileName);
4536*b30d1939SAndy Fiddaman } while(FindNextFile(hp, &info));
4537*b30d1939SAndy Fiddaman FindClose(hp);
4538*b30d1939SAndy Fiddaman }
4539*b30d1939SAndy Fiddaman if (SetCurrentDirectory(".."))
4540*b30d1939SAndy Fiddaman RemoveDirectory(dir);
4541*b30d1939SAndy Fiddaman }
4542*b30d1939SAndy Fiddaman
4543*b30d1939SAndy Fiddaman /*
4544*b30d1939SAndy Fiddaman * system(3) without PATH search that should work on all windows variants
4545*b30d1939SAndy Fiddaman */
4546*b30d1939SAndy Fiddaman
4547*b30d1939SAndy Fiddaman static int
sear_system(const char * command,int nowindow)4548*b30d1939SAndy Fiddaman sear_system(const char* command, int nowindow)
4549*b30d1939SAndy Fiddaman {
4550*b30d1939SAndy Fiddaman PROCESS_INFORMATION pinfo;
4551*b30d1939SAndy Fiddaman STARTUPINFO sinfo;
4552*b30d1939SAndy Fiddaman char* cp;
4553*b30d1939SAndy Fiddaman char path[PATH_MAX];
4554*b30d1939SAndy Fiddaman int n = *command == '"';
4555*b30d1939SAndy Fiddaman DWORD flags = NORMAL_PRIORITY_CLASS;
4556*b30d1939SAndy Fiddaman
4557*b30d1939SAndy Fiddaman strncpy(path, &command[n], PATH_MAX - 4);
4558*b30d1939SAndy Fiddaman n = n ? '"' : ' ';
4559*b30d1939SAndy Fiddaman for (cp = path; *cp; *cp++)
4560*b30d1939SAndy Fiddaman if (*cp == n)
4561*b30d1939SAndy Fiddaman break;
4562*b30d1939SAndy Fiddaman *cp = 0;
4563*b30d1939SAndy Fiddaman if (GetFileAttributes(path) == 0xffffffff && GetLastError() == ERROR_FILE_NOT_FOUND)
4564*b30d1939SAndy Fiddaman strcpy(cp, ".exe");
4565*b30d1939SAndy Fiddaman ZeroMemory(&sinfo, sizeof(sinfo));
4566*b30d1939SAndy Fiddaman if (nowindow)
4567*b30d1939SAndy Fiddaman flags |= CREATE_NO_WINDOW;
4568*b30d1939SAndy Fiddaman if (!CreateProcess(path, (char*)command, 0, 0, TRUE, flags, NULL, NULL, &sinfo, &pinfo))
4569*b30d1939SAndy Fiddaman n = GetLastError() == ERROR_FILE_NOT_FOUND ? 127 : 126;
4570*b30d1939SAndy Fiddaman else
4571*b30d1939SAndy Fiddaman {
4572*b30d1939SAndy Fiddaman CloseHandle(pinfo.hThread);
4573*b30d1939SAndy Fiddaman WaitForSingleObject(pinfo.hProcess, INFINITE);
4574*b30d1939SAndy Fiddaman if (!GetExitCodeProcess(pinfo.hProcess, &n))
4575*b30d1939SAndy Fiddaman n = 1;
4576*b30d1939SAndy Fiddaman CloseHandle(pinfo.hProcess);
4577*b30d1939SAndy Fiddaman Sleep(2 * 1000);
4578*b30d1939SAndy Fiddaman }
4579*b30d1939SAndy Fiddaman return n;
4580*b30d1939SAndy Fiddaman }
4581*b30d1939SAndy Fiddaman
4582*b30d1939SAndy Fiddaman /*
4583*b30d1939SAndy Fiddaman * copy t to f but no farther than e
4584*b30d1939SAndy Fiddaman * next t returned
4585*b30d1939SAndy Fiddaman */
4586*b30d1939SAndy Fiddaman
4587*b30d1939SAndy Fiddaman static char*
copy(char * t,const char * f,char * e)4588*b30d1939SAndy Fiddaman copy(char* t, const char* f, char* e)
4589*b30d1939SAndy Fiddaman {
4590*b30d1939SAndy Fiddaman while (t < e && *f)
4591*b30d1939SAndy Fiddaman *t++ = *f++;
4592*b30d1939SAndy Fiddaman return t;
4593*b30d1939SAndy Fiddaman }
4594*b30d1939SAndy Fiddaman
4595*b30d1939SAndy Fiddaman /*
4596*b30d1939SAndy Fiddaman * execute cmd, chdir .., and remove sear_tmp
4597*b30d1939SAndy Fiddaman */
4598*b30d1939SAndy Fiddaman
4599*b30d1939SAndy Fiddaman static int
sear_exec(const char * cmd,char * const * arg,char * operands,int code)4600*b30d1939SAndy Fiddaman sear_exec(const char* cmd, char* const* arg, char* operands, int code)
4601*b30d1939SAndy Fiddaman {
4602*b30d1939SAndy Fiddaman const char* a;
4603*b30d1939SAndy Fiddaman char* b;
4604*b30d1939SAndy Fiddaman char* e;
4605*b30d1939SAndy Fiddaman int r;
4606*b30d1939SAndy Fiddaman int sh;
4607*b30d1939SAndy Fiddaman int nowindow;
4608*b30d1939SAndy Fiddaman char buf[1024];
4609*b30d1939SAndy Fiddaman
4610*b30d1939SAndy Fiddaman fflush(stdout);
4611*b30d1939SAndy Fiddaman fflush(stderr);
4612*b30d1939SAndy Fiddaman if (sear_tmp)
4613*b30d1939SAndy Fiddaman {
4614*b30d1939SAndy Fiddaman close(0);
4615*b30d1939SAndy Fiddaman dup(sear_stdin);
4616*b30d1939SAndy Fiddaman close(sear_stdin);
4617*b30d1939SAndy Fiddaman nowindow = 0;
4618*b30d1939SAndy Fiddaman if (cmd)
4619*b30d1939SAndy Fiddaman {
4620*b30d1939SAndy Fiddaman if (arg)
4621*b30d1939SAndy Fiddaman for (r = 0; arg[r]; r++)
4622*b30d1939SAndy Fiddaman if (!strcmp(arg[r], "remote"))
4623*b30d1939SAndy Fiddaman {
4624*b30d1939SAndy Fiddaman nowindow = 1;
4625*b30d1939SAndy Fiddaman break;
4626*b30d1939SAndy Fiddaman }
4627*b30d1939SAndy Fiddaman sh = 0;
4628*b30d1939SAndy Fiddaman for (a = cmd; *a && *a != ' '; a++)
4629*b30d1939SAndy Fiddaman if (a[0] == '.' && a[1] == 's' && a[2] == 'h' && (!a[3] || a[3] == ' '))
4630*b30d1939SAndy Fiddaman {
4631*b30d1939SAndy Fiddaman sh = 1;
4632*b30d1939SAndy Fiddaman break;
4633*b30d1939SAndy Fiddaman }
4634*b30d1939SAndy Fiddaman b = buf;
4635*b30d1939SAndy Fiddaman e = buf + sizeof(buf) - 1;
4636*b30d1939SAndy Fiddaman if (sh || arg)
4637*b30d1939SAndy Fiddaman {
4638*b30d1939SAndy Fiddaman if (sh)
4639*b30d1939SAndy Fiddaman {
4640*b30d1939SAndy Fiddaman b = copy(b, "ksh.exe ", e);
4641*b30d1939SAndy Fiddaman if (*cmd && *cmd != '/')
4642*b30d1939SAndy Fiddaman b = copy(b, "./", e);
4643*b30d1939SAndy Fiddaman }
4644*b30d1939SAndy Fiddaman b = copy(b, cmd, e);
4645*b30d1939SAndy Fiddaman while (a = *arg++)
4646*b30d1939SAndy Fiddaman {
4647*b30d1939SAndy Fiddaman if ((e - b) < 3)
4648*b30d1939SAndy Fiddaman break;
4649*b30d1939SAndy Fiddaman b = copy(b, " \"", e);
4650*b30d1939SAndy Fiddaman b = copy(b, a, e);
4651*b30d1939SAndy Fiddaman b = copy(b, "\"", e);
4652*b30d1939SAndy Fiddaman }
4653*b30d1939SAndy Fiddaman }
4654*b30d1939SAndy Fiddaman if (operands)
4655*b30d1939SAndy Fiddaman {
4656*b30d1939SAndy Fiddaman if (b == buf)
4657*b30d1939SAndy Fiddaman b = copy(b, cmd, e);
4658*b30d1939SAndy Fiddaman b = copy(b, " -- ", e);
4659*b30d1939SAndy Fiddaman b = copy(b, operands, e);
4660*b30d1939SAndy Fiddaman }
4661*b30d1939SAndy Fiddaman if (b > buf)
4662*b30d1939SAndy Fiddaman {
4663*b30d1939SAndy Fiddaman *b = 0;
4664*b30d1939SAndy Fiddaman cmd = (const char*)buf;
4665*b30d1939SAndy Fiddaman }
4666*b30d1939SAndy Fiddaman r = sear_system(cmd, nowindow);
4667*b30d1939SAndy Fiddaman }
4668*b30d1939SAndy Fiddaman else
4669*b30d1939SAndy Fiddaman r = code;
4670*b30d1939SAndy Fiddaman if (code >= 0)
4671*b30d1939SAndy Fiddaman sear_rm_r(sear_tmp);
4672*b30d1939SAndy Fiddaman }
4673*b30d1939SAndy Fiddaman else
4674*b30d1939SAndy Fiddaman r = cmd ? 0 : code;
4675*b30d1939SAndy Fiddaman return r;
4676*b30d1939SAndy Fiddaman }
4677*b30d1939SAndy Fiddaman
4678*b30d1939SAndy Fiddaman #else
4679*b30d1939SAndy Fiddaman
4680*b30d1939SAndy Fiddaman #define EXIT(n) return(n)
4681*b30d1939SAndy Fiddaman
4682*b30d1939SAndy Fiddaman #endif
4683*b30d1939SAndy Fiddaman
4684*b30d1939SAndy Fiddaman int
main(argc,argv)4685*b30d1939SAndy Fiddaman main(argc, argv)
4686*b30d1939SAndy Fiddaman int argc;
4687*b30d1939SAndy Fiddaman char** argv;
4688*b30d1939SAndy Fiddaman {
4689*b30d1939SAndy Fiddaman register int c;
4690*b30d1939SAndy Fiddaman register char* s;
4691*b30d1939SAndy Fiddaman register char* t;
4692*b30d1939SAndy Fiddaman register char* e;
4693*b30d1939SAndy Fiddaman unsigned long n;
4694*b30d1939SAndy Fiddaman unsigned long m;
4695*b30d1939SAndy Fiddaman const unsigned char* a2x;
4696*b30d1939SAndy Fiddaman int clear;
4697*b30d1939SAndy Fiddaman int list;
4698*b30d1939SAndy Fiddaman int local;
4699*b30d1939SAndy Fiddaman int meter;
4700*b30d1939SAndy Fiddaman int unzip;
4701*b30d1939SAndy Fiddaman int verbose;
4702*b30d1939SAndy Fiddaman unsigned int mode;
4703*b30d1939SAndy Fiddaman unsigned long total;
4704*b30d1939SAndy Fiddaman off_t pos;
4705*b30d1939SAndy Fiddaman gzFile gz;
4706*b30d1939SAndy Fiddaman FILE* fp;
4707*b30d1939SAndy Fiddaman Header_t header;
4708*b30d1939SAndy Fiddaman unsigned char num[4];
4709*b30d1939SAndy Fiddaman char path[sizeof(header.prefix) + sizeof(header.name) + 4];
4710*b30d1939SAndy Fiddaman char buf[sizeof(header)];
4711*b30d1939SAndy Fiddaman #if defined(_SEAR_OPTS)
4712*b30d1939SAndy Fiddaman char* opts[4];
4713*b30d1939SAndy Fiddaman #endif
4714*b30d1939SAndy Fiddaman
4715*b30d1939SAndy Fiddaman #if defined(_SEAR_EXEC) || defined(_SEAR_SEEK)
4716*b30d1939SAndy Fiddaman int install = 1;
4717*b30d1939SAndy Fiddaman #endif
4718*b30d1939SAndy Fiddaman
4719*b30d1939SAndy Fiddaman setmode(0, O_BINARY);
4720*b30d1939SAndy Fiddaman setmode(1, O_BINARY);
4721*b30d1939SAndy Fiddaman clear = 0;
4722*b30d1939SAndy Fiddaman list = 0;
4723*b30d1939SAndy Fiddaman local = 0;
4724*b30d1939SAndy Fiddaman meter = 0;
4725*b30d1939SAndy Fiddaman unzip = 0;
4726*b30d1939SAndy Fiddaman verbose = 0;
4727*b30d1939SAndy Fiddaman if (s = *argv)
4728*b30d1939SAndy Fiddaman {
4729*b30d1939SAndy Fiddaman t = s;
4730*b30d1939SAndy Fiddaman while (*s)
4731*b30d1939SAndy Fiddaman if (*s++ == '/')
4732*b30d1939SAndy Fiddaman t = s;
4733*b30d1939SAndy Fiddaman if (!strcmp(t, "gunzip"))
4734*b30d1939SAndy Fiddaman unzip = 1;
4735*b30d1939SAndy Fiddaman state.id = t;
4736*b30d1939SAndy Fiddaman }
4737*b30d1939SAndy Fiddaman else
4738*b30d1939SAndy Fiddaman state.id = "ratz";
4739*b30d1939SAndy Fiddaman switch ('~')
4740*b30d1939SAndy Fiddaman {
4741*b30d1939SAndy Fiddaman case 0241:
4742*b30d1939SAndy Fiddaman switch ('\n')
4743*b30d1939SAndy Fiddaman {
4744*b30d1939SAndy Fiddaman case 0025:
4745*b30d1939SAndy Fiddaman a2x = a2o;
4746*b30d1939SAndy Fiddaman break;
4747*b30d1939SAndy Fiddaman default:
4748*b30d1939SAndy Fiddaman a2x = a2e;
4749*b30d1939SAndy Fiddaman break;
4750*b30d1939SAndy Fiddaman }
4751*b30d1939SAndy Fiddaman break;
4752*b30d1939SAndy Fiddaman case 0137:
4753*b30d1939SAndy Fiddaman a2x = a2i;
4754*b30d1939SAndy Fiddaman break;
4755*b30d1939SAndy Fiddaman default:
4756*b30d1939SAndy Fiddaman a2x = 0;
4757*b30d1939SAndy Fiddaman break;
4758*b30d1939SAndy Fiddaman }
4759*b30d1939SAndy Fiddaman #if defined(_SEAR_OPTS)
4760*b30d1939SAndy Fiddaman opts[0] = argv[0];
4761*b30d1939SAndy Fiddaman opts[1] = _SEAR_OPTS;
4762*b30d1939SAndy Fiddaman opts[2] = argv[1];
4763*b30d1939SAndy Fiddaman opts[3] = 0;
4764*b30d1939SAndy Fiddaman argv = opts;
4765*b30d1939SAndy Fiddaman #endif
4766*b30d1939SAndy Fiddaman #if _PACKAGE_ast
4767*b30d1939SAndy Fiddaman error_info.id = state.id;
4768*b30d1939SAndy Fiddaman for (;;)
4769*b30d1939SAndy Fiddaman {
4770*b30d1939SAndy Fiddaman switch (optget(argv, usage))
4771*b30d1939SAndy Fiddaman {
4772*b30d1939SAndy Fiddaman case 'c':
4773*b30d1939SAndy Fiddaman unzip = 1;
4774*b30d1939SAndy Fiddaman continue;
4775*b30d1939SAndy Fiddaman #if defined(_SEAR_EXEC) || defined(_SEAR_SEEK)
4776*b30d1939SAndy Fiddaman case 'i':
4777*b30d1939SAndy Fiddaman install = 0;
4778*b30d1939SAndy Fiddaman continue;
4779*b30d1939SAndy Fiddaman case 'k':
4780*b30d1939SAndy Fiddaman install = -1;
4781*b30d1939SAndy Fiddaman continue;
4782*b30d1939SAndy Fiddaman #endif
4783*b30d1939SAndy Fiddaman case 'l':
4784*b30d1939SAndy Fiddaman local = 1;
4785*b30d1939SAndy Fiddaman continue;
4786*b30d1939SAndy Fiddaman case 'm':
4787*b30d1939SAndy Fiddaman meter = 1;
4788*b30d1939SAndy Fiddaman continue;
4789*b30d1939SAndy Fiddaman case 'n':
4790*b30d1939SAndy Fiddaman a2x = 0;
4791*b30d1939SAndy Fiddaman continue;
4792*b30d1939SAndy Fiddaman case 't':
4793*b30d1939SAndy Fiddaman list = 1;
4794*b30d1939SAndy Fiddaman continue;
4795*b30d1939SAndy Fiddaman case 'v':
4796*b30d1939SAndy Fiddaman verbose = 1;
4797*b30d1939SAndy Fiddaman continue;
4798*b30d1939SAndy Fiddaman case 'V':
4799*b30d1939SAndy Fiddaman sfprintf(sfstdout, "%s\n", id + 10);
4800*b30d1939SAndy Fiddaman return 0;
4801*b30d1939SAndy Fiddaman case '?':
4802*b30d1939SAndy Fiddaman error(ERROR_USAGE|4, "%s", opt_info.arg);
4803*b30d1939SAndy Fiddaman continue;
4804*b30d1939SAndy Fiddaman case ':':
4805*b30d1939SAndy Fiddaman error(2, "%s", opt_info.arg);
4806*b30d1939SAndy Fiddaman continue;
4807*b30d1939SAndy Fiddaman }
4808*b30d1939SAndy Fiddaman break;
4809*b30d1939SAndy Fiddaman }
4810*b30d1939SAndy Fiddaman if (error_info.errors)
4811*b30d1939SAndy Fiddaman error(ERROR_USAGE|4, "%s", optusage(NiL));
4812*b30d1939SAndy Fiddaman argv += opt_info.index;
4813*b30d1939SAndy Fiddaman #else
4814*b30d1939SAndy Fiddaman while ((s = *++argv) && *s == '-' && *(s + 1))
4815*b30d1939SAndy Fiddaman {
4816*b30d1939SAndy Fiddaman if (*(s + 1) == '-')
4817*b30d1939SAndy Fiddaman {
4818*b30d1939SAndy Fiddaman if (!*(s + 2))
4819*b30d1939SAndy Fiddaman {
4820*b30d1939SAndy Fiddaman argv++;
4821*b30d1939SAndy Fiddaman break;
4822*b30d1939SAndy Fiddaman }
4823*b30d1939SAndy Fiddaman usage();
4824*b30d1939SAndy Fiddaman break;
4825*b30d1939SAndy Fiddaman }
4826*b30d1939SAndy Fiddaman for (;;)
4827*b30d1939SAndy Fiddaman {
4828*b30d1939SAndy Fiddaman switch (c = *++s)
4829*b30d1939SAndy Fiddaman {
4830*b30d1939SAndy Fiddaman case 0:
4831*b30d1939SAndy Fiddaman break;
4832*b30d1939SAndy Fiddaman case 'c':
4833*b30d1939SAndy Fiddaman unzip = 1;
4834*b30d1939SAndy Fiddaman continue;
4835*b30d1939SAndy Fiddaman #if defined(_SEAR_EXEC) || defined(_SEAR_SEEK)
4836*b30d1939SAndy Fiddaman case 'i':
4837*b30d1939SAndy Fiddaman install = 0;
4838*b30d1939SAndy Fiddaman continue;
4839*b30d1939SAndy Fiddaman case 'k':
4840*b30d1939SAndy Fiddaman install = -1;
4841*b30d1939SAndy Fiddaman continue;
4842*b30d1939SAndy Fiddaman #endif
4843*b30d1939SAndy Fiddaman case 'l':
4844*b30d1939SAndy Fiddaman local = 1;
4845*b30d1939SAndy Fiddaman continue;
4846*b30d1939SAndy Fiddaman case 'm':
4847*b30d1939SAndy Fiddaman meter = 1;
4848*b30d1939SAndy Fiddaman continue;
4849*b30d1939SAndy Fiddaman case 'n':
4850*b30d1939SAndy Fiddaman a2x = 0;
4851*b30d1939SAndy Fiddaman continue;
4852*b30d1939SAndy Fiddaman case 't':
4853*b30d1939SAndy Fiddaman list = 1;
4854*b30d1939SAndy Fiddaman continue;
4855*b30d1939SAndy Fiddaman case 'v':
4856*b30d1939SAndy Fiddaman verbose = 1;
4857*b30d1939SAndy Fiddaman continue;
4858*b30d1939SAndy Fiddaman case 'V':
4859*b30d1939SAndy Fiddaman fprintf(stdout, "%s\n", id + 10);
4860*b30d1939SAndy Fiddaman return 0;
4861*b30d1939SAndy Fiddaman default:
4862*b30d1939SAndy Fiddaman fprintf(stderr, "%s: -%c: unknown option\n", state.id, c);
4863*b30d1939SAndy Fiddaman /*FALLTHROUGH*/
4864*b30d1939SAndy Fiddaman case '?':
4865*b30d1939SAndy Fiddaman usage();
4866*b30d1939SAndy Fiddaman break;
4867*b30d1939SAndy Fiddaman }
4868*b30d1939SAndy Fiddaman break;
4869*b30d1939SAndy Fiddaman }
4870*b30d1939SAndy Fiddaman }
4871*b30d1939SAndy Fiddaman #endif
4872*b30d1939SAndy Fiddaman
4873*b30d1939SAndy Fiddaman #if defined(_SEAR_SEEK)
4874*b30d1939SAndy Fiddaman if (sear_seek((off_t)_SEAR_SEEK, install && !list))
4875*b30d1939SAndy Fiddaman {
4876*b30d1939SAndy Fiddaman Sleep(2 * 1000);
4877*b30d1939SAndy Fiddaman return 1;
4878*b30d1939SAndy Fiddaman }
4879*b30d1939SAndy Fiddaman #endif
4880*b30d1939SAndy Fiddaman
4881*b30d1939SAndy Fiddaman /*
4882*b30d1939SAndy Fiddaman * commit on the first gzip magic char
4883*b30d1939SAndy Fiddaman */
4884*b30d1939SAndy Fiddaman
4885*b30d1939SAndy Fiddaman if ((c = getchar()) == EOF)
4886*b30d1939SAndy Fiddaman EXIT(0);
4887*b30d1939SAndy Fiddaman ungetc(c, stdin);
4888*b30d1939SAndy Fiddaman if (c != gz_magic[0])
4889*b30d1939SAndy Fiddaman gz = 0;
4890*b30d1939SAndy Fiddaman else if (!(gz = gzfopen(stdin, FOPEN_READ)))
4891*b30d1939SAndy Fiddaman {
4892*b30d1939SAndy Fiddaman fprintf(stderr, "%s: gunzip open error\n", state.id);
4893*b30d1939SAndy Fiddaman EXIT(1);
4894*b30d1939SAndy Fiddaman }
4895*b30d1939SAndy Fiddaman if (unzip)
4896*b30d1939SAndy Fiddaman {
4897*b30d1939SAndy Fiddaman if (!gz)
4898*b30d1939SAndy Fiddaman {
4899*b30d1939SAndy Fiddaman fprintf(stderr, "%s: not a gzip file\n", state.id);
4900*b30d1939SAndy Fiddaman EXIT(1);
4901*b30d1939SAndy Fiddaman }
4902*b30d1939SAndy Fiddaman while ((c = gzread(gz, buf, sizeof(buf))) > 0)
4903*b30d1939SAndy Fiddaman if (fwrite(buf, c, 1, stdout) != 1)
4904*b30d1939SAndy Fiddaman {
4905*b30d1939SAndy Fiddaman fprintf(stderr, "%s: write error\n", state.id);
4906*b30d1939SAndy Fiddaman EXIT(1);
4907*b30d1939SAndy Fiddaman }
4908*b30d1939SAndy Fiddaman if (c < 0)
4909*b30d1939SAndy Fiddaman {
4910*b30d1939SAndy Fiddaman fprintf(stderr, "%s: read error\n", state.id);
4911*b30d1939SAndy Fiddaman EXIT(1);
4912*b30d1939SAndy Fiddaman }
4913*b30d1939SAndy Fiddaman if (fflush(stdout))
4914*b30d1939SAndy Fiddaman {
4915*b30d1939SAndy Fiddaman fprintf(stderr, "%s: flush error\n", state.id);
4916*b30d1939SAndy Fiddaman EXIT(1);
4917*b30d1939SAndy Fiddaman }
4918*b30d1939SAndy Fiddaman EXIT(0);
4919*b30d1939SAndy Fiddaman }
4920*b30d1939SAndy Fiddaman if (meter)
4921*b30d1939SAndy Fiddaman {
4922*b30d1939SAndy Fiddaman if ((pos = lseek(0, (off_t)0, SEEK_CUR)) < 0)
4923*b30d1939SAndy Fiddaman meter = 0;
4924*b30d1939SAndy Fiddaman else
4925*b30d1939SAndy Fiddaman {
4926*b30d1939SAndy Fiddaman if (lseek(0, (off_t)(-4), SEEK_END) < 0 || read(0, num, 4) != 4)
4927*b30d1939SAndy Fiddaman meter = 0;
4928*b30d1939SAndy Fiddaman else if (!(total = ((num[0]|(num[1]<<8)|(num[2]<<16)|(num[3]<<24)) + sizeof(Header_t) - 1) / sizeof(Header_t)))
4929*b30d1939SAndy Fiddaman total = 1;
4930*b30d1939SAndy Fiddaman lseek(0, pos, SEEK_SET);
4931*b30d1939SAndy Fiddaman }
4932*b30d1939SAndy Fiddaman }
4933*b30d1939SAndy Fiddaman
4934*b30d1939SAndy Fiddaman /*
4935*b30d1939SAndy Fiddaman * loop on all the header blocks
4936*b30d1939SAndy Fiddaman */
4937*b30d1939SAndy Fiddaman
4938*b30d1939SAndy Fiddaman while (block(stdin, gz, (char*)&header))
4939*b30d1939SAndy Fiddaman {
4940*b30d1939SAndy Fiddaman /*
4941*b30d1939SAndy Fiddaman * last 2 blocks are NUL
4942*b30d1939SAndy Fiddaman */
4943*b30d1939SAndy Fiddaman
4944*b30d1939SAndy Fiddaman if (!*header.name)
4945*b30d1939SAndy Fiddaman break;
4946*b30d1939SAndy Fiddaman
4947*b30d1939SAndy Fiddaman /*
4948*b30d1939SAndy Fiddaman * verify the checksum
4949*b30d1939SAndy Fiddaman */
4950*b30d1939SAndy Fiddaman
4951*b30d1939SAndy Fiddaman s = header.chksum;
4952*b30d1939SAndy Fiddaman e = header.chksum + sizeof(header.chksum);
4953*b30d1939SAndy Fiddaman if (a2x)
4954*b30d1939SAndy Fiddaman {
4955*b30d1939SAndy Fiddaman for (; s < e; s++)
4956*b30d1939SAndy Fiddaman *s = a2x[*(unsigned char*)s];
4957*b30d1939SAndy Fiddaman s = header.chksum;
4958*b30d1939SAndy Fiddaman }
4959*b30d1939SAndy Fiddaman n = number(s) & TAR_SUMASK;
4960*b30d1939SAndy Fiddaman while (s < e)
4961*b30d1939SAndy Fiddaman *s++ = 040;
4962*b30d1939SAndy Fiddaman m = 0;
4963*b30d1939SAndy Fiddaman s = (char*)&header;
4964*b30d1939SAndy Fiddaman e = (char*)&header + sizeof(header);
4965*b30d1939SAndy Fiddaman while (s < e)
4966*b30d1939SAndy Fiddaman m += *(unsigned char*)s++;
4967*b30d1939SAndy Fiddaman m &= TAR_SUMASK;
4968*b30d1939SAndy Fiddaman if (m != n)
4969*b30d1939SAndy Fiddaman {
4970*b30d1939SAndy Fiddaman if (state.files)
4971*b30d1939SAndy Fiddaman fprintf(stderr, "%s: archive corrupted\n", state.id);
4972*b30d1939SAndy Fiddaman else
4973*b30d1939SAndy Fiddaman fprintf(stderr, "%s: not a tar archive\n", state.id);
4974*b30d1939SAndy Fiddaman fprintf(stderr, "check sum %lu != %lu\n", m, n);
4975*b30d1939SAndy Fiddaman EXIT(1);
4976*b30d1939SAndy Fiddaman }
4977*b30d1939SAndy Fiddaman
4978*b30d1939SAndy Fiddaman /*
4979*b30d1939SAndy Fiddaman * convert to the native charset
4980*b30d1939SAndy Fiddaman */
4981*b30d1939SAndy Fiddaman
4982*b30d1939SAndy Fiddaman if (a2x)
4983*b30d1939SAndy Fiddaman for (e = (s = (char*)&header) + sizeof(header); s < e; s++)
4984*b30d1939SAndy Fiddaman *s = a2x[*(unsigned char*)s];
4985*b30d1939SAndy Fiddaman
4986*b30d1939SAndy Fiddaman /*
4987*b30d1939SAndy Fiddaman * get the pathname, type and size
4988*b30d1939SAndy Fiddaman */
4989*b30d1939SAndy Fiddaman
4990*b30d1939SAndy Fiddaman state.files++;
4991*b30d1939SAndy Fiddaman t = path;
4992*b30d1939SAndy Fiddaman if (!strncmp(header.magic, TMAGIC, sizeof(header.magic)) && *header.prefix)
4993*b30d1939SAndy Fiddaman {
4994*b30d1939SAndy Fiddaman s = header.prefix;
4995*b30d1939SAndy Fiddaman e = header.prefix + sizeof(header.prefix);
4996*b30d1939SAndy Fiddaman while (s < e && (c = *s++))
4997*b30d1939SAndy Fiddaman *t++ = c;
4998*b30d1939SAndy Fiddaman *t++ = '/';
4999*b30d1939SAndy Fiddaman }
5000*b30d1939SAndy Fiddaman s = header.name;
5001*b30d1939SAndy Fiddaman e = header.name + sizeof(header.name);
5002*b30d1939SAndy Fiddaman while (s < e && (c = *s++))
5003*b30d1939SAndy Fiddaman *t++ = c;
5004*b30d1939SAndy Fiddaman *t = 0;
5005*b30d1939SAndy Fiddaman
5006*b30d1939SAndy Fiddaman /*
5007*b30d1939SAndy Fiddaman * verify the dir prefix
5008*b30d1939SAndy Fiddaman */
5009*b30d1939SAndy Fiddaman
5010*b30d1939SAndy Fiddaman t = 0;
5011*b30d1939SAndy Fiddaman s = path;
5012*b30d1939SAndy Fiddaman while (*s)
5013*b30d1939SAndy Fiddaman if (*s++ == '/')
5014*b30d1939SAndy Fiddaman t = s;
5015*b30d1939SAndy Fiddaman if (t)
5016*b30d1939SAndy Fiddaman {
5017*b30d1939SAndy Fiddaman *--t = 0;
5018*b30d1939SAndy Fiddaman if (!list && access(path, 0))
5019*b30d1939SAndy Fiddaman {
5020*b30d1939SAndy Fiddaman s = path;
5021*b30d1939SAndy Fiddaman do
5022*b30d1939SAndy Fiddaman {
5023*b30d1939SAndy Fiddaman if (!(c = *s) || c == '/')
5024*b30d1939SAndy Fiddaman {
5025*b30d1939SAndy Fiddaman *s = 0;
5026*b30d1939SAndy Fiddaman if (access(path, 0) && mkdir(path, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH))
5027*b30d1939SAndy Fiddaman {
5028*b30d1939SAndy Fiddaman fprintf(stderr, "%s: %s: cannot create directory\n", state.id, path);
5029*b30d1939SAndy Fiddaman EXIT(1);
5030*b30d1939SAndy Fiddaman }
5031*b30d1939SAndy Fiddaman *s = c;
5032*b30d1939SAndy Fiddaman }
5033*b30d1939SAndy Fiddaman } while (*s++);
5034*b30d1939SAndy Fiddaman }
5035*b30d1939SAndy Fiddaman if (*(t + 1))
5036*b30d1939SAndy Fiddaman *t = '/';
5037*b30d1939SAndy Fiddaman else
5038*b30d1939SAndy Fiddaman header.typeflag = DIRTYPE;
5039*b30d1939SAndy Fiddaman }
5040*b30d1939SAndy Fiddaman
5041*b30d1939SAndy Fiddaman /*
5042*b30d1939SAndy Fiddaman * check for non-local paths
5043*b30d1939SAndy Fiddaman */
5044*b30d1939SAndy Fiddaman
5045*b30d1939SAndy Fiddaman if (local && (path[0] == '/' || path[0] == '.' && path[1] == '.' && (!path[2] || path[2] == '/')))
5046*b30d1939SAndy Fiddaman {
5047*b30d1939SAndy Fiddaman fprintf(stderr, "%s: %s: non-local path rejected", state.id, path);
5048*b30d1939SAndy Fiddaman if ((header.typeflag == REGTYPE || header.typeflag == AREGTYPE) && (n = number(header.size)))
5049*b30d1939SAndy Fiddaman while (n > 0)
5050*b30d1939SAndy Fiddaman {
5051*b30d1939SAndy Fiddaman if (!block(stdin, gz, buf))
5052*b30d1939SAndy Fiddaman {
5053*b30d1939SAndy Fiddaman fprintf(stderr, "%s: unexpected EOF\n", state.id);
5054*b30d1939SAndy Fiddaman EXIT(1);
5055*b30d1939SAndy Fiddaman }
5056*b30d1939SAndy Fiddaman if (n <= sizeof(header))
5057*b30d1939SAndy Fiddaman break;
5058*b30d1939SAndy Fiddaman n -= sizeof(header);
5059*b30d1939SAndy Fiddaman }
5060*b30d1939SAndy Fiddaman continue;
5061*b30d1939SAndy Fiddaman }
5062*b30d1939SAndy Fiddaman
5063*b30d1939SAndy Fiddaman /*
5064*b30d1939SAndy Fiddaman * create and grab the data
5065*b30d1939SAndy Fiddaman */
5066*b30d1939SAndy Fiddaman
5067*b30d1939SAndy Fiddaman n = number(header.mode);
5068*b30d1939SAndy Fiddaman mode = 0;
5069*b30d1939SAndy Fiddaman if (n & TUREAD)
5070*b30d1939SAndy Fiddaman mode |= S_IRUSR;
5071*b30d1939SAndy Fiddaman if (n & TUWRITE)
5072*b30d1939SAndy Fiddaman mode |= S_IWUSR;
5073*b30d1939SAndy Fiddaman if (n & TUEXEC)
5074*b30d1939SAndy Fiddaman mode |= S_IXUSR;
5075*b30d1939SAndy Fiddaman if (n & TGREAD)
5076*b30d1939SAndy Fiddaman mode |= S_IRGRP;
5077*b30d1939SAndy Fiddaman if (n & TGWRITE)
5078*b30d1939SAndy Fiddaman mode |= S_IWGRP;
5079*b30d1939SAndy Fiddaman if (n & TGEXEC)
5080*b30d1939SAndy Fiddaman mode |= S_IXGRP;
5081*b30d1939SAndy Fiddaman if (n & TOREAD)
5082*b30d1939SAndy Fiddaman mode |= S_IROTH;
5083*b30d1939SAndy Fiddaman if (n & TOWRITE)
5084*b30d1939SAndy Fiddaman mode |= S_IWOTH;
5085*b30d1939SAndy Fiddaman if (n & TOEXEC)
5086*b30d1939SAndy Fiddaman mode |= S_IXOTH;
5087*b30d1939SAndy Fiddaman if (list || meter)
5088*b30d1939SAndy Fiddaman {
5089*b30d1939SAndy Fiddaman if (meter)
5090*b30d1939SAndy Fiddaman {
5091*b30d1939SAndy Fiddaman int i;
5092*b30d1939SAndy Fiddaman int j;
5093*b30d1939SAndy Fiddaman int k;
5094*b30d1939SAndy Fiddaman int n;
5095*b30d1939SAndy Fiddaman int p;
5096*b30d1939SAndy Fiddaman char bar[METER_parts + 1];
5097*b30d1939SAndy Fiddaman
5098*b30d1939SAndy Fiddaman for (s = path; *s; s++)
5099*b30d1939SAndy Fiddaman if (s[0] == ' ' && s[1] == '-' && s[2] == '-' && s[3] == ' ')
5100*b30d1939SAndy Fiddaman break;
5101*b30d1939SAndy Fiddaman if (*s)
5102*b30d1939SAndy Fiddaman {
5103*b30d1939SAndy Fiddaman if (clear)
5104*b30d1939SAndy Fiddaman {
5105*b30d1939SAndy Fiddaman fprintf(stderr, "%*s", clear, "\r");
5106*b30d1939SAndy Fiddaman clear = 0;
5107*b30d1939SAndy Fiddaman }
5108*b30d1939SAndy Fiddaman fprintf(stderr, "\n%s\n\n", path);
5109*b30d1939SAndy Fiddaman }
5110*b30d1939SAndy Fiddaman else
5111*b30d1939SAndy Fiddaman {
5112*b30d1939SAndy Fiddaman n = (int)strlen(s = path);
5113*b30d1939SAndy Fiddaman p = (state.blocks * 100) / total;
5114*b30d1939SAndy Fiddaman if (n > (METER_width - METER_parts - 1))
5115*b30d1939SAndy Fiddaman {
5116*b30d1939SAndy Fiddaman s += n - (METER_width - METER_parts - 1);
5117*b30d1939SAndy Fiddaman n = METER_width - METER_parts - 1;
5118*b30d1939SAndy Fiddaman }
5119*b30d1939SAndy Fiddaman j = n + METER_parts + 2;
5120*b30d1939SAndy Fiddaman if (!clear)
5121*b30d1939SAndy Fiddaman clear = j + 5;
5122*b30d1939SAndy Fiddaman if ((k = clear - j - 5) < 0)
5123*b30d1939SAndy Fiddaman k = 0;
5124*b30d1939SAndy Fiddaman if ((i = (p / (100 / METER_parts))) >= sizeof(bar))
5125*b30d1939SAndy Fiddaman i = sizeof(bar) - 1;
5126*b30d1939SAndy Fiddaman n = 0;
5127*b30d1939SAndy Fiddaman while (n < i)
5128*b30d1939SAndy Fiddaman bar[n++] = '*';
5129*b30d1939SAndy Fiddaman while (n < sizeof(bar) - 1)
5130*b30d1939SAndy Fiddaman bar[n++] = ' ';
5131*b30d1939SAndy Fiddaman bar[n] = 0;
5132*b30d1939SAndy Fiddaman clear = fprintf(stderr, "%02d%% |%s| %s%*s", p, bar, s, k, "\r");
5133*b30d1939SAndy Fiddaman }
5134*b30d1939SAndy Fiddaman }
5135*b30d1939SAndy Fiddaman else
5136*b30d1939SAndy Fiddaman {
5137*b30d1939SAndy Fiddaman if (verbose)
5138*b30d1939SAndy Fiddaman {
5139*b30d1939SAndy Fiddaman switch (header.typeflag)
5140*b30d1939SAndy Fiddaman {
5141*b30d1939SAndy Fiddaman case REGTYPE:
5142*b30d1939SAndy Fiddaman case AREGTYPE:
5143*b30d1939SAndy Fiddaman c = '-';
5144*b30d1939SAndy Fiddaman break;
5145*b30d1939SAndy Fiddaman case DIRTYPE:
5146*b30d1939SAndy Fiddaman c = 'd';
5147*b30d1939SAndy Fiddaman break;
5148*b30d1939SAndy Fiddaman case LNKTYPE:
5149*b30d1939SAndy Fiddaman c = 'h';
5150*b30d1939SAndy Fiddaman break;
5151*b30d1939SAndy Fiddaman case SYMTYPE:
5152*b30d1939SAndy Fiddaman c = 'l';
5153*b30d1939SAndy Fiddaman break;
5154*b30d1939SAndy Fiddaman default:
5155*b30d1939SAndy Fiddaman c = '?';
5156*b30d1939SAndy Fiddaman break;
5157*b30d1939SAndy Fiddaman }
5158*b30d1939SAndy Fiddaman printf("%c", c);
5159*b30d1939SAndy Fiddaman m = 0400;
5160*b30d1939SAndy Fiddaman while (m)
5161*b30d1939SAndy Fiddaman {
5162*b30d1939SAndy Fiddaman printf("%c", (n & m) ? 'r' : '-');
5163*b30d1939SAndy Fiddaman m >>= 1;
5164*b30d1939SAndy Fiddaman printf("%c", (n & m) ? 'w' : '-');
5165*b30d1939SAndy Fiddaman m >>= 1;
5166*b30d1939SAndy Fiddaman printf("%c", (n & m) ? 'x' : '-');
5167*b30d1939SAndy Fiddaman m >>= 1;
5168*b30d1939SAndy Fiddaman }
5169*b30d1939SAndy Fiddaman printf(" %10lu ", number(header.size));
5170*b30d1939SAndy Fiddaman }
5171*b30d1939SAndy Fiddaman switch (header.typeflag)
5172*b30d1939SAndy Fiddaman {
5173*b30d1939SAndy Fiddaman case LNKTYPE:
5174*b30d1939SAndy Fiddaman printf("%s == %s\n", path, header.linkname);
5175*b30d1939SAndy Fiddaman break;
5176*b30d1939SAndy Fiddaman case SYMTYPE:
5177*b30d1939SAndy Fiddaman printf("%s => %s\n", path, header.linkname);
5178*b30d1939SAndy Fiddaman break;
5179*b30d1939SAndy Fiddaman default:
5180*b30d1939SAndy Fiddaman printf("%s\n", path);
5181*b30d1939SAndy Fiddaman break;
5182*b30d1939SAndy Fiddaman }
5183*b30d1939SAndy Fiddaman }
5184*b30d1939SAndy Fiddaman if (list)
5185*b30d1939SAndy Fiddaman {
5186*b30d1939SAndy Fiddaman if (skip(stdin, gz, buf, number(header.size)))
5187*b30d1939SAndy Fiddaman EXIT(1);
5188*b30d1939SAndy Fiddaman continue;
5189*b30d1939SAndy Fiddaman }
5190*b30d1939SAndy Fiddaman }
5191*b30d1939SAndy Fiddaman else if (verbose)
5192*b30d1939SAndy Fiddaman printf("%s\n", path);
5193*b30d1939SAndy Fiddaman switch (header.typeflag)
5194*b30d1939SAndy Fiddaman {
5195*b30d1939SAndy Fiddaman case REGTYPE:
5196*b30d1939SAndy Fiddaman case AREGTYPE:
5197*b30d1939SAndy Fiddaman while (!(fp = fopen(path, FOPEN_WRITE)))
5198*b30d1939SAndy Fiddaman if (unlink(path))
5199*b30d1939SAndy Fiddaman {
5200*b30d1939SAndy Fiddaman fprintf(stderr, "%s: warning: %s: cannot create file\n", state.id, path);
5201*b30d1939SAndy Fiddaman break;
5202*b30d1939SAndy Fiddaman }
5203*b30d1939SAndy Fiddaman n = number(header.size);
5204*b30d1939SAndy Fiddaman c = a2x ? 0 : -1;
5205*b30d1939SAndy Fiddaman while (n > 0)
5206*b30d1939SAndy Fiddaman {
5207*b30d1939SAndy Fiddaman if (!block(stdin, gz, buf))
5208*b30d1939SAndy Fiddaman {
5209*b30d1939SAndy Fiddaman fprintf(stderr, "%s: unexpected EOF\n", state.id);
5210*b30d1939SAndy Fiddaman EXIT(1);
5211*b30d1939SAndy Fiddaman }
5212*b30d1939SAndy Fiddaman switch (c)
5213*b30d1939SAndy Fiddaman {
5214*b30d1939SAndy Fiddaman case 0:
5215*b30d1939SAndy Fiddaman if ((m = n) < 4)
5216*b30d1939SAndy Fiddaman {
5217*b30d1939SAndy Fiddaman for (e = (s = buf) + m; s < e; s++)
5218*b30d1939SAndy Fiddaman if (a2x[*(unsigned char*)s] != '\n')
5219*b30d1939SAndy Fiddaman break;
5220*b30d1939SAndy Fiddaman }
5221*b30d1939SAndy Fiddaman else
5222*b30d1939SAndy Fiddaman {
5223*b30d1939SAndy Fiddaman if (m > 256)
5224*b30d1939SAndy Fiddaman m = 256;
5225*b30d1939SAndy Fiddaman for (e = (s = buf) + m; s < e; s++)
5226*b30d1939SAndy Fiddaman if (!ascii_text[*(unsigned char*)s])
5227*b30d1939SAndy Fiddaman break;
5228*b30d1939SAndy Fiddaman }
5229*b30d1939SAndy Fiddaman if (s < e)
5230*b30d1939SAndy Fiddaman {
5231*b30d1939SAndy Fiddaman c = -1;
5232*b30d1939SAndy Fiddaman break;
5233*b30d1939SAndy Fiddaman }
5234*b30d1939SAndy Fiddaman c = 1;
5235*b30d1939SAndy Fiddaman /*FALLTHROUGH*/
5236*b30d1939SAndy Fiddaman case 1:
5237*b30d1939SAndy Fiddaman for (e = (s = buf) + sizeof(header); s < e; s++)
5238*b30d1939SAndy Fiddaman *s = a2x[*(unsigned char*)s];
5239*b30d1939SAndy Fiddaman break;
5240*b30d1939SAndy Fiddaman }
5241*b30d1939SAndy Fiddaman if (fp && fwrite(buf, n > sizeof(header) ? sizeof(header) : n, 1, fp) != 1)
5242*b30d1939SAndy Fiddaman {
5243*b30d1939SAndy Fiddaman fprintf(stderr, "%s: %s: write error\n", state.id, path);
5244*b30d1939SAndy Fiddaman EXIT(1);
5245*b30d1939SAndy Fiddaman }
5246*b30d1939SAndy Fiddaman if (n <= sizeof(header))
5247*b30d1939SAndy Fiddaman break;
5248*b30d1939SAndy Fiddaman n -= sizeof(header);
5249*b30d1939SAndy Fiddaman }
5250*b30d1939SAndy Fiddaman if (fp && fclose(fp))
5251*b30d1939SAndy Fiddaman {
5252*b30d1939SAndy Fiddaman fprintf(stderr, "%s: %s: write error\n", state.id, path);
5253*b30d1939SAndy Fiddaman EXIT(1);
5254*b30d1939SAndy Fiddaman }
5255*b30d1939SAndy Fiddaman break;
5256*b30d1939SAndy Fiddaman case DIRTYPE:
5257*b30d1939SAndy Fiddaman if (access(path, 0) && mkdir(path, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH))
5258*b30d1939SAndy Fiddaman {
5259*b30d1939SAndy Fiddaman fprintf(stderr, "%s: %s: cannot create directory\n", state.id, path);
5260*b30d1939SAndy Fiddaman EXIT(1);
5261*b30d1939SAndy Fiddaman }
5262*b30d1939SAndy Fiddaman break;
5263*b30d1939SAndy Fiddaman case SYMTYPE:
5264*b30d1939SAndy Fiddaman #if defined(S_IFLNK) || defined(S_ISLNK)
5265*b30d1939SAndy Fiddaman while (symlink(header.linkname, path))
5266*b30d1939SAndy Fiddaman if (unlink(path))
5267*b30d1939SAndy Fiddaman {
5268*b30d1939SAndy Fiddaman fprintf(stderr, "%s: %s: cannot symlink to %s\n", state.id, path, header.linkname);
5269*b30d1939SAndy Fiddaman EXIT(1);
5270*b30d1939SAndy Fiddaman }
5271*b30d1939SAndy Fiddaman continue;
5272*b30d1939SAndy Fiddaman #endif
5273*b30d1939SAndy Fiddaman #if !_WIN32 || _WINIX
5274*b30d1939SAndy Fiddaman case LNKTYPE:
5275*b30d1939SAndy Fiddaman while (link(header.linkname, path))
5276*b30d1939SAndy Fiddaman if (unlink(path))
5277*b30d1939SAndy Fiddaman {
5278*b30d1939SAndy Fiddaman fprintf(stderr, "%s: %s: cannot link to %s\n", state.id, path, header.linkname);
5279*b30d1939SAndy Fiddaman EXIT(1);
5280*b30d1939SAndy Fiddaman }
5281*b30d1939SAndy Fiddaman continue;
5282*b30d1939SAndy Fiddaman #endif
5283*b30d1939SAndy Fiddaman default:
5284*b30d1939SAndy Fiddaman fprintf(stderr, "%s: %s: file type %c ignored\n", state.id, path, header.typeflag);
5285*b30d1939SAndy Fiddaman if (skip(stdin, gz, buf, number(header.size)))
5286*b30d1939SAndy Fiddaman EXIT(1);
5287*b30d1939SAndy Fiddaman continue;
5288*b30d1939SAndy Fiddaman }
5289*b30d1939SAndy Fiddaman if (chmod(path, mode))
5290*b30d1939SAndy Fiddaman fprintf(stderr, "%s: %s: cannot change mode to %03o\n", state.id, path, mode);
5291*b30d1939SAndy Fiddaman }
5292*b30d1939SAndy Fiddaman if (clear)
5293*b30d1939SAndy Fiddaman fprintf(stderr, "%*s", clear, "\r");
5294*b30d1939SAndy Fiddaman if (!state.files)
5295*b30d1939SAndy Fiddaman fprintf(stderr, "%s: warning: empty archive\n", state.id);
5296*b30d1939SAndy Fiddaman else if (verbose)
5297*b30d1939SAndy Fiddaman fprintf(stderr, "%lu file%s, %lu block%s\n", state.files, state.files == 1 ? "" : "s", state.blocks, state.blocks == 1 ? "" : "s");
5298*b30d1939SAndy Fiddaman #if defined(_SEAR_EXEC)
5299*b30d1939SAndy Fiddaman #if !defined(_SEAR_ARGS)
5300*b30d1939SAndy Fiddaman #define _SEAR_ARGS 0
5301*b30d1939SAndy Fiddaman #endif
5302*b30d1939SAndy Fiddaman if (install && sear_exec(_SEAR_EXEC, argv, _SEAR_ARGS, install))
5303*b30d1939SAndy Fiddaman {
5304*b30d1939SAndy Fiddaman Sleep(2 * 1000);
5305*b30d1939SAndy Fiddaman return 1;
5306*b30d1939SAndy Fiddaman }
5307*b30d1939SAndy Fiddaman #endif
5308*b30d1939SAndy Fiddaman return 0;
5309*b30d1939SAndy Fiddaman }
5310*b30d1939SAndy Fiddaman
5311*b30d1939SAndy Fiddaman #endif /* _RATZ_C */
5312