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 */
30char central_hdr_sig[4] = {0, 0, 0x01, 0x02};
31char local_hdr_sig[4]   = {0, 0, 0x03, 0x04};
32char end_central_sig[4] = {0, 0, 0x05, 0x06};
33/* extern char extd_local_sig[4] = {0, 0, 0x07, 0x08};  NOT USED YET */
34
35ZCONST 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
67static void registerGlobalPointer OF((__GPRO));
68
69
70
71static 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
94void 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
128Uz_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
157Uz_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