diff options
Diffstat (limited to 'macos/source/getenv.c')
-rw-r--r-- | macos/source/getenv.c | 398 |
1 files changed, 398 insertions, 0 deletions
diff --git a/macos/source/getenv.c b/macos/source/getenv.c new file mode 100644 index 0000000..586815d --- /dev/null +++ b/macos/source/getenv.c @@ -0,0 +1,398 @@ +/* + Copyright (c) 1990-2005 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2004-May-22 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* + +This file implements the getenv() function. + +# Background: +# Under Unix: Each Process (= running Program) has a set of +# associated variables. The variables are called enviroment +# variables and, together, constitute the process environment. +# These variables include the search path, the terminal type, +# and the user's login name. + +# Unfortunatelly the MacOS has no equivalent. So we need +# a file to define the environment variables. +# Name of this file is "MacZip.Env". It can be placed +# in the current folder of MacZip or in the +# preference folder of the system disk. +# If MacZip founds the "MacZip.Env" file in the current +# the folder of MacZip the "MacZip.Env" file in the +# preference folder will be ignored. + +# An environment variable has a name and a value: +# Name=Value +# Note: Spaces are significant: +# ZIPOPT=-r and +# ZIPOPT = -r are different !!! + + + */ + +/*****************************************************************************/ +/* Includes */ +/*****************************************************************************/ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <time.h> +#include <unix.h> +#include <Files.h> +#include <Folders.h> + +#include "pathname.h" +#include "helpers.h" + +/*****************************************************************************/ +/* Module level Vars */ +/*****************************************************************************/ + +static char ListAllKeyValues = 0; +static unsigned LineNumber = 0; +static char CompletePath[NAME_MAX]; +Boolean IgnoreEnvironment = false; /* used by dialog.c and initfunc.c + of the Mainapp */ + +/*****************************************************************************/ +/* Macros, typedefs */ +/*****************************************************************************/ + +typedef struct _EnviromentPair { + char *key; + char *value; +} EnviromentPair; + + +#define MAX_COMMAND 1024 + + +/*****************************************************************************/ +/* Prototypes */ +/*****************************************************************************/ + + +int get_char(FILE *file); +void unget_char(int ch,FILE *file); +int get_string(char *string,int size, FILE *file, char *terms); +void skip_comments(FILE *file); +char *load_entry(FILE *file); +char *getenv(const char *name); +EnviromentPair *ParseLine(char *line); +OSErr FSpFindFolder_Name(short vRefNum, OSType folderType, + Boolean createFolder,FSSpec *spec, unsigned char *name); +FILE * FSp_fopen(ConstFSSpecPtr spec, const char * open_mode); +void ShowAllKeyValues(void); +void Set_LineNum(unsigned ln); + +/*****************************************************************************/ +/* Functions */ +/*****************************************************************************/ + + +/* get_string(str, max, file, termstr) : like fgets() but + * (1) has terminator string which should include \n + * (2) will always leave room for the null + * (3) uses get_char() so LineNumber will be accurate + * (4) returns EOF or terminating character, whichever + */ +int get_string(char *string, int size, FILE *file, char *terms) +{ + int ch; + + while (EOF != (ch = get_char(file)) && !strchr(terms, ch)) { + if (size > 1) { + *string++ = (char) ch; + size--; + } + } + + if (size > 0) + { + *string = '\0'; + } + + return ch; +} + + + + +void Set_LineNum(unsigned ln) +{ + LineNumber = ln; +} + + + +/* get_char(file) : like getc() but increment LineNumber on newlines + */ +int get_char(FILE *file) +{ + int ch; + + ch = getc(file); + if (ch == '\n') + { + Set_LineNum(LineNumber + 1); + } + + return ch; +} + + + + +/* skip_comments(file) : read past comment (if any) + */ +void skip_comments(FILE *file) +{ + int ch; + + while (EOF != (ch = get_char(file))) + { + /* ch is now the first character of a line. + */ + + while (ch == ' ' || ch == '\t') + { + ch = get_char(file); + } + + if (ch == EOF) + { + break; + } + + /* ch is now the first non-blank character of a line. + */ + + if (ch != '\n' && ch != '#') + { + break; + } + + /* ch must be a newline or comment as first non-blank + * character on a line. + */ + + while (ch != '\n' && ch != EOF) + { + ch = get_char(file); + } + + /* ch is now the newline of a line which we're going to + * ignore. + */ + } + + if (ch != EOF) + { + unget_char(ch, file); + } +} + + + + +/* unget_char(ch, file) : like ungetc but do LineNumber processing + */ +void unget_char(int ch, FILE *file) +{ + ungetc(ch, file); + if (ch == '\n') + { + Set_LineNum(LineNumber - 1); + } +} + + +/* this function reads one file entry -- the next -- from a file. +* it skips any leading blank lines, ignores comments, and returns +* NULL if for any reason the entry can't be read and parsed. +*/ + +char *load_entry(FILE *file) +{ + int ch; + static char cmd[MAX_COMMAND]; + + skip_comments(file); + + ch = get_string(cmd, MAX_COMMAND, file, "\n"); + + if (ch == EOF) + { + return NULL; + } + + return cmd; +} + + + + + +EnviromentPair *ParseLine(char *line) +{ +char *tmpPtr; +static EnviromentPair *Env; +unsigned short length = strlen(line); + +Env->key = ""; +Env->value = ""; + +for (tmpPtr = line; *tmpPtr; tmpPtr++) + { + if (*tmpPtr == '=') + { + *tmpPtr = 0; + Env->key = line; + if (strlen(Env->key) < length) + { + Env->value = ++tmpPtr; + } + return Env; + } + } +return Env; +} + + + + + +char *getenv(const char *name) +{ +FILE *fp; +char *LineStr = NULL; +EnviromentPair *Env1; +FSSpec spec; +OSErr err; + +if (IgnoreEnvironment) + return NULL; /* user wants to ignore the environment vars */ + +if (name == NULL) + return NULL; + +GetCompletePath(CompletePath,"MacZip.Env",&spec,&err); + +/* try open the file in the current folder */ +fp = FSp_fopen(&spec,"r"); +if (fp == NULL) + { /* Okey, lets try open the file in the preference folder */ + FSpFindFolder_Name( + kOnSystemDisk, + kPreferencesFolderType, + kDontCreateFolder, + &spec, + "\pMacZip.Env"); + fp = FSp_fopen(&spec,"r"); + if (fp == NULL) + { + return NULL; /* there is no enviroment-file */ + } + } + +LineStr = load_entry(fp); +while (LineStr != NULL) + { /* parse the file line by line */ + Env1 = ParseLine(LineStr); + if (strlen(Env1->value) > 0) + { /* we found a key/value pair */ + if (ListAllKeyValues) + printf("\n Line:%3d [%s] = [%s]",LineNumber,Env1->key,Env1->value); + if (stricmp(name,Env1->key) == 0) + { /* we found the value of a given key */ + return Env1->value; + } + } + LineStr = load_entry(fp); /* read next line */ + } +fclose(fp); + +return NULL; +} + + + + + +OSErr FSpFindFolder_Name( + short vRefNum, /* Volume reference number. */ + OSType folderType, /* Folder type taken by FindFolder. */ + Boolean createFolder, /* Should we create it if non-existant. */ + FSSpec *spec, /* Pointer to resulting directory. */ + unsigned char *name) /* Name of the file in the folder */ +{ + short foundVRefNum; + long foundDirID; + OSErr err; + + err = FindFolder(vRefNum, folderType, createFolder, + &foundVRefNum, &foundDirID); + if (err != noErr) + { + return err; + } + + err = FSMakeFSSpec(foundVRefNum, foundDirID, name, spec); + return err; +} + + + + +void ShowAllKeyValues(void) +{ +OSErr err; +FSSpec spec; +Boolean tmpIgnoreEnvironment = IgnoreEnvironment; + +ListAllKeyValues = 1; +IgnoreEnvironment = false; + +GetCompletePath(CompletePath,"MacZip.Env",&spec,&err); +if (err != 0) + { /* Okey, lets try open the file in the preference folder */ + FSpFindFolder_Name( + kOnSystemDisk, + kPreferencesFolderType, + kDontCreateFolder, + &spec, + "\pMacZip.Env"); + GetFullPathFromSpec(CompletePath,&spec, &err); + if (err != 0) + { + return; /* there is no enviroment-file */ + } + } + +printf("\nLocation of the current \"MacZip.Env\" file:\n [%s]",CompletePath); + +printf("\n\nList of all environment variables\n"); +getenv(" "); +printf("\n\nEnd\n\n"); + +/* restore used variables */ +ListAllKeyValues = 0; +LineNumber = 0; +IgnoreEnvironment = tmpIgnoreEnvironment; +} + + + + + + + + + + |