getenv.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. /*
  2. Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
  3. See the accompanying file LICENSE, version 2000-Apr-09 or later
  4. (the contents of which are also included in zip.h) for terms of use.
  5. If, for some reason, all these files are missing, the Info-ZIP license
  6. also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
  7. */
  8. /*
  9. This file implements the getenv() function.
  10. # Background:
  11. # Under Unix: Each Process (= running Program) has a set of
  12. # associated variables. The variables are called enviroment
  13. # variables and, together, constitute the process environment.
  14. # These variables include the search path, the terminal type,
  15. # and the user's login name.
  16. # Unfortunatelly the MacOS has no equivalent. So we need
  17. # a file to define the environment variables.
  18. # Name of this file is "MacZip.Env". It can be placed
  19. # in the current folder of MacZip or in the
  20. # preference folder of the system disk.
  21. # If MacZip founds the "MacZip.Env" file in the current
  22. # the folder of MacZip the "MacZip.Env" file in the
  23. # preference folder will be ignored.
  24. # An environment variable has a name and a value:
  25. # Name=Value
  26. # Note: Spaces are significant:
  27. # ZIPOPT=-r and
  28. # ZIPOPT = -r are different !!!
  29. */
  30. /*****************************************************************************/
  31. /* Includes */
  32. /*****************************************************************************/
  33. #include <stdio.h>
  34. #include <string.h>
  35. #include <stdlib.h>
  36. #include <time.h>
  37. #include <unix.h>
  38. #include <Files.h>
  39. #include <Folders.h>
  40. #include "pathname.h"
  41. #include "helpers.h"
  42. /*****************************************************************************/
  43. /* Module level Vars */
  44. /*****************************************************************************/
  45. static char ListAllKeyValues = 0;
  46. static unsigned LineNumber = 0;
  47. static char CompletePath[NAME_MAX];
  48. Boolean IgnoreEnvironment = false; /* used by dialog.c and initfunc.c
  49. of the Mainapp */
  50. /*****************************************************************************/
  51. /* Macros, typedefs */
  52. /*****************************************************************************/
  53. typedef struct _EnviromentPair {
  54. char *key;
  55. char *value;
  56. } EnviromentPair;
  57. #define MAX_COMMAND 1024
  58. /*****************************************************************************/
  59. /* Prototypes */
  60. /*****************************************************************************/
  61. int get_char(FILE *file);
  62. void unget_char(int ch,FILE *file);
  63. int get_string(char *string,int size, FILE *file, char *terms);
  64. void skip_comments(FILE *file);
  65. char *load_entry(FILE *file);
  66. char *getenv(const char *name);
  67. EnviromentPair *ParseLine(char *line);
  68. OSErr FSpFindFolder_Name(short vRefNum, OSType folderType,
  69. Boolean createFolder,FSSpec *spec, unsigned char *name);
  70. FILE * FSp_fopen(ConstFSSpecPtr spec, const char * open_mode);
  71. void ShowAllKeyValues(void);
  72. void Set_LineNum(unsigned ln);
  73. /*****************************************************************************/
  74. /* Functions */
  75. /*****************************************************************************/
  76. /* get_string(str, max, file, termstr) : like fgets() but
  77. * (1) has terminator string which should include \n
  78. * (2) will always leave room for the null
  79. * (3) uses get_char() so LineNumber will be accurate
  80. * (4) returns EOF or terminating character, whichever
  81. */
  82. int get_string(char *string, int size, FILE *file, char *terms)
  83. {
  84. int ch;
  85. while (EOF != (ch = get_char(file)) && !strchr(terms, ch)) {
  86. if (size > 1) {
  87. *string++ = (char) ch;
  88. size--;
  89. }
  90. }
  91. if (size > 0)
  92. {
  93. *string = '\0';
  94. }
  95. return ch;
  96. }
  97. void Set_LineNum(unsigned ln)
  98. {
  99. LineNumber = ln;
  100. }
  101. /* get_char(file) : like getc() but increment LineNumber on newlines
  102. */
  103. int get_char(FILE *file)
  104. {
  105. int ch;
  106. ch = getc(file);
  107. if (ch == '\n')
  108. {
  109. Set_LineNum(LineNumber + 1);
  110. }
  111. return ch;
  112. }
  113. /* skip_comments(file) : read past comment (if any)
  114. */
  115. void skip_comments(FILE *file)
  116. {
  117. int ch;
  118. while (EOF != (ch = get_char(file)))
  119. {
  120. /* ch is now the first character of a line.
  121. */
  122. while (ch == ' ' || ch == '\t')
  123. {
  124. ch = get_char(file);
  125. }
  126. if (ch == EOF)
  127. {
  128. break;
  129. }
  130. /* ch is now the first non-blank character of a line.
  131. */
  132. if (ch != '\n' && ch != '#')
  133. {
  134. break;
  135. }
  136. /* ch must be a newline or comment as first non-blank
  137. * character on a line.
  138. */
  139. while (ch != '\n' && ch != EOF)
  140. {
  141. ch = get_char(file);
  142. }
  143. /* ch is now the newline of a line which we're going to
  144. * ignore.
  145. */
  146. }
  147. if (ch != EOF)
  148. {
  149. unget_char(ch, file);
  150. }
  151. }
  152. /* unget_char(ch, file) : like ungetc but do LineNumber processing
  153. */
  154. void unget_char(int ch, FILE *file)
  155. {
  156. ungetc(ch, file);
  157. if (ch == '\n')
  158. {
  159. Set_LineNum(LineNumber - 1);
  160. }
  161. }
  162. /* this function reads one file entry -- the next -- from a file.
  163. * it skips any leading blank lines, ignores comments, and returns
  164. * NULL if for any reason the entry can't be read and parsed.
  165. */
  166. char *load_entry(FILE *file)
  167. {
  168. int ch;
  169. static char cmd[MAX_COMMAND];
  170. skip_comments(file);
  171. ch = get_string(cmd, MAX_COMMAND, file, "\n");
  172. if (ch == EOF)
  173. {
  174. return NULL;
  175. }
  176. return cmd;
  177. }
  178. EnviromentPair *ParseLine(char *line)
  179. {
  180. char *tmpPtr;
  181. static EnviromentPair *Env;
  182. unsigned short length = strlen(line);
  183. Env->key = "";
  184. Env->value = "";
  185. for (tmpPtr = line; *tmpPtr; tmpPtr++)
  186. {
  187. if (*tmpPtr == '=')
  188. {
  189. *tmpPtr = 0;
  190. Env->key = line;
  191. if (strlen(Env->key) < length)
  192. {
  193. Env->value = ++tmpPtr;
  194. }
  195. return Env;
  196. }
  197. }
  198. return Env;
  199. }
  200. char *getenv(const char *name)
  201. {
  202. FILE *fp;
  203. char *LineStr = NULL;
  204. EnviromentPair *Env1;
  205. FSSpec spec;
  206. OSErr err;
  207. if (IgnoreEnvironment)
  208. return NULL; /* user wants to ignore the environment vars */
  209. if (name == NULL)
  210. return NULL;
  211. GetCompletePath(CompletePath,"MacZip.Env",&spec,&err);
  212. /* try open the file in the current folder */
  213. fp = FSp_fopen(&spec,"r");
  214. if (fp == NULL)
  215. { /* Okey, lets try open the file in the preference folder */
  216. FSpFindFolder_Name(
  217. kOnSystemDisk,
  218. kPreferencesFolderType,
  219. kDontCreateFolder,
  220. &spec,
  221. "\pMacZip.Env");
  222. fp = FSp_fopen(&spec,"r");
  223. if (fp == NULL)
  224. {
  225. return NULL; /* there is no enviroment-file */
  226. }
  227. }
  228. LineStr = load_entry(fp);
  229. while (LineStr != NULL)
  230. { /* parse the file line by line */
  231. Env1 = ParseLine(LineStr);
  232. if (strlen(Env1->value) > 0)
  233. { /* we found a key/value pair */
  234. if (ListAllKeyValues)
  235. printf("\n Line:%3d [%s] = [%s]",LineNumber,Env1->key,Env1->value);
  236. if (stricmp(name,Env1->key) == 0)
  237. { /* we found the value of a given key */
  238. return Env1->value;
  239. }
  240. }
  241. LineStr = load_entry(fp); /* read next line */
  242. }
  243. fclose(fp);
  244. return NULL;
  245. }
  246. OSErr FSpFindFolder_Name(
  247. short vRefNum, /* Volume reference number. */
  248. OSType folderType, /* Folder type taken by FindFolder. */
  249. Boolean createFolder, /* Should we create it if non-existant. */
  250. FSSpec *spec, /* Pointer to resulting directory. */
  251. unsigned char *name) /* Name of the file in the folder */
  252. {
  253. short foundVRefNum;
  254. long foundDirID;
  255. OSErr err;
  256. err = FindFolder(vRefNum, folderType, createFolder,
  257. &foundVRefNum, &foundDirID);
  258. if (err != noErr)
  259. {
  260. return err;
  261. }
  262. err = FSMakeFSSpec(foundVRefNum, foundDirID, name, spec);
  263. return err;
  264. }
  265. void ShowAllKeyValues(void)
  266. {
  267. OSErr err;
  268. FSSpec spec;
  269. Boolean tmpIgnoreEnvironment = IgnoreEnvironment;
  270. ListAllKeyValues = 1;
  271. IgnoreEnvironment = false;
  272. GetCompletePath(CompletePath,"MacZip.Env",&spec,&err);
  273. if (err != 0)
  274. { /* Okey, lets try open the file in the preference folder */
  275. FSpFindFolder_Name(
  276. kOnSystemDisk,
  277. kPreferencesFolderType,
  278. kDontCreateFolder,
  279. &spec,
  280. "\pMacZip.Env");
  281. GetFullPathFromSpec(CompletePath,&spec, &err);
  282. if (err != 0)
  283. {
  284. return; /* there is no enviroment-file */
  285. }
  286. }
  287. printf("\nLocation of the current \"MacZip.Env\" file:\n [%s]",CompletePath);
  288. printf("\n\nList of all environment variables\n");
  289. getenv(" ");
  290. printf("\n\nEnd\n\n");
  291. /* restore used variables */
  292. ListAllKeyValues = 0;
  293. LineNumber = 0;
  294. IgnoreEnvironment = tmpIgnoreEnvironment;
  295. }