184f33deaSJordan K. Hubbard /* Copyright 1988,1990,1993,1994 by Paul Vixie 284f33deaSJordan K. Hubbard * All rights reserved 384f33deaSJordan K. Hubbard * 484f33deaSJordan K. Hubbard * Distribute freely, except: don't remove my name from the source or 584f33deaSJordan K. Hubbard * documentation (don't take credit for my work), mark your changes (don't 684f33deaSJordan K. Hubbard * get me blamed for your possible bugs), don't alter or remove this 784f33deaSJordan K. Hubbard * notice. May be sold if buildable source is provided to buyer. No 884f33deaSJordan K. Hubbard * warrantee of any kind, express or implied, is included with this 984f33deaSJordan K. Hubbard * software; use at your own risk, responsibility for damages (if any) to 1084f33deaSJordan K. Hubbard * anyone resulting from the use of this software rests entirely with the 1184f33deaSJordan K. Hubbard * user. 1284f33deaSJordan K. Hubbard * 1384f33deaSJordan K. Hubbard * Send bug reports, bug fixes, enhancements, requests, flames, etc., and 1484f33deaSJordan K. Hubbard * I'll try to keep a version up to date. I can be reached as follows: 1584f33deaSJordan K. Hubbard * Paul Vixie <paul@vix.com> uunet!decwrl!vixie!paul 1684f33deaSJordan K. Hubbard */ 1784f33deaSJordan K. Hubbard 1884f33deaSJordan K. Hubbard #if !defined(lint) && !defined(LINT) 19401e6468SPhilippe Charnier static const char rcsid[] = 2097d92980SPeter Wemm "$FreeBSD$"; 2184f33deaSJordan K. Hubbard #endif 2284f33deaSJordan K. Hubbard 2384f33deaSJordan K. Hubbard 2484f33deaSJordan K. Hubbard #include "cron.h" 2584f33deaSJordan K. Hubbard 2684f33deaSJordan K. Hubbard 2784f33deaSJordan K. Hubbard char ** 2884f33deaSJordan K. Hubbard env_init() 2984f33deaSJordan K. Hubbard { 30d02e530bSGuy Helmer register char **p = (char **) malloc(sizeof(char *)); 3184f33deaSJordan K. Hubbard 32bdddbd2fSPaul Traina if (p) 3384f33deaSJordan K. Hubbard p[0] = NULL; 3484f33deaSJordan K. Hubbard return (p); 3584f33deaSJordan K. Hubbard } 3684f33deaSJordan K. Hubbard 3784f33deaSJordan K. Hubbard 3884f33deaSJordan K. Hubbard void 3984f33deaSJordan K. Hubbard env_free(envp) 4084f33deaSJordan K. Hubbard char **envp; 4184f33deaSJordan K. Hubbard { 4284f33deaSJordan K. Hubbard char **p; 4384f33deaSJordan K. Hubbard 444a9e66b5SDavid Nugent if ((p = envp)) 454a9e66b5SDavid Nugent for (; *p; p++) 4684f33deaSJordan K. Hubbard free(*p); 4784f33deaSJordan K. Hubbard free(envp); 4884f33deaSJordan K. Hubbard } 4984f33deaSJordan K. Hubbard 5084f33deaSJordan K. Hubbard 5184f33deaSJordan K. Hubbard char ** 5284f33deaSJordan K. Hubbard env_copy(envp) 5384f33deaSJordan K. Hubbard register char **envp; 5484f33deaSJordan K. Hubbard { 5584f33deaSJordan K. Hubbard register int count, i; 5684f33deaSJordan K. Hubbard register char **p; 5784f33deaSJordan K. Hubbard 5884f33deaSJordan K. Hubbard for (count = 0; envp[count] != NULL; count++) 5984f33deaSJordan K. Hubbard ; 60d02e530bSGuy Helmer p = (char **) malloc((count+1) * sizeof(char *)); /* 1 for the NULL */ 61bdddbd2fSPaul Traina if (p == NULL) { 62bdddbd2fSPaul Traina errno = ENOMEM; 63bdddbd2fSPaul Traina return NULL; 64bdddbd2fSPaul Traina } 6584f33deaSJordan K. Hubbard for (i = 0; i < count; i++) 66bdddbd2fSPaul Traina if ((p[i] = strdup(envp[i])) == NULL) { 67bdddbd2fSPaul Traina while (--i >= 0) 68bdddbd2fSPaul Traina (void) free(p[i]); 69bdddbd2fSPaul Traina free(p); 70bdddbd2fSPaul Traina errno = ENOMEM; 71bdddbd2fSPaul Traina return NULL; 72bdddbd2fSPaul Traina } 7384f33deaSJordan K. Hubbard p[count] = NULL; 7484f33deaSJordan K. Hubbard return (p); 7584f33deaSJordan K. Hubbard } 7684f33deaSJordan K. Hubbard 7784f33deaSJordan K. Hubbard 7884f33deaSJordan K. Hubbard char ** 7984f33deaSJordan K. Hubbard env_set(envp, envstr) 8084f33deaSJordan K. Hubbard char **envp; 8184f33deaSJordan K. Hubbard char *envstr; 8284f33deaSJordan K. Hubbard { 8384f33deaSJordan K. Hubbard register int count, found; 8484f33deaSJordan K. Hubbard register char **p; 858261236dSGuy Helmer char *q; 8684f33deaSJordan K. Hubbard 8784f33deaSJordan K. Hubbard /* 8884f33deaSJordan K. Hubbard * count the number of elements, including the null pointer; 8984f33deaSJordan K. Hubbard * also set 'found' to -1 or index of entry if already in here. 9084f33deaSJordan K. Hubbard */ 9184f33deaSJordan K. Hubbard found = -1; 9284f33deaSJordan K. Hubbard for (count = 0; envp[count] != NULL; count++) { 9384f33deaSJordan K. Hubbard if (!strcmp_until(envp[count], envstr, '=')) 9484f33deaSJordan K. Hubbard found = count; 9584f33deaSJordan K. Hubbard } 9684f33deaSJordan K. Hubbard count++; /* for the NULL */ 9784f33deaSJordan K. Hubbard 9884f33deaSJordan K. Hubbard if (found != -1) { 9984f33deaSJordan K. Hubbard /* 10084f33deaSJordan K. Hubbard * it exists already, so just free the existing setting, 10184f33deaSJordan K. Hubbard * save our new one there, and return the existing array. 10284f33deaSJordan K. Hubbard */ 1038261236dSGuy Helmer q = envp[found]; 104bdddbd2fSPaul Traina if ((envp[found] = strdup(envstr)) == NULL) { 1058261236dSGuy Helmer envp[found] = q; 1068261236dSGuy Helmer /* XXX env_free(envp); */ 107bdddbd2fSPaul Traina errno = ENOMEM; 108bdddbd2fSPaul Traina return NULL; 109bdddbd2fSPaul Traina } 1108261236dSGuy Helmer free(q); 11184f33deaSJordan K. Hubbard return (envp); 11284f33deaSJordan K. Hubbard } 11384f33deaSJordan K. Hubbard 11484f33deaSJordan K. Hubbard /* 11584f33deaSJordan K. Hubbard * it doesn't exist yet, so resize the array, move null pointer over 11684f33deaSJordan K. Hubbard * one, save our string over the old null pointer, and return resized 11784f33deaSJordan K. Hubbard * array. 11884f33deaSJordan K. Hubbard */ 11984f33deaSJordan K. Hubbard p = (char **) realloc((void *) envp, 120d02e530bSGuy Helmer (unsigned) ((count+1) * sizeof(char *))); 121bdddbd2fSPaul Traina if (p == NULL) { 1228261236dSGuy Helmer /* XXX env_free(envp); */ 123bdddbd2fSPaul Traina errno = ENOMEM; 124bdddbd2fSPaul Traina return NULL; 125bdddbd2fSPaul Traina } 12684f33deaSJordan K. Hubbard p[count] = p[count-1]; 127bdddbd2fSPaul Traina if ((p[count-1] = strdup(envstr)) == NULL) { 1288261236dSGuy Helmer env_free(p); 129bdddbd2fSPaul Traina errno = ENOMEM; 130bdddbd2fSPaul Traina return NULL; 131bdddbd2fSPaul Traina } 13284f33deaSJordan K. Hubbard return (p); 13384f33deaSJordan K. Hubbard } 13484f33deaSJordan K. Hubbard 13584f33deaSJordan K. Hubbard 13684f33deaSJordan K. Hubbard /* return ERR = end of file 13784f33deaSJordan K. Hubbard * FALSE = not an env setting (file was repositioned) 13884f33deaSJordan K. Hubbard * TRUE = was an env setting 13984f33deaSJordan K. Hubbard */ 14084f33deaSJordan K. Hubbard int 14184f33deaSJordan K. Hubbard load_env(envstr, f) 14284f33deaSJordan K. Hubbard char *envstr; 14384f33deaSJordan K. Hubbard FILE *f; 14484f33deaSJordan K. Hubbard { 14584f33deaSJordan K. Hubbard long filepos; 14684f33deaSJordan K. Hubbard int fileline; 147482bfcccSPaul Traina char name[MAX_ENVSTR], val[MAX_ENVSTR]; 148bb817201SOllivier Robert char quotechar, *c, *str; 149bb817201SOllivier Robert int state; 150bb817201SOllivier Robert 151bb817201SOllivier Robert /* The following states are traversed in order: */ 152bb817201SOllivier Robert #define NAMEI 0 /* First char of NAME, may be quote */ 153bb817201SOllivier Robert #define NAME 1 /* Subsequent chars of NAME */ 154bb817201SOllivier Robert #define EQ1 2 /* After end of name, looking for '=' sign */ 155bb817201SOllivier Robert #define EQ2 3 /* After '=', skipping whitespace */ 156bb817201SOllivier Robert #define VALUEI 4 /* First char of VALUE, may be quote */ 157bb817201SOllivier Robert #define VALUE 5 /* Subsequent chars of VALUE */ 158bb817201SOllivier Robert #define FINI 6 /* All done, skipping trailing whitespace */ 159bb817201SOllivier Robert #define ERROR 7 /* Error */ 16084f33deaSJordan K. Hubbard 16184f33deaSJordan K. Hubbard filepos = ftell(f); 16284f33deaSJordan K. Hubbard fileline = LineNumber; 16384f33deaSJordan K. Hubbard skip_comments(f); 16484f33deaSJordan K. Hubbard if (EOF == get_string(envstr, MAX_ENVSTR, f, "\n")) 16584f33deaSJordan K. Hubbard return (ERR); 16684f33deaSJordan K. Hubbard 167bb817201SOllivier Robert Debug(DPARS, ("load_env, read <%s>\n", envstr)); 16884f33deaSJordan K. Hubbard 169bb817201SOllivier Robert bzero (name, sizeof name); 170bb817201SOllivier Robert bzero (val, sizeof val); 171bb817201SOllivier Robert str = name; 172bb817201SOllivier Robert state = NAMEI; 173bb817201SOllivier Robert quotechar = '\0'; 174bb817201SOllivier Robert c = envstr; 175bb817201SOllivier Robert while (state != ERROR && *c) { 176bb817201SOllivier Robert switch (state) { 177bb817201SOllivier Robert case NAMEI: 178bb817201SOllivier Robert case VALUEI: 179bb817201SOllivier Robert if (*c == '\'' || *c == '"') 180bb817201SOllivier Robert quotechar = *c++; 181bb817201SOllivier Robert ++state; 182bb817201SOllivier Robert /* FALLTHROUGH */ 183bb817201SOllivier Robert case NAME: 184bb817201SOllivier Robert case VALUE: 185bb817201SOllivier Robert if (quotechar) { 186bb817201SOllivier Robert if (*c == quotechar) { 187bb817201SOllivier Robert state++; 188bb817201SOllivier Robert c++; 189bb817201SOllivier Robert break; 190bb817201SOllivier Robert } 191bb817201SOllivier Robert if (state == NAME && *c == '=') { 192bb817201SOllivier Robert state = ERROR; 193bb817201SOllivier Robert break; 194bb817201SOllivier Robert } 195bb817201SOllivier Robert } else { 1966ced08bfSThomas Quinot if (state == NAME) { 197bb817201SOllivier Robert if (isspace (*c)) { 198bb817201SOllivier Robert c++; 1996ced08bfSThomas Quinot state++; 200bb817201SOllivier Robert break; 201bb817201SOllivier Robert } 2026ced08bfSThomas Quinot if (*c == '=') { 203bb817201SOllivier Robert state++; 204bb817201SOllivier Robert break; 205bb817201SOllivier Robert } 206bb817201SOllivier Robert } 2076ced08bfSThomas Quinot } 208bb817201SOllivier Robert *str++ = *c++; 209bb817201SOllivier Robert break; 210bb817201SOllivier Robert 211bb817201SOllivier Robert case EQ1: 212bb817201SOllivier Robert if (*c == '=') { 213bb817201SOllivier Robert state++; 214bb817201SOllivier Robert str = val; 215bb817201SOllivier Robert quotechar = '\0'; 216bb817201SOllivier Robert } else { 217bb817201SOllivier Robert if (!isspace (*c)) 218bb817201SOllivier Robert state = ERROR; 219bb817201SOllivier Robert } 220bb817201SOllivier Robert c++; 221bb817201SOllivier Robert break; 222bb817201SOllivier Robert case EQ2: 223bb817201SOllivier Robert case FINI: 224bb817201SOllivier Robert if (isspace (*c)) 225bb817201SOllivier Robert c++; 226bb817201SOllivier Robert else 227bb817201SOllivier Robert state++; 228bb817201SOllivier Robert break; 229bb817201SOllivier Robert } 230bb817201SOllivier Robert } 231bb817201SOllivier Robert if (state != FINI && !(state == VALUE && !quotechar)) { 232bb817201SOllivier Robert Debug(DPARS, ("load_env, parse error, state = %d\n", state)) 23384f33deaSJordan K. Hubbard fseek(f, filepos, 0); 23484f33deaSJordan K. Hubbard Set_LineNum(fileline); 23584f33deaSJordan K. Hubbard return (FALSE); 23684f33deaSJordan K. Hubbard } 2376ced08bfSThomas Quinot if (state == VALUE) { 2386ced08bfSThomas Quinot /* End of unquoted value: trim trailing whitespace */ 2396ced08bfSThomas Quinot c = val + strlen (val); 2406ced08bfSThomas Quinot while (c > val && isspace (*(c - 1))) 2416ced08bfSThomas Quinot *(--c) = '\0'; 2426ced08bfSThomas Quinot } 24384f33deaSJordan K. Hubbard 2446ced08bfSThomas Quinot /* 2 fields from parser; looks like an env setting */ 24584f33deaSJordan K. Hubbard 246bdddbd2fSPaul Traina if (strlen(name) + 1 + strlen(val) >= MAX_ENVSTR-1) 247bdddbd2fSPaul Traina return (FALSE); 24884f33deaSJordan K. Hubbard (void) sprintf(envstr, "%s=%s", name, val); 24984f33deaSJordan K. Hubbard Debug(DPARS, ("load_env, <%s> <%s> -> <%s>\n", name, val, envstr)) 25084f33deaSJordan K. Hubbard return (TRUE); 25184f33deaSJordan K. Hubbard } 25284f33deaSJordan K. Hubbard 25384f33deaSJordan K. Hubbard 25484f33deaSJordan K. Hubbard char * 25584f33deaSJordan K. Hubbard env_get(name, envp) 25684f33deaSJordan K. Hubbard register char *name; 25784f33deaSJordan K. Hubbard register char **envp; 25884f33deaSJordan K. Hubbard { 25984f33deaSJordan K. Hubbard register int len = strlen(name); 26084f33deaSJordan K. Hubbard register char *p, *q; 26184f33deaSJordan K. Hubbard 262401e6468SPhilippe Charnier while ((p = *envp++)) { 26384f33deaSJordan K. Hubbard if (!(q = strchr(p, '='))) 26484f33deaSJordan K. Hubbard continue; 26584f33deaSJordan K. Hubbard if ((q - p) == len && !strncmp(p, name, len)) 26684f33deaSJordan K. Hubbard return (q+1); 26784f33deaSJordan K. Hubbard } 26884f33deaSJordan K. Hubbard return (NULL); 26984f33deaSJordan K. Hubbard } 270