1 /* $OpenBSD: env.c,v 1.13 2002/07/11 20:15:40 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 const rcsid[] = "$OpenBSD: env.c,v 1.13 2002/07/11 20:15:40 millert Exp $"; 25 #endif 26 27 #include "cron.h" 28 29 char ** 30 env_init(void) { 31 char **p = (char **) malloc(sizeof(char **)); 32 33 if (p != NULL) 34 p[0] = NULL; 35 return (p); 36 } 37 38 void 39 env_free(char **envp) { 40 char **p; 41 42 for (p = envp; *p != NULL; p++) 43 free(*p); 44 free(envp); 45 } 46 47 char ** 48 env_copy(char **envp) { 49 int count, i, save_errno; 50 char **p; 51 52 for (count = 0; envp[count] != NULL; count++) 53 continue; 54 p = (char **) malloc((count+1) * sizeof(char *)); /* 1 for the NULL */ 55 if (p != NULL) { 56 for (i = 0; i < count; i++) 57 if ((p[i] = strdup(envp[i])) == NULL) { 58 save_errno = errno; 59 while (--i >= 0) 60 free(p[i]); 61 free(p); 62 errno = save_errno; 63 return (NULL); 64 } 65 p[count] = NULL; 66 } 67 return (p); 68 } 69 70 char ** 71 env_set(char **envp, char *envstr) { 72 int count, found; 73 char **p, *envtmp; 74 75 /* 76 * count the number of elements, including the null pointer; 77 * also set 'found' to -1 or index of entry if already in here. 78 */ 79 found = -1; 80 for (count = 0; envp[count] != NULL; count++) { 81 if (!strcmp_until(envp[count], envstr, '=')) 82 found = count; 83 } 84 count++; /* for the NULL */ 85 86 if (found != -1) { 87 /* 88 * it exists already, so just free the existing setting, 89 * save our new one there, and return the existing array. 90 */ 91 if ((envtmp = strdup(envstr)) == NULL) 92 return (NULL); 93 free(envp[found]); 94 envp[found] = envtmp; 95 return (envp); 96 } 97 98 /* 99 * it doesn't exist yet, so resize the array, move null pointer over 100 * one, save our string over the old null pointer, and return resized 101 * array. 102 */ 103 if ((envtmp = strdup(envstr)) == NULL) 104 return (NULL); 105 p = (char **) realloc((void *) envp, 106 (size_t) ((count+1) * sizeof(char **))); 107 if (p == NULL) { 108 free(envtmp); 109 return (NULL); 110 } 111 p[count] = p[count-1]; 112 p[count-1] = envtmp; 113 return (p); 114 } 115 116 /* return ERR = end of file 117 * FALSE = not an env setting (file was repositioned) 118 * TRUE = was an env setting 119 */ 120 int 121 load_env(char *envstr, FILE *f) { 122 long filepos; 123 int fileline; 124 char name[MAX_ENVSTR], val[MAX_ENVSTR]; 125 int fields; 126 127 filepos = ftell(f); 128 fileline = LineNumber; 129 skip_comments(f); 130 if (EOF == get_string(envstr, MAX_ENVSTR, f, "\n")) 131 return (ERR); 132 133 Debug(DPARS, ("load_env, read <%s>\n", envstr)) 134 135 name[0] = val[0] = '\0'; 136 fields = sscanf(envstr, "%[^ =] = %[^\n#]", name, val); 137 if (fields != 2) { 138 Debug(DPARS, ("load_env, not 2 fields (%d)\n", fields)) 139 fseek(f, filepos, 0); 140 Set_LineNum(fileline); 141 return (FALSE); 142 } 143 144 /* 145 * 2 fields from scanf; looks like an env setting. 146 */ 147 148 /* 149 * process value string 150 */ 151 /*local*/{ 152 int len = strdtb(val); 153 154 if (len >= 2) { 155 if (val[0] == '\'' || val[0] == '"') { 156 if (val[len-1] == val[0]) { 157 val[len-1] = '\0'; 158 memmove(val, val+1, len); 159 } 160 } 161 } 162 } 163 164 /* 165 * This can't overflow because get_string() limited the size of the 166 * name and val fields. Still, it doesn't hurt... 167 */ 168 (void) snprintf(envstr, MAX_ENVSTR, "%s=%s", name, val); 169 Debug(DPARS, ("load_env, <%s> <%s> -> <%s>\n", name, val, envstr)) 170 return (TRUE); 171 } 172 173 char * 174 env_get(char *name, char **envp) { 175 int len = strlen(name); 176 char *p, *q; 177 178 while ((p = *envp++) != NULL) { 179 if (!(q = strchr(p, '='))) 180 continue; 181 if ((q - p) == len && !strncmp(p, name, len)) 182 return (q+1); 183 } 184 return (NULL); 185 } 186