184f33deaSJordan K. Hubbard /* Copyright 1988,1990,1993,1994 by Paul Vixie 284f33deaSJordan K. Hubbard * All rights reserved 3*fe590ffeSEric van Gyzen */ 4*fe590ffeSEric van Gyzen 5*fe590ffeSEric van Gyzen /* 6*fe590ffeSEric van Gyzen * Copyright (c) 1997 by Internet Software Consortium 784f33deaSJordan K. Hubbard * 8*fe590ffeSEric van Gyzen * Permission to use, copy, modify, and distribute this software for any 9*fe590ffeSEric van Gyzen * purpose with or without fee is hereby granted, provided that the above 10*fe590ffeSEric van Gyzen * copyright notice and this permission notice appear in all copies. 1184f33deaSJordan K. Hubbard * 12*fe590ffeSEric van Gyzen * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS 13*fe590ffeSEric van Gyzen * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES 14*fe590ffeSEric van Gyzen * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE 15*fe590ffeSEric van Gyzen * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 16*fe590ffeSEric van Gyzen * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 17*fe590ffeSEric van Gyzen * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 18*fe590ffeSEric van Gyzen * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 19*fe590ffeSEric van Gyzen * SOFTWARE. 2084f33deaSJordan K. Hubbard */ 2184f33deaSJordan K. Hubbard 2284f33deaSJordan K. Hubbard #if !defined(lint) && !defined(LINT) 23*fe590ffeSEric van Gyzen static const char rcsid[] = "$Id: env.c,v 1.3 1998/08/14 00:32:39 vixie Exp $"; 2484f33deaSJordan K. Hubbard #endif 2584f33deaSJordan K. Hubbard 2684f33deaSJordan K. Hubbard 2784f33deaSJordan K. Hubbard #include "cron.h" 2884f33deaSJordan K. Hubbard 2984f33deaSJordan K. Hubbard 3084f33deaSJordan K. Hubbard char ** 31e93f27e3SJohn Baldwin env_init(void) 3284f33deaSJordan K. Hubbard { 33*fe590ffeSEric van Gyzen char **p = (char **) malloc(sizeof(char **)); 3484f33deaSJordan K. Hubbard 35bdddbd2fSPaul Traina if (p) 3684f33deaSJordan K. Hubbard p[0] = NULL; 3784f33deaSJordan K. Hubbard return (p); 3884f33deaSJordan K. Hubbard } 3984f33deaSJordan K. Hubbard 4084f33deaSJordan K. Hubbard 4184f33deaSJordan K. Hubbard void 42e93f27e3SJohn Baldwin env_free(char **envp) 4384f33deaSJordan K. Hubbard { 4484f33deaSJordan K. Hubbard char **p; 4584f33deaSJordan K. Hubbard 464a9e66b5SDavid Nugent if ((p = envp)) 474a9e66b5SDavid Nugent for (; *p; p++) 4884f33deaSJordan K. Hubbard free(*p); 4984f33deaSJordan K. Hubbard free(envp); 5084f33deaSJordan K. Hubbard } 5184f33deaSJordan K. Hubbard 5284f33deaSJordan K. Hubbard 5384f33deaSJordan K. Hubbard char ** 54e93f27e3SJohn Baldwin env_copy(char **envp) 5584f33deaSJordan K. Hubbard { 56*fe590ffeSEric van Gyzen int count, i; 57*fe590ffeSEric van Gyzen char **p; 5884f33deaSJordan K. Hubbard 5984f33deaSJordan K. Hubbard for (count = 0; envp[count] != NULL; count++) 6084f33deaSJordan K. Hubbard ; 61d02e530bSGuy Helmer p = (char **) malloc((count+1) * sizeof(char *)); /* 1 for the NULL */ 62bdddbd2fSPaul Traina if (p == NULL) { 63bdddbd2fSPaul Traina errno = ENOMEM; 64bdddbd2fSPaul Traina return NULL; 65bdddbd2fSPaul Traina } 6684f33deaSJordan K. Hubbard for (i = 0; i < count; i++) 67bdddbd2fSPaul Traina if ((p[i] = strdup(envp[i])) == NULL) { 68bdddbd2fSPaul Traina while (--i >= 0) 69bdddbd2fSPaul Traina (void) free(p[i]); 70bdddbd2fSPaul Traina free(p); 71bdddbd2fSPaul Traina errno = ENOMEM; 72bdddbd2fSPaul Traina return NULL; 73bdddbd2fSPaul Traina } 7484f33deaSJordan K. Hubbard p[count] = NULL; 7584f33deaSJordan K. Hubbard return (p); 7684f33deaSJordan K. Hubbard } 7784f33deaSJordan K. Hubbard 7884f33deaSJordan K. Hubbard 7984f33deaSJordan K. Hubbard char ** 80e93f27e3SJohn Baldwin env_set(char **envp, char *envstr) 8184f33deaSJordan K. Hubbard { 82*fe590ffeSEric van Gyzen int count, found; 83*fe590ffeSEric van Gyzen char **p; 848261236dSGuy Helmer char *q; 8584f33deaSJordan K. Hubbard 8684f33deaSJordan K. Hubbard /* 8784f33deaSJordan K. Hubbard * count the number of elements, including the null pointer; 8884f33deaSJordan K. Hubbard * also set 'found' to -1 or index of entry if already in here. 8984f33deaSJordan K. Hubbard */ 9084f33deaSJordan K. Hubbard found = -1; 9184f33deaSJordan K. Hubbard for (count = 0; envp[count] != NULL; count++) { 9284f33deaSJordan K. Hubbard if (!strcmp_until(envp[count], envstr, '=')) 9384f33deaSJordan K. Hubbard found = count; 9484f33deaSJordan K. Hubbard } 9584f33deaSJordan K. Hubbard count++; /* for the NULL */ 9684f33deaSJordan K. Hubbard 9784f33deaSJordan K. Hubbard if (found != -1) { 9884f33deaSJordan K. Hubbard /* 9984f33deaSJordan K. Hubbard * it exists already, so just free the existing setting, 10084f33deaSJordan K. Hubbard * save our new one there, and return the existing array. 10184f33deaSJordan K. Hubbard */ 1028261236dSGuy Helmer q = envp[found]; 103bdddbd2fSPaul Traina if ((envp[found] = strdup(envstr)) == NULL) { 1048261236dSGuy Helmer envp[found] = q; 1058261236dSGuy Helmer /* XXX env_free(envp); */ 106bdddbd2fSPaul Traina errno = ENOMEM; 107bdddbd2fSPaul Traina return NULL; 108bdddbd2fSPaul Traina } 1098261236dSGuy Helmer free(q); 11084f33deaSJordan K. Hubbard return (envp); 11184f33deaSJordan K. Hubbard } 11284f33deaSJordan K. Hubbard 11384f33deaSJordan K. Hubbard /* 11484f33deaSJordan K. Hubbard * it doesn't exist yet, so resize the array, move null pointer over 11584f33deaSJordan K. Hubbard * one, save our string over the old null pointer, and return resized 11684f33deaSJordan K. Hubbard * array. 11784f33deaSJordan K. Hubbard */ 11884f33deaSJordan K. Hubbard p = (char **) realloc((void *) envp, 119d02e530bSGuy Helmer (unsigned) ((count+1) * sizeof(char *))); 120bdddbd2fSPaul Traina if (p == NULL) { 1218261236dSGuy Helmer /* XXX env_free(envp); */ 122bdddbd2fSPaul Traina errno = ENOMEM; 123bdddbd2fSPaul Traina return NULL; 124bdddbd2fSPaul Traina } 12584f33deaSJordan K. Hubbard p[count] = p[count-1]; 126bdddbd2fSPaul Traina if ((p[count-1] = strdup(envstr)) == NULL) { 1278261236dSGuy Helmer env_free(p); 128bdddbd2fSPaul Traina errno = ENOMEM; 129bdddbd2fSPaul Traina return NULL; 130bdddbd2fSPaul Traina } 13184f33deaSJordan K. Hubbard return (p); 13284f33deaSJordan K. Hubbard } 13384f33deaSJordan K. Hubbard 13484f33deaSJordan K. Hubbard 13584f33deaSJordan K. Hubbard /* return ERR = end of file 13684f33deaSJordan K. Hubbard * FALSE = not an env setting (file was repositioned) 13784f33deaSJordan K. Hubbard * TRUE = was an env setting 13884f33deaSJordan K. Hubbard */ 13984f33deaSJordan K. Hubbard int 140e93f27e3SJohn Baldwin load_env(char *envstr, FILE *f) 14184f33deaSJordan K. Hubbard { 14284f33deaSJordan K. Hubbard long filepos; 14384f33deaSJordan K. Hubbard int fileline; 144482bfcccSPaul Traina char name[MAX_ENVSTR], val[MAX_ENVSTR]; 145bb817201SOllivier Robert char quotechar, *c, *str; 146bb817201SOllivier Robert int state; 147bb817201SOllivier Robert 148bb817201SOllivier Robert /* The following states are traversed in order: */ 149bb817201SOllivier Robert #define NAMEI 0 /* First char of NAME, may be quote */ 150bb817201SOllivier Robert #define NAME 1 /* Subsequent chars of NAME */ 151bb817201SOllivier Robert #define EQ1 2 /* After end of name, looking for '=' sign */ 152bb817201SOllivier Robert #define EQ2 3 /* After '=', skipping whitespace */ 153bb817201SOllivier Robert #define VALUEI 4 /* First char of VALUE, may be quote */ 154bb817201SOllivier Robert #define VALUE 5 /* Subsequent chars of VALUE */ 155bb817201SOllivier Robert #define FINI 6 /* All done, skipping trailing whitespace */ 156bb817201SOllivier Robert #define ERROR 7 /* Error */ 15784f33deaSJordan K. Hubbard 15884f33deaSJordan K. Hubbard filepos = ftell(f); 15984f33deaSJordan K. Hubbard fileline = LineNumber; 16084f33deaSJordan K. Hubbard skip_comments(f); 16184f33deaSJordan K. Hubbard if (EOF == get_string(envstr, MAX_ENVSTR, f, "\n")) 16284f33deaSJordan K. Hubbard return (ERR); 16384f33deaSJordan K. Hubbard 164bb817201SOllivier Robert Debug(DPARS, ("load_env, read <%s>\n", envstr)); 16584f33deaSJordan K. Hubbard 166bb817201SOllivier Robert bzero (name, sizeof name); 167bb817201SOllivier Robert bzero (val, sizeof val); 168bb817201SOllivier Robert str = name; 169bb817201SOllivier Robert state = NAMEI; 170bb817201SOllivier Robert quotechar = '\0'; 171bb817201SOllivier Robert c = envstr; 172bb817201SOllivier Robert while (state != ERROR && *c) { 173bb817201SOllivier Robert switch (state) { 174bb817201SOllivier Robert case NAMEI: 175bb817201SOllivier Robert case VALUEI: 176bb817201SOllivier Robert if (*c == '\'' || *c == '"') 177bb817201SOllivier Robert quotechar = *c++; 178bb817201SOllivier Robert ++state; 179bb817201SOllivier Robert /* FALLTHROUGH */ 180bb817201SOllivier Robert case NAME: 181bb817201SOllivier Robert case VALUE: 182bb817201SOllivier Robert if (quotechar) { 183bb817201SOllivier Robert if (*c == quotechar) { 184bb817201SOllivier Robert state++; 185bb817201SOllivier Robert c++; 186bb817201SOllivier Robert break; 187bb817201SOllivier Robert } 188bb817201SOllivier Robert if (state == NAME && *c == '=') { 189bb817201SOllivier Robert state = ERROR; 190bb817201SOllivier Robert break; 191bb817201SOllivier Robert } 192bb817201SOllivier Robert } else { 1936ced08bfSThomas Quinot if (state == NAME) { 194bb817201SOllivier Robert if (isspace (*c)) { 195bb817201SOllivier Robert c++; 1966ced08bfSThomas Quinot state++; 197bb817201SOllivier Robert break; 198bb817201SOllivier Robert } 1996ced08bfSThomas Quinot if (*c == '=') { 200bb817201SOllivier Robert state++; 201bb817201SOllivier Robert break; 202bb817201SOllivier Robert } 203bb817201SOllivier Robert } 2046ced08bfSThomas Quinot } 205bb817201SOllivier Robert *str++ = *c++; 206bb817201SOllivier Robert break; 207bb817201SOllivier Robert 208bb817201SOllivier Robert case EQ1: 209bb817201SOllivier Robert if (*c == '=') { 210bb817201SOllivier Robert state++; 211bb817201SOllivier Robert str = val; 212bb817201SOllivier Robert quotechar = '\0'; 213bb817201SOllivier Robert } else { 214bb817201SOllivier Robert if (!isspace (*c)) 215bb817201SOllivier Robert state = ERROR; 216bb817201SOllivier Robert } 217bb817201SOllivier Robert c++; 218bb817201SOllivier Robert break; 219bb817201SOllivier Robert case EQ2: 220bb817201SOllivier Robert case FINI: 221bb817201SOllivier Robert if (isspace (*c)) 222bb817201SOllivier Robert c++; 223bb817201SOllivier Robert else 224bb817201SOllivier Robert state++; 225bb817201SOllivier Robert break; 226bb817201SOllivier Robert } 227bb817201SOllivier Robert } 228bb817201SOllivier Robert if (state != FINI && !(state == VALUE && !quotechar)) { 229bb817201SOllivier Robert Debug(DPARS, ("load_env, parse error, state = %d\n", state)) 23084f33deaSJordan K. Hubbard fseek(f, filepos, 0); 23184f33deaSJordan K. Hubbard Set_LineNum(fileline); 23284f33deaSJordan K. Hubbard return (FALSE); 23384f33deaSJordan K. Hubbard } 2346ced08bfSThomas Quinot if (state == VALUE) { 2356ced08bfSThomas Quinot /* End of unquoted value: trim trailing whitespace */ 2366ced08bfSThomas Quinot c = val + strlen (val); 2376ced08bfSThomas Quinot while (c > val && isspace (*(c - 1))) 2386ced08bfSThomas Quinot *(--c) = '\0'; 2396ced08bfSThomas Quinot } 24084f33deaSJordan K. Hubbard 2416ced08bfSThomas Quinot /* 2 fields from parser; looks like an env setting */ 24284f33deaSJordan K. Hubbard 243*fe590ffeSEric van Gyzen if (snprintf(envstr, MAX_ENVSTR, "%s=%s", name, val) >= MAX_ENVSTR) 244bdddbd2fSPaul Traina return (FALSE); 24584f33deaSJordan K. Hubbard Debug(DPARS, ("load_env, <%s> <%s> -> <%s>\n", name, val, envstr)) 24684f33deaSJordan K. Hubbard return (TRUE); 24784f33deaSJordan K. Hubbard } 24884f33deaSJordan K. Hubbard 24984f33deaSJordan K. Hubbard 25084f33deaSJordan K. Hubbard char * 251e93f27e3SJohn Baldwin env_get(char *name, char **envp) 25284f33deaSJordan K. Hubbard { 253*fe590ffeSEric van Gyzen int len = strlen(name); 254*fe590ffeSEric van Gyzen char *p, *q; 25584f33deaSJordan K. Hubbard 256*fe590ffeSEric van Gyzen while ((p = *envp++) != NULL) { 25784f33deaSJordan K. Hubbard if (!(q = strchr(p, '='))) 25884f33deaSJordan K. Hubbard continue; 25984f33deaSJordan K. Hubbard if ((q - p) == len && !strncmp(p, name, len)) 26084f33deaSJordan K. Hubbard return (q+1); 26184f33deaSJordan K. Hubbard } 26284f33deaSJordan K. Hubbard return (NULL); 26384f33deaSJordan K. Hubbard } 264