1 /*
2   Copyright (c) 1990-2009 Info-ZIP.  All rights reserved.
3 
4   See the accompanying file LICENSE, version 2009-Jan-02 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
8 */
9 /*---------------------------------------------------------------------------
10 
11   globals.h
12 
13   There is usually no need to include this file since unzip.h includes it.
14 
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.
20 
21   GLOBAL CONSTRUCTOR AND DESTRUCTOR (API WRITERS READ THIS!!!)
22   ------------------------------------------------------------
23 
24   No, it's not C++, but it's as close as we can get with K&R.
25 
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
30   code.
31 
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.
37 
38   USING VARIABLES FROM THE STRUCTURE
39   ----------------------------------
40 
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.
46 
47   ADDING VARIABLES TO THE STRUCTURE
48   ---------------------------------
49 
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!
57 
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
63   so who cares!)
64 
65   ADDING FUNCTIONS
66   ----------------
67 
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:
72 
73     int extract_or_test_files(__G)
74       __GDEF
75     {
76        ... stuff ...
77     }
78 
79   A function with other parameters would look like:
80 
81     int memextract(__G__ tgt, tgtsize, src, srcsize)
82         __GDEF
83         uch *tgt, *src;
84         ulg tgtsize, srcsize;
85     {
86       ... stuff ...
87     }
88 
89   In the Function Prototypes section of unzpriv.h, you should use __GPRO and
90   __GPRO__ instead:
91 
92     int  uz_opts                   OF((__GPRO__ int *pargc, char ***pargv));
93     int  process_zipfiles          OF((__GPRO));
94 
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.
97 
98 
99   TESTING THE CODE
100   -----------------
101 
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.
108 
109   SIGNAL MADNESS
110   --------------
111 
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.
123 
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.
128 
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.
132 
133   ---------------------------------------------------------------------------*/
134 
135 #ifndef __globals_h
136 #define __globals_h
137 
138 #ifdef USE_ZLIB
139 #  include "zlib.h"
140 #  ifdef zlib_version           /* This name is used internally in unzip */
141 #    undef zlib_version         /*  and must not be defined as a macro. */
142 #  endif
143 #endif
144 
145 #ifdef USE_BZIP2
146 #  include "bzlib.h"
147 #endif
148 
149 
150 /*************/
151 /*  Globals  */
152 /*************/
153 
154 typedef struct Globals {
155 #ifdef DLL
156     zvoid *callerglobs; /* pointer to structure of pass-through global vars */
157 #endif
158 
159     /* command options of general use */
160     UzpOpts UzO;        /* command options of general use */
161 
162 #ifndef FUNZIP
163     /* command options specific to the high level command line interface */
164 #ifdef MORE
165     int M_flag;         /* -M: built-in "more" function */
166 #endif
167 
168     /* internal flags and general globals */
169 #ifdef MORE
170     int height;           /* check for SIGWINCH, etc., eventually... */
171     int lines;            /* count of lines displayed on current screen */
172 # if (defined(SCREENWIDTH) && defined(SCREENLWRAP))
173     int width;
174     int chars;            /* count of screen characters in current line */
175 # endif
176 #endif /* MORE */
177 #if (defined(IZ_CHECK_TZ) && defined(USE_EF_UT_TIME))
178     int tz_is_valid;      /* indicates that timezone info can be used */
179 #endif
180     int noargs;           /* did true command line have *any* arguments? */
181     unsigned filespecs;   /* number of real file specifications to be matched */
182     unsigned xfilespecs;  /* number of excluded filespecs to be matched */
183     int process_all_files;
184     int overwrite_mode;   /* 0 - query, 1 - always, 2 - never */
185     int create_dirs;      /* used by main(), mapname(), checkdir() */
186     int extract_flag;
187     int newzip;           /* reset in extract.c; used in crypt.c */
188     zoff_t   real_ecrec_offset;
189     zoff_t   expect_ecrec_offset;
190     zoff_t   csize;       /* used by decompr. (NEXTBYTE): must be signed */
191     zoff_t   used_csize;  /* used by extract_or_test_member(), explode() */
192 
193 #ifdef DLL
194      int fValidate;       /* true if only validating an archive */
195      int filenotfound;
196      int redirect_data;   /* redirect data to memory buffer */
197      int redirect_text;   /* redirect text output to buffer */
198 # ifndef NO_SLIDE_REDIR
199      int redirect_slide;  /* redirect decompression area to mem buffer */
200 #  if (defined(USE_DEFLATE64) && defined(INT_16BIT))
201      ulg _wsize;          /* size of sliding window exceeds "unsigned" range */
202 #  else
203      unsigned _wsize;     /* sliding window size can be hold in unsigned */
204 #  endif
205 # endif
206      ulg redirect_size;            /* size of redirected output buffer */
207      uch *redirect_buffer;         /* pointer to head of allocated buffer */
208      uch *redirect_pointer;        /* pointer past end of written data */
209 # ifndef NO_SLIDE_REDIR
210      uch *redirect_sldptr;         /* head of decompression slide buffer */
211 # endif
212 # ifdef OS2DLL
213      cbList(processExternally);    /* call-back list */
214 # endif
215 #endif /* DLL */
216 
217     char **pfnames;
218     char **pxnames;
219     char sig[4];
220     char answerbuf[10];
221     min_info info[DIR_BLKSIZ];
222     min_info *pInfo;
223 #endif /* !FUNZIP */
224     union work area;                /* see unzpriv.h for definition of work */
225 
226 #if (!defined(USE_ZLIB) || defined(USE_OWN_CRCTAB))
227     ZCONST ulg near *crc_32_tab;
228 #else
229     ZCONST ulg Far *crc_32_tab;
230 #endif
231     ulg       crc32val;             /* CRC shift reg. (was static in funzip) */
232 
233 #ifdef FUNZIP
234     FILE      *in;                  /* file descriptor of compressed stream */
235 #endif
236     uch       *inbuf;               /* input buffer (any size is OK) */
237     uch       *inptr;               /* pointer into input buffer */
238     int       incnt;
239 
240 #ifndef FUNZIP
241     ulg       bitbuf;
242     int       bits_left;            /* unreduce and unshrink only */
243     int       zipeof;
244     char      *argv0;               /* used for NT and EXE_EXTENSION */
245     char      *wildzipfn;
246     char      *zipfn;    /* GRR:  WINDLL:  must nuke any malloc'd zipfn... */
247 #ifdef USE_STRM_INPUT
248     FILE      *zipfd;               /* zipfile file descriptor */
249 #else
250     int       zipfd;                /* zipfile file handle */
251 #endif
252     zoff_t    ziplen;
253     zoff_t    cur_zipfile_bufstart; /* extract_or_test, readbuf, ReadByte */
254     zoff_t    extra_bytes;          /* used in unzip.c, misc.c */
255     uch       *extra_field;         /* Unix, VMS, Mac, OS/2, Acorn, ... */
256     uch       *hold;
257 
258     local_file_hdr  lrec;          /* used in unzip.c, extract.c */
259     cdir_file_hdr   crec;          /* used in unzip.c, extract.c, misc.c */
260     ecdir_rec       ecrec;         /* used in unzip.c, extract.c */
261     z_stat   statbuf;              /* used by main, mapname, check_for_newer */
262 
263     int      mem_mode;
264     uch      *outbufptr;           /* extract.c static */
265     ulg      outsize;              /* extract.c static */
266     int      reported_backslash;   /* extract.c static */
267     int      disk_full;
268     int      newfile;
269 
270     int      didCRlast;            /* fileio static */
271     ulg      numlines;             /* fileio static: number of lines printed */
272     int      sol;                  /* fileio static: at start of line */
273     int      no_ecrec;             /* process static */
274 #ifdef SYMLINKS
275     int      symlnk;
276     slinkentry *slink_head;        /* pointer to head of symlinks list */
277     slinkentry *slink_last;        /* pointer to last entry in symlinks list */
278 #endif
279 #ifdef NOVELL_BUG_FAILSAFE
280     int      dne;                  /* true if stat() says file doesn't exist */
281 #endif
282 
283     FILE     *outfile;
284     uch      *outbuf;
285     uch      *realbuf;
286 
287 #ifndef VMS                        /* if SMALL_MEM, outbuf2 is initialized in */
288     uch      *outbuf2;             /*  process_zipfiles() (never changes); */
289 #endif                             /*  else malloc'd ONLY if unshrink and -a */
290 #endif /* !FUNZIP */
291     uch      *outptr;
292     ulg      outcnt;               /* number of chars stored in outbuf */
293 #ifndef FUNZIP
294     char     filename[FILNAMSIZ];  /* also used by NT for temporary SFX path */
295 #ifdef UNICODE_SUPPORT
296     char     *filename_full;       /* the full path so Unicode checks work */
297     extent   fnfull_bufsize;       /* size of allocated filename buffer */
298     int      unicode_escape_all;
299     int      unicode_mismatch;
300 #ifdef UTF8_MAYBE_NATIVE
301     int      native_is_utf8;       /* bool, TRUE => native charset == UTF-8 */
302 #endif
303 
304     int      unipath_version;      /* version of Unicode field */
305     ulg      unipath_checksum;     /* Unicode field checksum */
306     char     *unipath_filename;    /* UTF-8 path */
307 #endif /* UNICODE_SUPPORT */
308 
309 #ifdef CMS_MVS
310     char     *tempfn;              /* temp file used; erase on close */
311 #endif
312 
313     char *key;         /* crypt static: decryption password or NULL */
314     int nopwd;         /* crypt static */
315 #endif /* !FUNZIP */
316     z_uint4 keys[3];   /* crypt static: keys defining pseudo-random sequence */
317 
318 #if (!defined(DOS_FLX_H68_NLM_OS2_W32) && !defined(AMIGA) && !defined(RISCOS))
319 #if (!defined(MACOS) && !defined(ATARI) && !defined(VMS))
320     int echofd;        /* ttyio static: file descriptor whose echo is off */
321 #endif /* !(MACOS || ATARI || VMS) */
322 #endif /* !(DOS_FLX_H68_NLM_OS2_W32 || AMIGA || RISCOS) */
323 
324     unsigned hufts;    /* track memory usage */
325 
326 #ifdef USE_ZLIB
327     int inflInit;             /* inflate static: zlib inflate() initialized */
328     z_stream dstrm;           /* inflate global: decompression stream */
329 #else
330     struct huft *fixed_tl;              /* inflate static */
331     struct huft *fixed_td;              /* inflate static */
332     unsigned fixed_bl, fixed_bd;        /* inflate static */
333 #ifdef USE_DEFLATE64
334     struct huft *fixed_tl64;            /* inflate static */
335     struct huft *fixed_td64;            /* inflate static */
336     unsigned fixed_bl64, fixed_bd64;    /* inflate static */
337     struct huft *fixed_tl32;            /* inflate static */
338     struct huft *fixed_td32;            /* inflate static */
339     unsigned fixed_bl32, fixed_bd32;    /* inflate static */
340     ZCONST ush *cplens;                 /* inflate static */
341     ZCONST uch *cplext;                 /* inflate static */
342     ZCONST uch *cpdext;                 /* inflate static */
343 #endif
344     unsigned wp;              /* inflate static: current position in slide */
345     ulg bb;                   /* inflate static: bit buffer */
346     unsigned bk;              /* inflate static: bits count in bit buffer */
347 #endif /* ?USE_ZLIB */
348 
349 #ifndef FUNZIP
350     /* cylindric buffer space for formatting zoff_t values (fileio static) */
351     char fzofft_buf[FZOFFT_NUM][FZOFFT_LEN];
352     int fzofft_index;
353 
354 #ifdef SMALL_MEM
355     char rgchBigBuffer[512];
356     char rgchSmallBuffer[96];
357     char rgchSmallBuffer2[160];  /* boosted to 160 for local3[] in unzip.c */
358 #endif
359 
360     MsgFn *message;
361     InputFn *input;
362     PauseFn *mpause;
363     PasswdFn *decr_passwd;
364     StatCBFn *statreportcb;
365 #ifdef WINDLL
366     LPUSERFUNCTIONS lpUserFunctions;
367 #endif
368 
369     int incnt_leftover;       /* so improved NEXTBYTE does not waste input */
370     uch *inptr_leftover;
371 
372 #ifdef VMS_TEXT_CONV
373     unsigned VMS_line_length; /* so native VMS variable-length text files */
374     int      VMS_line_state;  /*  are readable on other platforms */
375     int      VMS_line_pad;
376 #endif
377 
378 #if (defined(SFX) && defined(CHEAP_SFX_AUTORUN))
379     char autorun_command[FILNAMSIZ];
380 #endif
381 #endif /* !FUNZIP */
382 
383 #ifdef SYSTEM_SPECIFIC_GLOBALS
384     SYSTEM_SPECIFIC_GLOBALS
385 #endif
386 
387 } Uz_Globs;  /* end of struct Globals */
388 
389 
390 /***************************************************************************/
391 
392 
393 #define CRC_32_TAB      G.crc_32_tab
394 
395 
396 Uz_Globs *globalsCtor   OF((void));
397 
398 /* pseudo constant sigs; they are initialized at runtime so unzip executable
399  * won't look like a zipfile
400  */
401 extern char local_hdr_sig[4];
402 extern char central_hdr_sig[4];
403 extern char end_central_sig[4];
404 extern char end_central32_sig[4];
405 extern char end_central64_sig[4];
406 extern char end_centloc64_sig[4];
407 /* extern char extd_local_sig[4];  NOT USED YET */
408 
409 #ifdef REENTRANT
410 #  define G                   (*(Uz_Globs *)pG)
411 #  define __G                 pG
412 #  define __G__               pG,
413 #  define __GPRO              Uz_Globs *pG
414 #  define __GPRO__            Uz_Globs *pG,
415 #  define __GDEF              Uz_Globs *pG;
416 #  ifdef  USETHREADID
417      extern int               lastScan;
418      void deregisterGlobalPointer OF((__GPRO));
419      Uz_Globs *getGlobalPointer   OF((void));
420 #    define GETGLOBALS()      Uz_Globs *pG = getGlobalPointer()
421 #    define DESTROYGLOBALS()  do {free_G_buffers(pG); \
422                                   deregisterGlobalPointer(pG);} while (0)
423 #  else
424      extern Uz_Globs          *GG;
425 #    define GETGLOBALS()      Uz_Globs *pG = GG
426 #    define DESTROYGLOBALS()  do {free_G_buffers(pG); free(pG);} while (0)
427 #  endif /* ?USETHREADID */
428 #  define CONSTRUCTGLOBALS()  Uz_Globs *pG = globalsCtor()
429 #else /* !REENTRANT */
430    extern Uz_Globs            G;
431 #  define __G
432 #  define __G__
433 #  define __GPRO              void
434 #  define __GPRO__
435 #  define __GDEF
436 #  define GETGLOBALS()
437 #  define CONSTRUCTGLOBALS()  globalsCtor()
438 #  define DESTROYGLOBALS()
439 #endif /* ?REENTRANT */
440 
441 #define uO              G.UzO
442 
443 #endif /* __globals_h */
444