1 /* 2 Copyright (c) 1990-2000 Info-ZIP. All rights reserved. 3 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 8 */ 9 /*--------------------------------------------------------------------------- 10 11 globals.c 12 13 Routines to allocate and initialize globals, with or without threads. 14 15 Contents: registerGlobalPointer() 16 deregisterGlobalPointer() 17 getGlobalPointer() 18 globalsCtor() 19 20 ---------------------------------------------------------------------------*/ 21 22 23 #define UNZIP_INTERNAL 24 #include "unzip.h" 25 26 #ifndef FUNZIP 27 /* initialization of sigs is completed at runtime so unzip(sfx) executable 28 * won't look like a zipfile 29 */ 30 char central_hdr_sig[4] = {0, 0, 0x01, 0x02}; 31 char local_hdr_sig[4] = {0, 0, 0x03, 0x04}; 32 char end_central_sig[4] = {0, 0, 0x05, 0x06}; 33 /* extern char extd_local_sig[4] = {0, 0, 0x07, 0x08}; NOT USED YET */ 34 35 ZCONST char *fnames[2] = {"*", NULL}; /* default filenames vector */ 36 #endif 37 38 39 #ifndef REENTRANT 40 Uz_Globs G; 41 #else /* REENTRANT */ 42 43 # ifndef USETHREADID 44 Uz_Globs *GG; 45 # else /* USETHREADID */ 46 # define THREADID_ENTRIES 0x40 47 48 int lastScan; 49 Uz_Globs *threadPtrTable[THREADID_ENTRIES]; 50 ulg threadIdTable [THREADID_ENTRIES] = { 51 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 52 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* Make sure there are */ 53 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* THREADID_ENTRIES 0s */ 54 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 55 }; 56 57 static ZCONST char Far TooManyThreads[] = 58 "error: more than %d simultaneous threads.\n\ 59 Some threads are probably not calling DESTROYTHREAD()\n"; 60 static ZCONST char Far EntryNotFound[] = 61 "error: couldn't find global pointer in table.\n\ 62 Maybe somebody accidentally called DESTROYTHREAD() twice.\n"; 63 static ZCONST char Far GlobalPointerMismatch[] = 64 "error: global pointer in table does not match pointer passed as\ 65 parameter\n"; 66 67 static void registerGlobalPointer OF((__GPRO)); 68 69 70 71 static void registerGlobalPointer(__G) 72 __GDEF 73 { 74 int scan=0; 75 ulg tid = GetThreadId(); 76 77 while (threadIdTable[scan] && scan < THREADID_ENTRIES) 78 scan++; 79 80 if (scan == THREADID_ENTRIES) { 81 ZCONST char *tooMany = LoadFarString(TooManyThreads); 82 Info(slide, 0x421, ((char *)slide, tooMany, THREADID_ENTRIES)); 83 free(pG); 84 EXIT(PK_MEM); /* essentially memory error before we've started */ 85 } 86 87 threadIdTable [scan] = tid; 88 threadPtrTable[scan] = pG; 89 lastScan = scan; 90 } 91 92 93 94 void deregisterGlobalPointer(__G) 95 __GDEF 96 { 97 int scan=0; 98 ulg tid = GetThreadId(); 99 100 101 while (threadIdTable[scan] != tid && scan < THREADID_ENTRIES) 102 scan++; 103 104 /*--------------------------------------------------------------------------- 105 There are two things we can do if we can't find the entry: ignore it or 106 scream. The most likely reason for it not to be here is the user calling 107 this routine twice. Since this could cause BIG problems if any globals 108 are accessed after the first call, we'd better scream. 109 ---------------------------------------------------------------------------*/ 110 111 if (scan == THREADID_ENTRIES || threadPtrTable[scan] != pG) { 112 ZCONST char *noEntry; 113 if (scan == THREADID_ENTRIES) 114 noEntry = LoadFarString(EntryNotFound); 115 else 116 noEntry = LoadFarString(GlobalPointerMismatch); 117 Info(slide, 0x421, ((char *)slide, noEntry)); 118 EXIT(PK_WARN); /* programming error, but after we're all done */ 119 } 120 121 threadIdTable [scan] = 0; 122 lastScan = scan; 123 free(threadPtrTable[scan]); 124 } 125 126 127 128 Uz_Globs *getGlobalPointer() 129 { 130 int scan=0; 131 ulg tid = GetThreadId(); 132 133 while (threadIdTable[scan] != tid && scan < THREADID_ENTRIES) 134 scan++; 135 136 /*--------------------------------------------------------------------------- 137 There are two things we can do if we can't find the entry: ignore it or 138 scream. The most likely reason for it not to be here is the user calling 139 this routine twice. Since this could cause BIG problems if any globals 140 are accessed after the first call, we'd better scream. 141 ---------------------------------------------------------------------------*/ 142 143 if (scan == THREADID_ENTRIES) { 144 ZCONST char *noEntry = LoadFarString(EntryNotFound); 145 fprintf(stderr, noEntry); /* can't use Info w/o a global pointer */ 146 EXIT(PK_ERR); /* programming error while still working */ 147 } 148 149 return threadPtrTable[scan]; 150 } 151 152 # endif /* ?USETHREADID */ 153 #endif /* ?REENTRANT */ 154 155 156 157 Uz_Globs *globalsCtor() 158 { 159 #ifdef REENTRANT 160 Uz_Globs *pG = (Uz_Globs *)malloc(sizeof(Uz_Globs)); 161 162 if (!pG) 163 return (Uz_Globs *)NULL; 164 #endif /* REENTRANT */ 165 166 /* for REENTRANT version, G is defined as (*pG) */ 167 168 memzero(&G, sizeof(Uz_Globs)); 169 170 #ifndef FUNZIP 171 #ifdef CMS_MVS 172 uO.aflag=1; 173 uO.C_flag=1; 174 #endif 175 #ifdef TANDEM 176 uO.aflag=1; /* default to '-a' auto create Text Files as type 101 */ 177 #endif 178 179 uO.lflag=(-1); 180 G.wildzipfn = ""; 181 G.pfnames = (char **)fnames; 182 G.pxnames = (char **)&fnames[1]; 183 G.pInfo = G.info; 184 G.sol = TRUE; /* at start of line */ 185 186 G.message = UzpMessagePrnt; 187 G.input = UzpInput; /* not used by anyone at the moment... */ 188 #if defined(WINDLL) || defined(MACOS) 189 G.mpause = NULL; /* has scrollbars: no need for pausing */ 190 #else 191 G.mpause = UzpMorePause; 192 #endif 193 G.decr_passwd = UzpPassword; 194 #endif /* !FUNZIP */ 195 196 #if (!defined(DOS_FLX_H68_NLM_OS2_W32) && !defined(AMIGA) && !defined(RISCOS)) 197 #if (!defined(MACOS) && !defined(ATARI) && !defined(VMS)) 198 G.echofd = -1; 199 #endif /* !(MACOS || ATARI || VMS) */ 200 #endif /* !(DOS_FLX_H68_NLM_OS2_W32 || AMIGA || RISCOS) */ 201 202 #ifdef SYSTEM_SPECIFIC_CTOR 203 SYSTEM_SPECIFIC_CTOR(__G); 204 #endif 205 206 #ifdef REENTRANT 207 #ifdef USETHREADID 208 registerGlobalPointer(__G); 209 #else 210 GG = &G; 211 #endif /* ?USETHREADID */ 212 #endif /* REENTRANT */ 213 214 return &G; 215 } 216