1 /* $OpenBSD: env.c,v 1.9 2001/02/18 20:17:20 millert Exp $ */ 2 /* Copyright 1988,1990,1993,1994 by Paul Vixie 3 * All rights reserved 4 */ 5 6 /* 7 * Copyright (c) 1997,2000 by Internet Software Consortium, Inc. 8 * 9 * Permission to use, copy, modify, and distribute this software for any 10 * purpose with or without fee is hereby granted, provided that the above 11 * copyright notice and this permission notice appear in all copies. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS 14 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES 15 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE 16 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 17 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 18 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 19 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 20 * SOFTWARE. 21 */ 22 23 #if !defined(lint) && !defined(LINT) 24 static char rcsid[] = "$OpenBSD: env.c,v 1.9 2001/02/18 20:17:20 millert Exp $"; 25 #endif 26 27 28 #include "cron.h" 29 30 31 char ** 32 env_init() 33 { 34 char **p = (char **) malloc(sizeof(char **)); 35 36 if (p != NULL) 37 p[0] = NULL; 38 return (p); 39 } 40 41 42 void 43 env_free(envp) 44 char **envp; 45 { 46 char **p; 47 48 for (p = envp; *p; p++) 49 free(*p); 50 free(envp); 51 } 52 53 54 char ** 55 env_copy(envp) 56 char **envp; 57 { 58 int count, i, save_errno; 59 char **p; 60 61 for (count = 0; envp[count] != NULL; count++) 62 ; 63 p = (char **) malloc((count+1) * sizeof(char *)); /* 1 for the NULL */ 64 if (p != NULL) { 65 for (i = 0; i < count; i++) 66 if ((p[i] = strdup(envp[i])) == NULL) { 67 save_errno = errno; 68 while (--i >= 0) 69 free(p[i]); 70 free(p); 71 errno = save_errno; 72 return (NULL); 73 } 74 p[count] = NULL; 75 } 76 return (p); 77 } 78 79 80 char ** 81 env_set(envp, envstr) 82 char **envp; 83 char *envstr; 84 { 85 int count, found; 86 char **p, *cp; 87 88 /* 89 * count the number of elements, including the null pointer; 90 * also set 'found' to -1 or index of entry if already in here. 91 */ 92 found = -1; 93 for (count = 0; envp[count] != NULL; count++) { 94 if (!strcmp_until(envp[count], envstr, '=')) 95 found = count; 96 } 97 count++; /* for the NULL */ 98 99 if (found != -1) { 100 /* 101 * it exists already, so just free the existing setting, 102 * save our new one there, and return the existing array. 103 */ 104 free(envp[found]); 105 if ((envp[found] = strdup(envstr)) == NULL) { 106 envp[found] = ""; 107 return (NULL); 108 } 109 return (envp); 110 } 111 112 /* 113 * it doesn't exist yet, so resize the array, move null pointer over 114 * one, save our string over the old null pointer, and return resized 115 * array. 116 */ 117 p = (char **) realloc((void *) envp, 118 (size_t) ((count+1) * sizeof(char **))); 119 if (p == NULL) 120 return (NULL); 121 cp = strdup(envstr); 122 if (cp == NULL) 123 return(NULL); 124 p[count] = p[count-1]; 125 p[count-1] = cp; 126 return (p); 127 } 128 129 130 /* return ERR = end of file 131 * FALSE = not an env setting (file was repositioned) 132 * TRUE = was an env setting 133 */ 134 int 135 load_env(envstr, f) 136 char *envstr; 137 FILE *f; 138 { 139 long filepos; 140 int fileline; 141 char name[MAX_ENVSTR], val[MAX_ENVSTR]; 142 int fields; 143 144 filepos = ftell(f); 145 fileline = LineNumber; 146 skip_comments(f); 147 if (EOF == get_string(envstr, MAX_ENVSTR, f, "\n")) 148 return (ERR); 149 150 Debug(DPARS, ("load_env, read <%s>\n", envstr)) 151 152 name[0] = val[0] = '\0'; 153 fields = sscanf(envstr, "%[^ =] = %[^\n#]", name, val); 154 if (fields != 2) { 155 Debug(DPARS, ("load_env, not 2 fields (%d)\n", fields)) 156 fseek(f, filepos, 0); 157 Set_LineNum(fileline); 158 return (FALSE); 159 } 160 161 /* 162 * 2 fields from scanf; looks like an env setting. 163 */ 164 165 /* 166 * process value string 167 */ 168 /*local*/{ 169 int len = strdtb(val); 170 171 if (len >= 2) { 172 if (val[0] == '\'' || val[0] == '"') { 173 if (val[len-1] == val[0]) { 174 val[len-1] = '\0'; 175 memmove(val, val+1, len); 176 } 177 } 178 } 179 } 180 181 /* 182 * This can't overflow because get_string() limited the size of the 183 * name and val fields. Still, it doesn't hurt... 184 */ 185 (void) snprintf(envstr, MAX_ENVSTR, "%s=%s", name, val); 186 Debug(DPARS, ("load_env, <%s> <%s> -> <%s>\n", name, val, envstr)) 187 return (TRUE); 188 } 189 190 191 char * 192 env_get(name, envp) 193 char *name; 194 char **envp; 195 { 196 int len = strlen(name); 197 char *p, *q; 198 199 while ((p = *envp++) != NULL) { 200 if (!(q = strchr(p, '='))) 201 continue; 202 if ((q - p) == len && !strncmp(p, name, len)) 203 return (q+1); 204 } 205 return (NULL); 206 } 207