which included commits to RCS files with non-trunk default branches. git-svn-id: svn://10.65.10.50/trunk@5403 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			409 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			409 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
/*---------------------------------------------------------------------------
 | 
						|
 | 
						|
  globals.h
 | 
						|
 | 
						|
  There is usually no need to include this file since unzip.h includes it.
 | 
						|
 | 
						|
  This header file is used by all of the UnZip source files.  It contains
 | 
						|
  a struct definition that is used to "house" all of the global variables.
 | 
						|
  This is done to allow for multithreaded environments (OS/2, NT, Win95,
 | 
						|
  Unix) to call UnZip through an API without a semaphore.  REENTRANT should
 | 
						|
  be defined for all platforms that require this.
 | 
						|
 | 
						|
  GLOBAL CONSTRUCTOR AND DESTRUCTOR (API WRITERS READ THIS!!!)
 | 
						|
  ------------------------------------------------------------
 | 
						|
 | 
						|
  No, it's not C++, but it's as close as we can get with K&R.
 | 
						|
 | 
						|
  The main() of each process that uses these globals must include the
 | 
						|
  CONSTRUCTGLOBALS; statement.  This will malloc enough memory for the
 | 
						|
  structure and initialize any variables that require it.  This must
 | 
						|
  also be done by any API function that jumps into the middle of the
 | 
						|
  code.
 | 
						|
 | 
						|
  The DESTROYGLOBALS; statement should be inserted before EVERY "EXIT(n)".
 | 
						|
  Naturally, it also needs to be put before any API returns as well.
 | 
						|
  In fact, it's much more important in API functions since the process
 | 
						|
  will NOT end, and therefore the memory WON'T automatically be freed
 | 
						|
  by the operating system.
 | 
						|
 | 
						|
  USING VARIABLES FROM THE STRUCTURE
 | 
						|
  ----------------------------------
 | 
						|
 | 
						|
  All global variables must now be prefixed with `G.' which is either a
 | 
						|
  global struct (in which case it should be the only global variable) or
 | 
						|
  a macro for the value of a local pointer variable that is passed from
 | 
						|
  function to function.  Yes, this is a pain.  But it's the only way to
 | 
						|
  allow full reentrancy.
 | 
						|
 | 
						|
  ADDING VARIABLES TO THE STRUCTURE
 | 
						|
  ---------------------------------
 | 
						|
 | 
						|
  If you make the inclusion of any variables conditional, be sure to only
 | 
						|
  check macros that are GUARANTEED to be included in every module.  For
 | 
						|
  instance, newzip, P_flag and pwdarg are needed only if CRYPT is TRUE,
 | 
						|
  but this is defined after unzip.h has been read.  If you are not careful,
 | 
						|
  some modules will expect your variable to be part of this struct while
 | 
						|
  others won't.  This will cause BIG problems. (Inexplicable crashes at
 | 
						|
  strange times, car fires, etc.)  When in doubt, always include it!
 | 
						|
 | 
						|
  Note also that UnZipSFX needs a few variables that UnZip doesn't.  However,
 | 
						|
  it also includes some object files from UnZip.  If we were to conditionally
 | 
						|
  include the extra variables that UnZipSFX needs, the object files from
 | 
						|
  UnZip would not mesh with the UnZipSFX object files.  Result: we just
 | 
						|
  include the UnZipSFX variables every time.  (It's only an extra 4 bytes
 | 
						|
  so who cares!)
 | 
						|
 | 
						|
  ADDING FUNCTIONS
 | 
						|
  ----------------
 | 
						|
 | 
						|
  To support this new global struct, all functions must now conditionally
 | 
						|
  pass the globals pointer (pG) to each other.  This is supported by 5 macros:
 | 
						|
  __GPRO, __GPRO__, __G, __G__ and __GDEF.  A function that needs no other
 | 
						|
  parameters would look like this:
 | 
						|
 | 
						|
    int extract_or_test_files(__G)
 | 
						|
      __GDEF
 | 
						|
    {
 | 
						|
       ... stuff ...
 | 
						|
    }
 | 
						|
 | 
						|
  A function with other parameters would look like:
 | 
						|
 | 
						|
    int memextract(__G__ tgt, tgtsize, src, srcsize)
 | 
						|
        __GDEF
 | 
						|
        uch *tgt, *src;
 | 
						|
        ulg tgtsize, srcsize;
 | 
						|
    {
 | 
						|
      ... stuff ...
 | 
						|
    }
 | 
						|
 | 
						|
  In the Function Prototypes section of unzpriv.h, you should use __GPRO and
 | 
						|
  __GPRO__ instead:
 | 
						|
 | 
						|
    int  uz_opts                   OF((__GPRO__ int *pargc, char ***pargv));
 | 
						|
    int  process_zipfiles          OF((__GPRO));
 | 
						|
 | 
						|
  Note that there is NO comma after __G__ or __GPRO__ and no semi-colon after
 | 
						|
  __GDEF.  I wish there was another way but I don't think there is.
 | 
						|
 | 
						|
 | 
						|
  TESTING THE CODE
 | 
						|
  -----------------
 | 
						|
 | 
						|
  Whether your platform requires reentrancy or not, you should always try
 | 
						|
  building with REENTRANT defined if any functions have been added.  It is
 | 
						|
  pretty easy to forget a __G__ or a __GDEF and this mistake will only show
 | 
						|
  up if REENTRANT is defined.  All platforms should run with REENTRANT
 | 
						|
  defined.  Platforms that can't take advantage of it will just be paying
 | 
						|
  a performance penalty needlessly.
 | 
						|
 | 
						|
  SIGNAL MADNESS
 | 
						|
  --------------
 | 
						|
 | 
						|
  This whole pointer passing scheme falls apart when it comes to SIGNALs.
 | 
						|
  I handle this situation 2 ways right now.  If you define USETHREADID,
 | 
						|
  UnZip will include a 64-entry table.  Each entry can hold a global
 | 
						|
  pointer and thread ID for one thread.  This should allow up to 64
 | 
						|
  threads to access UnZip simultaneously.  Calling DESTROYGLOBALS()
 | 
						|
  will free the global struct and zero the table entry.  If somebody
 | 
						|
  forgets to call DESTROYGLOBALS(), this table will eventually fill up
 | 
						|
  and UnZip will exit with an error message.  A good way to test your
 | 
						|
  code to make sure you didn't forget a DESTROYGLOBALS() is to change
 | 
						|
  THREADID_ENTRIES to 3 or 4 in globals.c, making the table real small.
 | 
						|
  Then make a small test program that calls your API a dozen times.
 | 
						|
 | 
						|
  Those platforms that don't have threads still need to be able to compile
 | 
						|
  with REENTRANT defined to test and see if new code is correctly written
 | 
						|
  to work either way.  For these platforms, I simply keep a global pointer
 | 
						|
  called GG that points to the Globals structure.  Good enough for testing.
 | 
						|
 | 
						|
  I believe that NT has thread level storage.  This could probably be used
 | 
						|
  to store a global pointer for the sake of the signal handler more cleanly
 | 
						|
  than my table approach.
 | 
						|
 | 
						|
  ---------------------------------------------------------------------------*/
 | 
						|
 | 
						|
#ifndef __globals_h
 | 
						|
#define __globals_h
 | 
						|
 | 
						|
#ifdef USE_ZLIB
 | 
						|
#  include "zlib.h"
 | 
						|
#endif
 | 
						|
 | 
						|
 | 
						|
/*************/
 | 
						|
/*  Globals  */
 | 
						|
/*************/
 | 
						|
 | 
						|
struct Globals {
 | 
						|
    int zipinfo_mode;   /* behave like ZipInfo or like normal UnZip? */
 | 
						|
    int aflag;          /* -a: do ASCII-EBCDIC and/or end-of-line translation */
 | 
						|
#ifdef VMS
 | 
						|
    int bflag;          /* -b: force fixed record format for binary files */
 | 
						|
#endif
 | 
						|
#ifdef UNIXBACKUP
 | 
						|
    int B_flag;         /* -B: back up existing files by renaming to *~ first */
 | 
						|
#endif
 | 
						|
    int cflag;          /* -c: output to stdout */
 | 
						|
    int C_flag;         /* -C: match filenames case-insensitively */
 | 
						|
    int dflag;          /* -d: all args are files/dirs to be extracted */
 | 
						|
    int fflag;          /* -f: "freshen" (extract only newer files) */
 | 
						|
    int hflag;          /* -h: header line (zipinfo) */
 | 
						|
#ifdef RISCOS
 | 
						|
    int scanimage;      /* -I: scan image files */
 | 
						|
#endif
 | 
						|
    int jflag;          /* -j: junk pathnames (unzip) */
 | 
						|
    int lflag;          /* -12slmv: listing format (zipinfo) */
 | 
						|
    int L_flag;         /* -L: convert filenames from some OSes to lowercase */
 | 
						|
#ifdef MORE
 | 
						|
    int M_flag;         /* -M: built-in "more" function */
 | 
						|
    int height;         /* check for SIGWINCH, etc., eventually... */
 | 
						|
#endif                  /* (take line-wrapping into account?) */
 | 
						|
    int overwrite_none; /* -n: never overwrite files (no prompting) */
 | 
						|
    int overwrite_all;  /* -o: OK to overwrite files without prompting */
 | 
						|
    int P_flag;         /* -P: give password on command line (ARGH!) */
 | 
						|
    int qflag;          /* -q: produce a lot less output */
 | 
						|
#ifdef DOS_OS2_W32
 | 
						|
    int sflag;          /* -s: convert spaces in filenames to underscores */
 | 
						|
    int volflag;        /* -$: extract volume labels */
 | 
						|
#endif
 | 
						|
    int tflag;          /* -t: test (unzip) or totals line (zipinfo) */
 | 
						|
    int T_flag;         /* -T: timestamps (unzip) or dec. time fmt (zipinfo) */
 | 
						|
    int uflag;          /* -u: "update" (extract only newer/brand-new files) */
 | 
						|
    int vflag;          /* -v: (verbosely) list directory */
 | 
						|
    int V_flag;         /* -V: don't strip VMS version numbers */
 | 
						|
#if defined(VMS) || defined(UNIX) || defined(OS2_W32) || defined(__BEOS__)
 | 
						|
    int X_flag;         /* -X: restore owner/protection or UID/GID or ACLs */
 | 
						|
#endif
 | 
						|
    int zflag;          /* -z: display the zipfile comment (only, for unzip) */
 | 
						|
#ifdef MACOS
 | 
						|
    int HFSFlag;
 | 
						|
#endif
 | 
						|
 | 
						|
    int noargs;           /* did true command line have *any* arguments? */
 | 
						|
    int filespecs;        /* number of real file specifications to be matched */
 | 
						|
    int xfilespecs;       /* number of excluded filespecs to be matched */
 | 
						|
    int process_all_files;
 | 
						|
    int create_dirs;      /* used by main(), mapname(), checkdir() */
 | 
						|
    int extract_flag;
 | 
						|
    int newzip;           /* reset in extract.c; used in crypt.c */
 | 
						|
    LONGINT   real_ecrec_offset;
 | 
						|
    LONGINT   expect_ecrec_offset;
 | 
						|
    long csize;           /* used by decompr. (NEXTBYTE): must be signed */
 | 
						|
    long ucsize;          /* used by unReduce(), explode() */
 | 
						|
    long used_csize;      /* used by extract_or_test_member(), explode() */
 | 
						|
 | 
						|
#ifdef DLL
 | 
						|
     int filenotfound;
 | 
						|
     int redirect_data;   /* redirect data to memory buffer */
 | 
						|
     int redirect_text;   /* redirect text output to buffer */
 | 
						|
# ifdef OS2DLL
 | 
						|
     cbList(processExternally);    /* call-back list */
 | 
						|
# endif
 | 
						|
     unsigned _wsize;
 | 
						|
     int stem_len;
 | 
						|
     int putchar_idx;
 | 
						|
     uch *redirect_pointer;
 | 
						|
     uch *redirect_buffer;
 | 
						|
     unsigned redirect_size;
 | 
						|
#endif /* DLL */
 | 
						|
 | 
						|
    char **pfnames;
 | 
						|
    char **pxnames;
 | 
						|
    char sig[5];
 | 
						|
    char answerbuf[10];
 | 
						|
    min_info info[DIR_BLKSIZ];
 | 
						|
    min_info *pInfo;
 | 
						|
    union work area;                /* see unzpriv.h for definition of work */
 | 
						|
 | 
						|
#ifndef FUNZIP
 | 
						|
    ulg near  *crc_32_tab;
 | 
						|
#endif
 | 
						|
    ulg       crc32val;             /* CRC shift reg. (was static in funzip) */
 | 
						|
 | 
						|
    uch       *inbuf;               /* input buffer (any size is OK) */
 | 
						|
    uch       *inptr;               /* pointer into input buffer */
 | 
						|
    int       incnt;
 | 
						|
    ulg       bitbuf;
 | 
						|
    int       bits_left;            /* unreduce and unshrink only */
 | 
						|
    int       zipeof;
 | 
						|
    char      *argv0;               /* used for NT and EXE_EXTENSION */
 | 
						|
    char      *wildzipfn;
 | 
						|
    char      *zipfn;    /* GRR:  WINDLL:  must nuke any malloc'd zipfn... */
 | 
						|
#ifdef USE_STRM_INPUT
 | 
						|
    FILE      *zipfd;               /* zipfile file descriptor */
 | 
						|
#else
 | 
						|
    int       zipfd;                /* zipfile file handle */
 | 
						|
#endif
 | 
						|
    LONGINT   ziplen;
 | 
						|
    LONGINT   cur_zipfile_bufstart; /* extract_or_test, readbuf, ReadByte */
 | 
						|
    LONGINT   extra_bytes;          /* used in unzip.c, misc.c */
 | 
						|
    uch       *extra_field;         /* Unix, VMS, Mac, OS/2, Acorn, ... */
 | 
						|
    uch       *hold;
 | 
						|
    char      local_hdr_sig[5];     /* initialize sigs at runtime so unzip */
 | 
						|
    char      central_hdr_sig[5];   /*  executable won't look like a zipfile */
 | 
						|
    char      end_central_sig[5];
 | 
						|
/* char extd_local_sig[5];  NOT USED YET */
 | 
						|
 | 
						|
    local_file_hdr  lrec;          /* used in unzip.c, extract.c */
 | 
						|
    cdir_file_hdr   crec;          /* used in unzip.c, extract.c, misc.c */
 | 
						|
    ecdir_rec       ecrec;         /* used in unzip.c, extract.c */
 | 
						|
    struct stat     statbuf;       /* used by main, mapname, check_for_newer */
 | 
						|
 | 
						|
    int      mem_mode;
 | 
						|
    uch      *outbufptr;           /* extract.c static */
 | 
						|
    ulg      outsize;              /* extract.c static */
 | 
						|
    int      reported_backslash;   /* extract.c static */
 | 
						|
    int      disk_full;
 | 
						|
    int      newfile;
 | 
						|
 | 
						|
    int      didCRlast;            /* fileio static */
 | 
						|
    ulg      numlines;             /* fileio static: number of lines printed */
 | 
						|
    int      sol;                  /* fileio static: at start of line */
 | 
						|
    int      no_ecrec;             /* process static */
 | 
						|
#ifdef SYMLINKS
 | 
						|
    int      symlnk;
 | 
						|
#endif
 | 
						|
#ifdef NOVELL_BUG_FAILSAFE
 | 
						|
    int      dne;                  /* true if stat() says file doesn't exist */
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef FUNZIP
 | 
						|
    FILE     *in;
 | 
						|
#endif
 | 
						|
    FILE     *outfile;
 | 
						|
    uch      *outbuf;
 | 
						|
    uch      *realbuf;
 | 
						|
 | 
						|
#ifndef VMS                        /* if SMALL_MEM, outbuf2 is initialized in */
 | 
						|
    uch      *outbuf2;             /*  process_zipfiles() (never changes); */
 | 
						|
#endif                             /*  else malloc'd ONLY if unshrink and -a */
 | 
						|
    uch      *outptr;
 | 
						|
    ulg      outcnt;               /* number of chars stored in outbuf */
 | 
						|
    char     filename[FILNAMSIZ];  /* also used by NT for temporary SFX path */
 | 
						|
 | 
						|
#ifdef CMS_MVS
 | 
						|
    char     *tempfn;              /* temp file used; erase on close */
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef MACOS
 | 
						|
    short    gnVRefNum;
 | 
						|
    long     glDirID;
 | 
						|
    OSType   gostCreator;
 | 
						|
    OSType   gostType;
 | 
						|
    int      fMacZipped;
 | 
						|
    int      macflag;
 | 
						|
    short    giCursor;
 | 
						|
    CursHandle rghCursor[4];       /* status cursors */
 | 
						|
#endif
 | 
						|
 | 
						|
    char *pwdarg;      /* pointer to command-line password (-P option) */
 | 
						|
 | 
						|
    int nopwd;         /* crypt static */
 | 
						|
    ulg keys[3];       /* crypt static: keys defining pseudo-random sequence */
 | 
						|
    char *key;         /* crypt static: decryption password or NULL */
 | 
						|
 | 
						|
#if (!defined(DOS_H68_OS2_W32) && !defined(AMIGA) && !defined(RISCOS))
 | 
						|
#if (!defined(MACOS) && !defined(ATARI) && !defined(VMS))
 | 
						|
    int echofd;        /* crypt static: file descriptor whose echo is off */
 | 
						|
#endif /* !(MACOS || ATARI || VMS) */
 | 
						|
#endif /* !(DOS_H68_OS2_W32 || AMIGA || RISCOS) */
 | 
						|
 | 
						|
    unsigned hufts;    /* track memory usage */
 | 
						|
 | 
						|
#ifdef USE_ZLIB
 | 
						|
    int inflInit;             /* inflate static: zlib inflate() initialized */
 | 
						|
    z_stream dstrm;           /* inflate global: decompression stream */
 | 
						|
#else
 | 
						|
    struct huft *fixed_tl;    /* inflate static */
 | 
						|
    struct huft *fixed_td;    /* inflate static */
 | 
						|
    int fixed_bl, fixed_bd;   /* inflate static */
 | 
						|
    unsigned wp;              /* inflate static: current position in slide */
 | 
						|
    ulg bb;                   /* inflate static: bit buffer */
 | 
						|
    unsigned bk;              /* inflate static: bits in bit buffer */
 | 
						|
#endif /* ?USE_ZLIB */
 | 
						|
 | 
						|
#ifdef SMALL_MEM
 | 
						|
    char rgchBigBuffer[512];
 | 
						|
    char rgchSmallBuffer[96];
 | 
						|
    char rgchSmallBuffer2[160];  /* boosted to 160 for local3[] in unzip.c */
 | 
						|
#endif
 | 
						|
 | 
						|
    MsgFn *message;
 | 
						|
    InputFn *input;
 | 
						|
    PauseFn *mpause;
 | 
						|
    PasswdFn *decr_passwd;
 | 
						|
#ifdef WINDLL
 | 
						|
    ReplaceFn *replace;
 | 
						|
    SoundFn *sound;
 | 
						|
#endif
 | 
						|
 | 
						|
    int incnt_leftover;       /* so improved NEXTBYTE does not waste input */
 | 
						|
    uch *inptr_leftover;
 | 
						|
 | 
						|
#ifdef VMS_TEXT_CONV
 | 
						|
    int VMS_line_state;       /* so native VMS variable-length text files are */
 | 
						|
    int VMS_line_length;      /*  readable on other platforms */
 | 
						|
    int VMS_line_pad;
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef SYSTEM_SPECIFIC_GLOBALS
 | 
						|
    SYSTEM_SPECIFIC_GLOBALS
 | 
						|
#endif
 | 
						|
 | 
						|
};  /* end of struct Globals */
 | 
						|
 | 
						|
 | 
						|
/***************************************************************************/
 | 
						|
 | 
						|
 | 
						|
#ifdef FUNZIP
 | 
						|
#  if !defined(USE_ZLIB) || defined(USE_OWN_CRCTAB)
 | 
						|
     extern ulg near  crc_32_tab[];
 | 
						|
#  else
 | 
						|
     extern ulg near *crc_32_tab;
 | 
						|
#  endif
 | 
						|
#  define CRC_32_TAB  crc_32_tab
 | 
						|
#else
 | 
						|
#  define CRC_32_TAB  G.crc_32_tab
 | 
						|
#endif
 | 
						|
 | 
						|
 | 
						|
struct Globals *globalsCtor   OF((void));
 | 
						|
 | 
						|
 | 
						|
#ifdef REENTRANT
 | 
						|
#  define G                   (*pG)
 | 
						|
#  define __G                 pG
 | 
						|
#  define __G__               pG,
 | 
						|
#  define __GPRO              struct Globals *pG
 | 
						|
#  define __GPRO__            struct Globals *pG,
 | 
						|
#  define __GDEF              struct Globals *pG;
 | 
						|
#  ifdef  USETHREADID
 | 
						|
     extern int               lastScan;
 | 
						|
     void deregisterGlobalPointer     OF((__GPRO));
 | 
						|
     struct Globals *getGlobalPointer OF((void));
 | 
						|
#    define GETGLOBALS()      struct Globals *pG = getGlobalPointer();
 | 
						|
#    define DESTROYGLOBALS()  {free_G_buffers(pG); deregisterGlobalPointer(pG);}
 | 
						|
#  else
 | 
						|
     extern struct Globals    *GG;
 | 
						|
#    define GETGLOBALS()      struct Globals *pG = GG;
 | 
						|
#    define DESTROYGLOBALS()  {free_G_buffers(pG); free(pG);}
 | 
						|
#  endif /* ?USETHREADID */
 | 
						|
#  define CONSTRUCTGLOBALS()  struct Globals *pG = globalsCtor()
 | 
						|
#else /* !REENTRANT */
 | 
						|
   extern struct Globals      G;
 | 
						|
#  define __G
 | 
						|
#  define __G__
 | 
						|
#  define __GPRO              void
 | 
						|
#  define __GPRO__
 | 
						|
#  define __GDEF
 | 
						|
#  define GETGLOBALS()
 | 
						|
#  define CONSTRUCTGLOBALS()  globalsCtor()
 | 
						|
#  define DESTROYGLOBALS()
 | 
						|
#endif /* ?REENTRANT */
 | 
						|
 | 
						|
 | 
						|
#endif /* __globals_h */
 |