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 zip.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 This file implements the getenv() function.
12 
13 #  Background:
14 #  Under Unix: Each Process (= running Program) has a set of
15 #  associated variables. The variables are called enviroment
16 #  variables and, together, constitute the process environment.
17 #  These variables include the search path, the terminal type,
18 #  and the user's login name.
19 
20 #  Unfortunatelly the MacOS has no equivalent. So we need
21 #  a file to define the environment variables.
22 #  Name of this file is "MacZip.Env". It can be placed
23 #  in the current folder of MacZip or in the
24 #  preference folder of the system disk.
25 #  If MacZip founds the "MacZip.Env" file in the current
26 #  the folder of MacZip the "MacZip.Env" file in the
27 #  preference folder will be ignored.
28 
29 #  An environment variable has a name and a value:
30 #  Name=Value
31 #  Note: Spaces are significant:
32 #  ZIPOPT=-r  and
33 #  ZIPOPT = -r are different !!!
34 
35 
36  */
37 
38 /*****************************************************************************/
39 /*  Includes                                                                 */
40 /*****************************************************************************/
41 
42 #include <stdio.h>
43 #include <string.h>
44 #include <stdlib.h>
45 #include <time.h>
46 #include <unix.h>
47 #include <Files.h>
48 #include <Folders.h>
49 
50 #include "pathname.h"
51 #include "helpers.h"
52 
53 /*****************************************************************************/
54 /*  Module level Vars                                                        */
55 /*****************************************************************************/
56 
57 static char ListAllKeyValues = 0;
58 static unsigned LineNumber   = 0;
59 static char CompletePath[NAME_MAX];
60 Boolean IgnoreEnvironment    = false;  /* used by dialog.c and initfunc.c
61                                           of the Mainapp */
62 
63 /*****************************************************************************/
64 /*  Macros, typedefs                                                         */
65 /*****************************************************************************/
66 
67 typedef struct _EnviromentPair {
68     char *key;
69     char *value;
70 } EnviromentPair;
71 
72 
73 #define MAX_COMMAND 1024
74 
75 
76 /*****************************************************************************/
77 /*  Prototypes                                                               */
78 /*****************************************************************************/
79 
80 
81 int get_char(FILE *file);
82 void unget_char(int ch,FILE *file);
83 int get_string(char *string,int size, FILE *file, char *terms);
84 void skip_comments(FILE *file);
85 char *load_entry(FILE *file);
86 char *getenv(const char *name);
87 EnviromentPair *ParseLine(char *line);
88 OSErr FSpFindFolder_Name(short vRefNum, OSType folderType,
89                          Boolean createFolder,FSSpec *spec, unsigned char *name);
90 FILE * FSp_fopen(ConstFSSpecPtr spec, const char * open_mode);
91 void ShowAllKeyValues(void);
92 void Set_LineNum(unsigned ln);
93 
94 /*****************************************************************************/
95 /*  Functions                                                                */
96 /*****************************************************************************/
97 
98 
99 /* get_string(str, max, file, termstr) : like fgets() but
100  *      (1) has terminator string which should include \n
101  *      (2) will always leave room for the null
102  *      (3) uses get_char() so LineNumber will be accurate
103  *      (4) returns EOF or terminating character, whichever
104  */
get_string(char * string,int size,FILE * file,char * terms)105 int get_string(char *string, int size, FILE *file, char *terms)
106 {
107     int ch;
108 
109     while (EOF != (ch = get_char(file)) && !strchr(terms, ch)) {
110         if (size > 1) {
111             *string++ = (char) ch;
112             size--;
113         }
114     }
115 
116     if (size > 0)
117         {
118         *string = '\0';
119         }
120 
121     return ch;
122 }
123 
124 
125 
126 
Set_LineNum(unsigned ln)127 void Set_LineNum(unsigned ln)
128 {
129  LineNumber = ln;
130 }
131 
132 
133 
134 /* get_char(file) : like getc() but increment LineNumber on newlines
135  */
get_char(FILE * file)136 int get_char(FILE *file)
137 {
138     int ch;
139 
140     ch = getc(file);
141     if (ch == '\n')
142         {
143         Set_LineNum(LineNumber + 1);
144         }
145 
146     return ch;
147 }
148 
149 
150 
151 
152 /* skip_comments(file) : read past comment (if any)
153  */
skip_comments(FILE * file)154 void skip_comments(FILE *file)
155 {
156     int ch;
157 
158     while (EOF != (ch = get_char(file)))
159         {
160         /* ch is now the first character of a line.
161          */
162 
163         while (ch == ' ' || ch == '\t')
164             {
165             ch = get_char(file);
166             }
167 
168         if (ch == EOF)
169             {
170             break;
171             }
172 
173         /* ch is now the first non-blank character of a line.
174          */
175 
176         if (ch != '\n' && ch != '#')
177             {
178             break;
179             }
180 
181         /* ch must be a newline or comment as first non-blank
182          * character on a line.
183          */
184 
185         while (ch != '\n' && ch != EOF)
186             {
187             ch = get_char(file);
188             }
189 
190         /* ch is now the newline of a line which we're going to
191          * ignore.
192          */
193     }
194 
195     if (ch != EOF)
196         {
197         unget_char(ch, file);
198         }
199 }
200 
201 
202 
203 
204 /* unget_char(ch, file) : like ungetc but do LineNumber processing
205  */
unget_char(int ch,FILE * file)206 void unget_char(int ch, FILE *file)
207 {
208     ungetc(ch, file);
209     if (ch == '\n')
210         {
211         Set_LineNum(LineNumber - 1);
212         }
213 }
214 
215 
216 /* this function reads one file entry -- the next -- from a file.
217 *  it skips any leading blank lines, ignores comments, and returns
218 *  NULL if for any reason the entry can't be read and parsed.
219 */
220 
load_entry(FILE * file)221 char *load_entry(FILE *file)
222 {
223     int ch;
224     static char cmd[MAX_COMMAND];
225 
226     skip_comments(file);
227 
228     ch = get_string(cmd, MAX_COMMAND, file, "\n");
229 
230     if (ch == EOF)
231         {
232         return NULL;
233         }
234 
235     return cmd;
236 }
237 
238 
239 
240 
241 
ParseLine(char * line)242 EnviromentPair *ParseLine(char *line)
243 {
244 char *tmpPtr;
245 static EnviromentPair *Env;
246 unsigned short length = strlen(line);
247 
248 Env->key   = "";
249 Env->value = "";
250 
251 for (tmpPtr = line; *tmpPtr; tmpPtr++)
252     {
253     if (*tmpPtr == '=')
254         {
255         *tmpPtr = 0;
256         Env->key = line;
257         if (strlen(Env->key) < length)
258             {
259             Env->value = ++tmpPtr;
260             }
261         return Env;
262         }
263     }
264 return Env;
265 }
266 
267 
268 
269 
270 
getenv(const char * name)271 char *getenv(const char *name)
272 {
273 FILE *fp;
274 char *LineStr = NULL;
275 EnviromentPair *Env1;
276 FSSpec spec;
277 OSErr err;
278 
279 if (IgnoreEnvironment)
280     return NULL;  /* user wants to ignore the environment vars */
281 
282 if (name == NULL)
283     return NULL;
284 
285 GetCompletePath(CompletePath,"MacZip.Env",&spec,&err);
286 
287 /* try open the file in the current folder */
288 fp = FSp_fopen(&spec,"r");
289 if (fp == NULL)
290     { /* Okey, lets try open the file in the preference folder */
291     FSpFindFolder_Name(
292                    kOnSystemDisk,
293                    kPreferencesFolderType,
294                    kDontCreateFolder,
295                    &spec,
296                    "\pMacZip.Env");
297     fp = FSp_fopen(&spec,"r");
298     if (fp == NULL)
299         {
300         return NULL; /* there is no enviroment-file */
301         }
302     }
303 
304 LineStr = load_entry(fp);
305 while (LineStr != NULL)
306     {   /* parse the file line by line */
307     Env1 = ParseLine(LineStr);
308     if (strlen(Env1->value) > 0)
309         {       /* we found a key/value pair */
310         if (ListAllKeyValues)
311             printf("\n   Line:%3d   [%s] = [%s]",LineNumber,Env1->key,Env1->value);
312         if (stricmp(name,Env1->key) == 0)
313             {   /* we found the value of a given key */
314             return Env1->value;
315             }
316         }
317     LineStr = load_entry(fp);  /* read next line */
318     }
319 fclose(fp);
320 
321 return NULL;
322 }
323 
324 
325 
326 
327 
FSpFindFolder_Name(short vRefNum,OSType folderType,Boolean createFolder,FSSpec * spec,unsigned char * name)328 OSErr FSpFindFolder_Name(
329     short vRefNum,          /* Volume reference number. */
330     OSType folderType,      /* Folder type taken by FindFolder. */
331     Boolean createFolder,   /* Should we create it if non-existant. */
332     FSSpec *spec,           /* Pointer to resulting directory. */
333     unsigned char *name)    /* Name of the file in the folder */
334 {
335     short foundVRefNum;
336     long foundDirID;
337     OSErr err;
338 
339     err = FindFolder(vRefNum, folderType, createFolder,
340                      &foundVRefNum, &foundDirID);
341     if (err != noErr)
342         {
343         return err;
344         }
345 
346     err = FSMakeFSSpec(foundVRefNum, foundDirID, name, spec);
347     return err;
348 }
349 
350 
351 
352 
ShowAllKeyValues(void)353 void ShowAllKeyValues(void)
354 {
355 OSErr err;
356 FSSpec spec;
357 Boolean tmpIgnoreEnvironment = IgnoreEnvironment;
358 
359 ListAllKeyValues = 1;
360 IgnoreEnvironment = false;
361 
362 GetCompletePath(CompletePath,"MacZip.Env",&spec,&err);
363 if (err != 0)
364     { /* Okey, lets try open the file in the preference folder */
365     FSpFindFolder_Name(
366                    kOnSystemDisk,
367                    kPreferencesFolderType,
368                    kDontCreateFolder,
369                    &spec,
370                    "\pMacZip.Env");
371     GetFullPathFromSpec(CompletePath,&spec, &err);
372     if (err != 0)
373         {
374         return; /* there is no enviroment-file */
375         }
376     }
377 
378 printf("\nLocation of the current \"MacZip.Env\" file:\n [%s]",CompletePath);
379 
380 printf("\n\nList of all environment variables\n");
381 getenv(" ");
382 printf("\n\nEnd\n\n");
383 
384 /* restore used variables */
385 ListAllKeyValues = 0;
386 LineNumber = 0;
387 IgnoreEnvironment = tmpIgnoreEnvironment;
388 }
389 
390 
391 
392 
393 
394 
395 
396 
397 
398 
399