2
Copyright (c) 1990-2004 Info-ZIP. All rights reserved.
4
See the accompanying file LICENSE, version 2000-Apr-09 or later
5
(the contents of which are also included in unzip.h) for terms of use.
6
If, for some reason, all these files are missing, the Info-ZIP license
7
also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
9
/*---------------------------------------------------------------------------
13
There is usually no need to include this file since unzip.h includes it.
15
This header file is used by all of the UnZip source files. It contains
16
a struct definition that is used to "house" all of the global variables.
17
This is done to allow for multithreaded environments (OS/2, NT, Win95,
18
Unix) to call UnZip through an API without a semaphore. REENTRANT should
19
be defined for all platforms that require this.
21
GLOBAL CONSTRUCTOR AND DESTRUCTOR (API WRITERS READ THIS!!!)
22
------------------------------------------------------------
24
No, it's not C++, but it's as close as we can get with K&R.
26
The main() of each process that uses these globals must include the
27
CONSTRUCTGLOBALS; statement. This will malloc enough memory for the
28
structure and initialize any variables that require it. This must
29
also be done by any API function that jumps into the middle of the
32
The DESTROYGLOBALS(); statement should be inserted before EVERY "EXIT(n)".
33
Naturally, it also needs to be put before any API returns as well.
34
In fact, it's much more important in API functions since the process
35
will NOT end, and therefore the memory WON'T automatically be freed
36
by the operating system.
38
USING VARIABLES FROM THE STRUCTURE
39
----------------------------------
41
All global variables must now be prefixed with `G.' which is either a
42
global struct (in which case it should be the only global variable) or
43
a macro for the value of a local pointer variable that is passed from
44
function to function. Yes, this is a pain. But it's the only way to
45
allow full reentrancy.
47
ADDING VARIABLES TO THE STRUCTURE
48
---------------------------------
50
If you make the inclusion of any variables conditional, be sure to only
51
check macros that are GUARANTEED to be included in every module.
52
For instance, newzip and pwdarg are needed only if CRYPT is TRUE,
53
but this is defined after unzip.h has been read. If you are not careful,
54
some modules will expect your variable to be part of this struct while
55
others won't. This will cause BIG problems. (Inexplicable crashes at
56
strange times, car fires, etc.) When in doubt, always include it!
58
Note also that UnZipSFX needs a few variables that UnZip doesn't. However,
59
it also includes some object files from UnZip. If we were to conditionally
60
include the extra variables that UnZipSFX needs, the object files from
61
UnZip would not mesh with the UnZipSFX object files. Result: we just
62
include the UnZipSFX variables every time. (It's only an extra 4 bytes
68
To support this new global struct, all functions must now conditionally
69
pass the globals pointer (pG) to each other. This is supported by 5 macros:
70
__GPRO, __GPRO__, __G, __G__ and __GDEF. A function that needs no other
71
parameters would look like this:
73
int extract_or_test_files(__G)
79
A function with other parameters would look like:
81
int memextract(__G__ tgt, tgtsize, src, srcsize)
89
In the Function Prototypes section of unzpriv.h, you should use __GPRO and
92
int uz_opts OF((__GPRO__ int *pargc, char ***pargv));
93
int process_zipfiles OF((__GPRO));
95
Note that there is NO comma after __G__ or __GPRO__ and no semi-colon after
96
__GDEF. I wish there was another way but I don't think there is.
102
Whether your platform requires reentrancy or not, you should always try
103
building with REENTRANT defined if any functions have been added. It is
104
pretty easy to forget a __G__ or a __GDEF and this mistake will only show
105
up if REENTRANT is defined. All platforms should run with REENTRANT
106
defined. Platforms that can't take advantage of it will just be paying
107
a performance penalty needlessly.
112
This whole pointer passing scheme falls apart when it comes to SIGNALs.
113
I handle this situation 2 ways right now. If you define USETHREADID,
114
UnZip will include a 64-entry table. Each entry can hold a global
115
pointer and thread ID for one thread. This should allow up to 64
116
threads to access UnZip simultaneously. Calling DESTROYGLOBALS()
117
will free the global struct and zero the table entry. If somebody
118
forgets to call DESTROYGLOBALS(), this table will eventually fill up
119
and UnZip will exit with an error message. A good way to test your
120
code to make sure you didn't forget a DESTROYGLOBALS() is to change
121
THREADID_ENTRIES to 3 or 4 in globals.c, making the table real small.
122
Then make a small test program that calls your API a dozen times.
124
Those platforms that don't have threads still need to be able to compile
125
with REENTRANT defined to test and see if new code is correctly written
126
to work either way. For these platforms, I simply keep a global pointer
127
called GG that points to the Globals structure. Good enough for testing.
129
I believe that NT has thread level storage. This could probably be used
130
to store a global pointer for the sake of the signal handler more cleanly
131
than my table approach.
133
---------------------------------------------------------------------------*/
140
# ifdef zlib_version /* This name is used internally in unzip */
141
# undef zlib_version /* and must not be defined as a macro. */
150
typedef struct Globals {
152
zvoid *callerglobs; /* pointer to structure of pass-through global vars */
155
/* command options of general use */
156
UzpOpts UzO; /* command options of general use */
159
/* command options specific to the high level command line interface */
161
int M_flag; /* -M: built-in "more" function */
164
/* internal flags and general globals */
166
int height; /* check for SIGWINCH, etc., eventually... */
167
int lines; /* count of lines displayed on current screen */
168
# if (defined(SCREENWIDTH) && defined(SCREENLWRAP))
170
int chars; /* count of screen characters in current line */
173
#if (defined(IZ_CHECK_TZ) && defined(USE_EF_UT_TIME))
174
int tz_is_valid; /* indicates that timezone info can be used */
176
int noargs; /* did true command line have *any* arguments? */
177
unsigned filespecs; /* number of real file specifications to be matched */
178
unsigned xfilespecs; /* number of excluded filespecs to be matched */
179
int process_all_files;
180
int overwrite_mode; /* 0 - query, 1 - always, 2 - never */
181
int create_dirs; /* used by main(), mapname(), checkdir() */
183
int newzip; /* reset in extract.c; used in crypt.c */
184
LONGINT real_ecrec_offset;
185
LONGINT expect_ecrec_offset;
186
long csize; /* used by decompr. (NEXTBYTE): must be signed */
187
long used_csize; /* used by extract_or_test_member(), explode() */
190
int fValidate; /* true if only validating an archive */
192
int redirect_data; /* redirect data to memory buffer */
193
int redirect_text; /* redirect text output to buffer */
194
# ifndef NO_SLIDE_REDIR
195
int redirect_slide; /* redirect decompression area to mem buffer */
196
# if (defined(USE_DEFLATE64) && defined(INT_16BIT))
197
ulg _wsize; /* size of sliding window exceeds "unsigned" range */
199
unsigned _wsize; /* sliding window size can be hold in unsigned */
202
ulg redirect_size; /* size of redirected output buffer */
203
uch *redirect_buffer; /* pointer to head of allocated buffer */
204
uch *redirect_pointer; /* pointer past end of written data */
205
# ifndef NO_SLIDE_REDIR
206
uch *redirect_sldptr; /* head of decompression slide buffer */
209
cbList(processExternally); /* call-back list */
217
min_info info[DIR_BLKSIZ];
220
union work area; /* see unzpriv.h for definition of work */
223
# if (!defined(USE_ZLIB) || defined(USE_OWN_CRCTAB))
224
ZCONST ulg near *crc_32_tab;
226
ZCONST ulg Far *crc_32_tab;
229
ulg crc32val; /* CRC shift reg. (was static in funzip) */
232
FILE *in; /* file descriptor of compressed stream */
234
uch *inbuf; /* input buffer (any size is OK) */
235
uch *inptr; /* pointer into input buffer */
240
int bits_left; /* unreduce and unshrink only */
242
char *argv0; /* used for NT and EXE_EXTENSION */
244
char *zipfn; /* GRR: WINDLL: must nuke any malloc'd zipfn... */
245
#ifdef USE_STRM_INPUT
246
FILE *zipfd; /* zipfile file descriptor */
248
int zipfd; /* zipfile file handle */
251
LONGINT cur_zipfile_bufstart; /* extract_or_test, readbuf, ReadByte */
252
LONGINT extra_bytes; /* used in unzip.c, misc.c */
253
uch *extra_field; /* Unix, VMS, Mac, OS/2, Acorn, ... */
256
local_file_hdr lrec; /* used in unzip.c, extract.c */
257
cdir_file_hdr crec; /* used in unzip.c, extract.c, misc.c */
258
ecdir_rec ecrec; /* used in unzip.c, extract.c */
259
struct stat statbuf; /* used by main, mapname, check_for_newer */
262
uch *outbufptr; /* extract.c static */
263
ulg outsize; /* extract.c static */
264
int reported_backslash; /* extract.c static */
268
int didCRlast; /* fileio static */
269
ulg numlines; /* fileio static: number of lines printed */
270
int sol; /* fileio static: at start of line */
271
int no_ecrec; /* process static */
274
slinkentry *slink_head; /* pointer to head of symlinks list */
275
slinkentry *slink_last; /* pointer to last entry in symlinks list */
277
#ifdef NOVELL_BUG_FAILSAFE
278
int dne; /* true if stat() says file doesn't exist */
285
#ifndef VMS /* if SMALL_MEM, outbuf2 is initialized in */
286
uch *outbuf2; /* process_zipfiles() (never changes); */
287
#endif /* else malloc'd ONLY if unshrink and -a */
290
ulg outcnt; /* number of chars stored in outbuf */
292
char filename[FILNAMSIZ]; /* also used by NT for temporary SFX path */
295
char *tempfn; /* temp file used; erase on close */
298
char *key; /* crypt static: decryption password or NULL */
299
int nopwd; /* crypt static */
301
ulg keys[3]; /* crypt static: keys defining pseudo-random sequence */
303
#if (!defined(DOS_FLX_H68_NLM_OS2_W32) && !defined(AMIGA) && !defined(RISCOS))
304
#if (!defined(MACOS) && !defined(ATARI) && !defined(VMS))
305
int echofd; /* ttyio static: file descriptor whose echo is off */
306
#endif /* !(MACOS || ATARI || VMS) */
307
#endif /* !(DOS_FLX_H68_NLM_OS2_W32 || AMIGA || RISCOS) */
309
unsigned hufts; /* track memory usage */
312
int inflInit; /* inflate static: zlib inflate() initialized */
313
z_stream dstrm; /* inflate global: decompression stream */
315
struct huft *fixed_tl; /* inflate static */
316
struct huft *fixed_td; /* inflate static */
317
unsigned fixed_bl, fixed_bd; /* inflate static */
319
struct huft *fixed_tl64; /* inflate static */
320
struct huft *fixed_td64; /* inflate static */
321
unsigned fixed_bl64, fixed_bd64; /* inflate static */
322
struct huft *fixed_tl32; /* inflate static */
323
struct huft *fixed_td32; /* inflate static */
324
unsigned fixed_bl32, fixed_bd32; /* inflate static */
325
ZCONST ush *cplens; /* inflate static */
326
ZCONST uch *cplext; /* inflate static */
327
ZCONST uch *cpdext; /* inflate static */
329
unsigned wp; /* inflate static: current position in slide */
330
ulg bb; /* inflate static: bit buffer */
331
unsigned bk; /* inflate static: bits count in bit buffer */
332
#endif /* ?USE_ZLIB */
336
char rgchBigBuffer[512];
337
char rgchSmallBuffer[96];
338
char rgchSmallBuffer2[160]; /* boosted to 160 for local3[] in unzip.c */
344
PasswdFn *decr_passwd;
345
StatCBFn *statreportcb;
347
LPUSERFUNCTIONS lpUserFunctions;
350
int incnt_leftover; /* so improved NEXTBYTE does not waste input */
354
unsigned VMS_line_length; /* so native VMS variable-length text files */
355
int VMS_line_state; /* are readable on other platforms */
359
#if (defined(SFX) && defined(CHEAP_SFX_AUTORUN))
360
char autorun_command[FILNAMSIZ];
364
#ifdef SYSTEM_SPECIFIC_GLOBALS
365
SYSTEM_SPECIFIC_GLOBALS
368
} Uz_Globs; /* end of struct Globals */
371
/***************************************************************************/
375
# if (!defined(USE_ZLIB) || defined(USE_OWN_CRCTAB))
376
extern ZCONST ulg near crc_32_tab[256];
378
extern ZCONST ulg Far *crc_32_tab;
380
# define CRC_32_TAB crc_32_tab
382
# define CRC_32_TAB G.crc_32_tab
386
Uz_Globs *globalsCtor OF((void));
388
/* pseudo constant sigs; they are initialized at runtime so unzip executable
389
* won't look like a zipfile
391
extern char local_hdr_sig[4];
392
extern char central_hdr_sig[4];
393
extern char end_central_sig[4];
394
/* extern char extd_local_sig[4]; NOT USED YET */
397
# define G (*(Uz_Globs *)pG)
400
# define __GPRO Uz_Globs *pG
401
# define __GPRO__ Uz_Globs *pG,
402
# define __GDEF Uz_Globs *pG;
405
void deregisterGlobalPointer OF((__GPRO));
406
Uz_Globs *getGlobalPointer OF((void));
407
# define GETGLOBALS() Uz_Globs *pG = getGlobalPointer()
408
# define DESTROYGLOBALS() do {free_G_buffers(pG); \
409
deregisterGlobalPointer(pG);} while (0)
412
# define GETGLOBALS() Uz_Globs *pG = GG
413
# define DESTROYGLOBALS() do {free_G_buffers(pG); free(pG);} while (0)
414
# endif /* ?USETHREADID */
415
# define CONSTRUCTGLOBALS() Uz_Globs *pG = globalsCtor()
416
#else /* !REENTRANT */
423
# define GETGLOBALS()
424
# define CONSTRUCTGLOBALS() globalsCtor()
425
# define DESTROYGLOBALS()
426
#endif /* ?REENTRANT */
430
#endif /* __globals_h */