home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / unzip52.zip / globals.h < prev    next >
C/C++ Source or Header  |  1996-04-25  |  15KB  |  395 lines

  1. /*---------------------------------------------------------------------------
  2.  
  3.   globals.h
  4.  
  5.   There is usually no need to include this file since unzip.h includes it.
  6.  
  7.   This header file is used by all of the UnZip source files.  It contains
  8.   a struct definition that is used to "house" all of the global variables.
  9.   This is done to allow for multithreaded environments (OS/2, NT, Win95,
  10.   Unix) to call UnZip through an API without a semaphore.  REENTRANT should
  11.   be defined for all platforms that require this.
  12.  
  13.   GLOBAL CONSTRUCTOR AND DESTRUCTOR (API WRITERS READ THIS!!!)
  14.   ------------------------------------------------------------
  15.  
  16.   No, it's not C++, but it's as close as we can get with K&R.
  17.  
  18.   The main() of each process that uses these globals must include the
  19.   CONSTRUCTGLOBALS; statement.  This will malloc enough memory for the
  20.   structure and initialize any variables that require it.  This must
  21.   also be done by any API function that jumps into the middle of the
  22.   code.
  23.  
  24.   The DESTROYGLOBALS; statement should be inserted before EVERY "EXIT(n)".
  25.   Naturally, it also needs to be put before any API returns as well.
  26.   In fact, it's much more important in API functions since the process
  27.   will NOT end, and therefore the memory WON'T automatically be freed
  28.   by the operating system.
  29.  
  30.   USING VARIABLES FROM THE STRUCTURE
  31.   ----------------------------------
  32.  
  33.   All global variables must now be prefixed with `G.' which is either a
  34.   global struct (in which case it should be the only global variable) or
  35.   a macro for the value of a local pointer variable that is passed from
  36.   function to function.  Yes, this is a pain.  But it's the only way to
  37.   allow full reentrancy.
  38.  
  39.   ADDING VARIABLES TO THE STRUCTURE
  40.   ---------------------------------
  41.  
  42.   If you make the inclusion of any variables conditional, be sure to only
  43.   check macros that are GUARANTEED to be included in every module.  For
  44.   instance newzip is only needed if CRYPT is defined, but this is defined
  45.   after unzip.h has been read.  If you are not careful, some modules will
  46.   expect your variable to be part of this struct while others won't.  This
  47.   will cause BIG problems. (Inexplicable crashes at strange times, car fires,
  48.   etc.)  When in doubt, always include it!
  49.  
  50.   Note also that UnZipSFX needs a few variables that UnZip doesn't.  However,
  51.   it also includes some object files from UnZip.  If we were to conditionally
  52.   include the extra variables that UnZipSFX needs, the object files from
  53.   UnZip would not mesh with the UnZipSFX object files.  Result: we just
  54.   include the UnZipSFX variables every time.  (It's only an extra 4 bytes
  55.   so who cares!)
  56.  
  57.   ADDING FUNCTIONS
  58.   ----------------
  59.  
  60.   To support this new global struct, all functions must now conditionally
  61.   pass the globals pointer (pG) to each other.  This is supported by 5 macros:
  62.   __GPRO, __GPRO__, __G, __G__ and __GDEF.  A function that needs no other
  63.   parameters would look like this:
  64.  
  65.     int extract_or_test_files(__G)
  66.       __GDEF
  67.     {
  68.        ... stuff ...
  69.     }
  70.  
  71.   A function with other parameters would look like:
  72.  
  73.     int memextract(__G__ tgt, tgtsize, src, srcsize)
  74.         __GDEF
  75.         uch *tgt, *src;
  76.         ulg tgtsize, srcsize;
  77.     {
  78.       ... stuff ...
  79.     }
  80.  
  81.   In the Function Prototypes section of unzpriv.h, you should use __GPRO and
  82.   __GPRO__ instead:
  83.  
  84.     int  uz_opts                   OF((__GPRO__ int *pargc, char ***pargv));
  85.     int  process_zipfiles          OF((__GPRO));
  86.  
  87.   Note that there is NO comma after __G__ or __GPRO__ and no semi-colon after
  88.   __GDEF.  I wish there was another way but I don't think there is.
  89.  
  90.  
  91.   TESTING THE CODE
  92.   -----------------
  93.  
  94.   Whether your platform requires reentrancy or not, you should always try
  95.   building with REENTRANT defined if any functions have been added.  It is
  96.   pretty easy to forget a __G__ or a __GDEF and this mistake will only show
  97.   up if REENTRANT is defined.  All platforms should run with REENTRANT
  98.   defined.  Platforms that can't take advantage of it will just be paying
  99.   a performance penalty needlessly.
  100.  
  101.   SIGNAL MADNESS
  102.   --------------
  103.  
  104.   This whole pointer passing scheme falls apart when it comes to SIGNALs.
  105.   I handle this situation 2 ways right now.  If you define USETHREADID,
  106.   UnZip will include a 64-entry table.  Each entry can hold a global
  107.   pointer and thread ID for one thread.  This should allow up to 64
  108.   threads to access UnZip simultaneously.  Calling DESTROYGLOBALS()
  109.   will free the global struct and zero the table entry.  If somebody
  110.   forgets to call DESTROYGLOBALS(), this table will eventually fill up
  111.   and UnZip will exit with an error message.  A good way to test your
  112.   code to make sure you didn't forget a DESTROYGLOBALS() is to change
  113.   THREADID_ENTRIES to 3 or 4 in globals.c, making the table real small.
  114.   Then make a small test program that calls your API a dozen times.
  115.  
  116.   Those platforms that don't have threads still need to be able to compile
  117.   with REENTRANT defined to test and see if new code is correctly written
  118.   to work either way.  For these platforms, I simply keep a global pointer
  119.   called GG that points to the Globals structure.  Good enough for testing.
  120.  
  121.   I believe that NT has thread level storage.  This could probably be used
  122.   to store a global pointer for the sake of the signal handler more cleanly
  123.   than my table approach.
  124.  
  125.   ---------------------------------------------------------------------------*/
  126.  
  127. #ifndef __globals_h
  128. #define __globals_h
  129.  
  130. #ifdef USE_ZLIB
  131. #  include "zlib.h"
  132. #endif
  133.  
  134.  
  135. /*************/
  136. /*  Globals  */
  137. /*************/
  138.  
  139. struct Globals {
  140.     int zipinfo_mode;   /* behave like ZipInfo or like normal UnZip? */
  141.     int aflag;          /* -a: do ASCII-EBCDIC and/or end-of-line translation */
  142. #if defined(VMS)
  143.     int bflag;          /* -b: force fixed record format for binary files */
  144. #endif /* VMS */
  145.     int cflag;          /* -c: output to stdout */
  146.     int C_flag;         /* -C: match filenames case-insensitively */
  147.     int dflag;          /* -d: all args are files/dirs to be extracted */
  148.     int fflag;          /* -f: "freshen" (extract only newer files) */
  149.     int hflag;          /* -h: header line (zipinfo) */
  150. #ifdef RISCOS
  151.     int scanimage;      /* -I: scan image files */
  152. #endif
  153.     int jflag;          /* -j: junk pathnames (unzip) */
  154.     int lflag;          /* -12slmv: listing format (zipinfo) */
  155.     int L_flag;         /* -L: convert filenames from some OSes to lowercase */
  156. #ifdef MORE
  157.     int M_flag;         /* -M: built-in "more" function */
  158.     int height;         /* check for SIGWINCH, etc., eventually... */
  159. #endif               /* (take line-wrapping into account?) */
  160.     int overwrite_none; /* -n: never overwrite files (no prompting) */
  161.     int overwrite_all;  /* -o: OK to overwrite files without prompting */
  162.     int qflag;          /* -q: produce a lot less output */
  163. #ifdef DOS_OS2_W32
  164.     int sflag;          /* -s: convert spaces in filenames to underscores */
  165.     int volflag;        /* -$: extract volume labels */
  166. #endif
  167.     int tflag;          /* -t: test (unzip) or totals line (zipinfo) */
  168.     int T_flag;         /* -T: timestamps (unzip) or dec. time fmt (zipinfo) */
  169.     int uflag;          /* -u: "update" (extract only newer/brand-new files) */
  170.     int vflag;          /* -v: (verbosely) list directory */
  171.     int V_flag;         /* -V: don't strip VMS version numbers */
  172. #if defined(VMS) || defined(UNIX) || defined(OS2)
  173.     int X_flag;         /* -X: restore owner/protection or UID/GID or ACLs */
  174. #endif
  175.     int zflag;          /* -z: display the zipfile comment (only, for unzip) */
  176. #ifdef MACOS
  177.     int HFSFlag;
  178. #endif
  179.  
  180.     int filespecs;        /* number of real file specifications to be matched */
  181.     int xfilespecs;       /* number of excluded filespecs to be matched */
  182.     int process_all_files;
  183.     int create_dirs;      /* used by main(), mapname(), checkdir() */
  184.     int extract_flag;
  185.     int newzip;           /* used in extract.c, crypt.c, zipinfo.c */
  186.     LONGINT   real_ecrec_offset;
  187.     LONGINT   expect_ecrec_offset;
  188.     long csize;           /* used by list_files(), NEXTBYTE: must be signed */
  189.     long ucsize;          /* used by list_files(), unReduce(), explode() */
  190.     long used_csize;      /* used by extract_or_test_member(), explode() */
  191.  
  192. #ifdef DLL
  193.      int filenotfound;
  194.      int redirect_data;   /* redirect data to memory buffer */
  195.      int redirect_text;   /* redirect text output to buffer */
  196. # ifdef OS2API
  197.      cbList(processExternally);    /* call-back list */
  198. # endif
  199.      unsigned _wsize;
  200.      int stem_len;
  201.      int putchar_idx;
  202.      uch *redirect_pointer;
  203.      uch *redirect_buffer;
  204.      unsigned redirect_size;
  205. #endif /* DLL */
  206.  
  207.     char **pfnames;
  208.     char **pxnames;
  209.     char sig[5];
  210.     char answerbuf[10];
  211.     min_info info[DIR_BLKSIZ];
  212.     min_info *pInfo;
  213.     union work area;                /* see unzpriv.h for definition of work */
  214.  
  215. #ifndef FUNZIP
  216.     ulg near  *crc_32_tab;
  217. #endif
  218.     ulg       crc32val;             /* CRC shift reg. (was static in funzip) */
  219.  
  220.     uch       *inbuf;               /* input buffer (any size is OK) */
  221.     uch       *inptr;               /* pointer into input buffer */
  222.     int       incnt;
  223.     ulg       bitbuf;
  224.     int       bits_left;            /* unreduce and unshrink only */
  225.     int       zipeof;
  226.     char      *argv0;               /* used for NT and EXE_EXTENSION */
  227.     char      *wildzipfn;
  228.     char      *zipfn;    /* GRR:  MSWIN:  must nuke any malloc'd zipfn... */
  229. #ifdef USE_STRM_INPUT
  230.     FILE      *zipfd;               /* zipfile file descriptor */
  231. #else /* !USE_STRM_INPUT */
  232.     int       zipfd;                /* zipfile file handle */
  233. #endif /* ?USE_STRM_INPUT */
  234.     LONGINT   ziplen;
  235.     LONGINT   cur_zipfile_bufstart; /* extract_or_test, readbuf, ReadByte */
  236.     LONGINT   extra_bytes;          /* used in unzip.c, misc.c */
  237.     uch       *extra_field;         /* Unix, VMS, Mac, OS/2, Acorn, ... */
  238.     uch       *hold;
  239.     char      local_hdr_sig[5];     /* initialize sigs at runtime so unzip */
  240.     char      central_hdr_sig[5];   /*  executable won't look like a zipfile */
  241.     char      end_central_sig[5];
  242. /* char extd_local_sig[5];  NOT USED YET */
  243.  
  244.     local_file_hdr  lrec;          /* used in unzip.c, extract.c */
  245.     cdir_file_hdr   crec;          /* used in unzip.c, extract.c, misc.c */
  246.     ecdir_rec       ecrec;         /* used in unzip.c, extract.c */
  247.     struct stat     statbuf;       /* used by main, mapname, check_for_newer */
  248.  
  249.     int      mem_mode;
  250.     uch      *outbufptr;           /* extract.c static */
  251.     ulg      outsize;              /* extract.c static */
  252.     int      reported_backslash;   /* extract.c static */
  253.     int      disk_full;
  254.     int      newfile;
  255.  
  256.     int      didCRlast;            /* fileio static */
  257.     ulg      numlines;             /* fileio static: number of lines printed */
  258.     int      sol;                  /* fileio static: at start of line */
  259.     int      no_ecrec;             /* process static */
  260. #ifdef SYMLINKS
  261.     int      symlnk;
  262. #endif
  263. #ifdef NOVELL_BUG_FAILSAFE
  264.     int      dne;                  /* true if stat() says file doesn't exist */
  265. #endif
  266.  
  267. #ifdef FUNZIP
  268.     FILE     *in;
  269. #endif
  270.     FILE     *outfile;
  271.     uch      *outbuf;
  272.     uch      *realbuf;
  273.  
  274. #ifndef VMS                        /* if SMALL_MEM, outbuf2 is initialized in */
  275.     uch      *outbuf2;             /*  main() (never changes); else malloc'd */
  276. #endif                             /*  ONLY if unshrink and -a */
  277.     uch      *outptr;
  278.     ulg      outcnt;               /* number of chars stored in outbuf */
  279. #ifdef MSWIN
  280.     char     *filename;
  281. #else
  282.     char     filename[FILNAMSIZ];  /* also used by NT for temporary SFX path */
  283. #endif
  284.  
  285. #ifdef MACOS
  286.     short    gnVRefNum;
  287.     long     glDirID;
  288.     OSType   gostCreator;
  289.     OSType   gostType;
  290.     int      fMacZipped;
  291.     int      macflag;
  292.     short    giCursor;
  293.     CursHandle rghCursor[4];       /* status cursors */
  294. #endif
  295.  
  296.     unsigned calls;    /* crypt static: ensure diff. random header each time */
  297.     int nopwd;         /* crypt static */
  298.     ulg keys[3];       /* crypt static: keys defining pseudo-random sequence */
  299.     char *key;         /* crypt static: decryption password or NULL */
  300.  
  301. #if (!defined(DOS_H68_OS2_W32) && !defined(AMIGA) && !defined(RISCOS))
  302. #if (!defined(MACOS) && !defined(ATARI) && !defined(VMS))
  303.     int echofd;        /* crypt static: file descriptor whose echo is off */
  304. #endif /* !(MACOS || ATARI || VMS) */
  305. #endif /* !(DOS_H68_OS2_W32 || AMIGA || RISCOS) */
  306.  
  307.     unsigned hufts;    /* track memory usage */
  308.  
  309. #ifdef USE_ZLIB
  310.     int inflInit;             /* inflate static: zlib inflate() initialized */
  311.     z_stream dstrm;           /* inflate global: decompression stream */
  312. #else
  313.     struct huft *fixed_tl;    /* inflate static */
  314.     struct huft *fixed_td;    /* inflate static */
  315.     int fixed_bl, fixed_bd;   /* inflate static */
  316.     unsigned wp;              /* inflate static: current position in slide */
  317.     ulg bb;                   /* inflate static: bit buffer */
  318.     unsigned bk;              /* inflate static: bits in bit buffer */
  319. #endif /* ?USE_ZLIB */
  320.  
  321. #ifdef SMALL_MEM
  322.     char rgchBigBuffer[512];
  323.     char rgchSmallBuffer[96];
  324.     char rgchSmallBuffer2[160];  /* boosted to 160 for local3[] in unzip.c */
  325. #endif
  326.  
  327.     MsgFn *message;
  328.     InputFn *input;
  329.     PauseFn *mpause;
  330.  
  331.     int incnt_leftover;       /* so improved NEXTBYTE does not waste input */
  332.     uch *inptr_leftover;
  333.  
  334. #ifdef SYSTEM_SPECIFIC_GLOBALS
  335.     SYSTEM_SPECIFIC_GLOBALS
  336. #endif
  337.  
  338. };  /* end of struct Globals */
  339.  
  340.  
  341. /***************************************************************************/
  342.  
  343.  
  344. #ifdef FUNZIP
  345. #  if !defined(USE_ZLIB) || defined(USE_OWN_CRCTAB)
  346.      extern ulg near  crc_32_tab[];
  347. #  else
  348.      extern ulg near *crc_32_tab;
  349. #  endif
  350. #  define CRC_32_TAB  crc_32_tab
  351. #else
  352. #  define CRC_32_TAB  G.crc_32_tab
  353. #endif
  354.  
  355.  
  356. struct Globals *globalsCtor   OF((void));
  357.  
  358.  
  359. #ifdef REENTRANT
  360. #  ifdef RECHEAT
  361.      extern struct Globals    *pG;
  362. #  endif
  363. #  define G                   (*pG)
  364. #  define __G                 pG
  365. #  define __G__               pG,
  366. #  define __GPRO              struct Globals *pG
  367. #  define __GPRO__            struct Globals *pG,
  368. #  define __GDEF              struct Globals *pG;
  369. #  ifdef  USETHREADID
  370.      extern int               lastScan;
  371.      void deregisterGlobalPointer     OF((__GPRO));
  372.      struct Globals *getGlobalPointer OF((void));
  373. #    define GETGLOBALS()      struct Globals *pG = getGlobalPointer();
  374. #    define DESTROYGLOBALS()  {inflate_free(pG); deregisterGlobalPointer(pG);}
  375. #  else
  376.      extern struct Globals    *GG;
  377. #    define GETGLOBALS()      struct Globals *pG = GG;
  378. #    define DESTROYGLOBALS()  {inflate_free(pG); free(pG);}
  379. #  endif /* ?USETHREADID */
  380. #  define CONSTRUCTGLOBALS()  struct Globals *pG = globalsCtor()
  381. #else /* !REENTRANT */
  382.    extern struct Globals      G;
  383. #  define __G
  384. #  define __G__
  385. #  define __GPRO              void
  386. #  define __GPRO__
  387. #  define __GDEF
  388. #  define GETGLOBALS()
  389. #  define CONSTRUCTGLOBALS()  globalsCtor()
  390. #  define DESTROYGLOBALS()
  391. #endif /* ?REENTRANT */
  392.  
  393.  
  394. #endif /* __globals_h */
  395.