1 /* Copyright 1988,1990,1993,1994 by Paul Vixie 2 * All rights reserved 3 * 4 * Distribute freely, except: don't remove my name from the source or 5 * documentation (don't take credit for my work), mark your changes (don't 6 * get me blamed for your possible bugs), don't alter or remove this 7 * notice. May be sold if buildable source is provided to buyer. No 8 * warrantee of any kind, express or implied, is included with this 9 * software; use at your own risk, responsibility for damages (if any) to 10 * anyone resulting from the use of this software rests entirely with the 11 * user. 12 * 13 * Send bug reports, bug fixes, enhancements, requests, flames, etc., and 14 * I'll try to keep a version up to date. I can be reached as follows: 15 * Paul Vixie <paul@vix.com> uunet!decwrl!vixie!paul 16 */ 17 18 #if !defined(lint) && !defined(LINT) 19 static const char rcsid[] = 20 "$FreeBSD$"; 21 #endif 22 23 24 #include "cron.h" 25 26 27 char ** 28 env_init() 29 { 30 register char **p = (char **) malloc(sizeof(char *)); 31 32 if (p) 33 p[0] = NULL; 34 return (p); 35 } 36 37 38 void 39 env_free(envp) 40 char **envp; 41 { 42 char **p; 43 44 for (p = envp; *p; p++) 45 free(*p); 46 free(envp); 47 } 48 49 50 char ** 51 env_copy(envp) 52 register char **envp; 53 { 54 register int count, i; 55 register char **p; 56 57 for (count = 0; envp[count] != NULL; count++) 58 ; 59 p = (char **) malloc((count+1) * sizeof(char *)); /* 1 for the NULL */ 60 if (p == NULL) { 61 errno = ENOMEM; 62 return NULL; 63 } 64 for (i = 0; i < count; i++) 65 if ((p[i] = strdup(envp[i])) == NULL) { 66 while (--i >= 0) 67 (void) free(p[i]); 68 free(p); 69 errno = ENOMEM; 70 return NULL; 71 } 72 p[count] = NULL; 73 return (p); 74 } 75 76 77 char ** 78 env_set(envp, envstr) 79 char **envp; 80 char *envstr; 81 { 82 register int count, found; 83 register char **p; 84 char *q; 85 86 /* 87 * count the number of elements, including the null pointer; 88 * also set 'found' to -1 or index of entry if already in here. 89 */ 90 found = -1; 91 for (count = 0; envp[count] != NULL; count++) { 92 if (!strcmp_until(envp[count], envstr, '=')) 93 found = count; 94 } 95 count++; /* for the NULL */ 96 97 if (found != -1) { 98 /* 99 * it exists already, so just free the existing setting, 100 * save our new one there, and return the existing array. 101 */ 102 q = envp[found]; 103 if ((envp[found] = strdup(envstr)) == NULL) { 104 envp[found] = q; 105 /* XXX env_free(envp); */ 106 errno = ENOMEM; 107 return NULL; 108 } 109 free(q); 110 return (envp); 111 } 112 113 /* 114 * it doesn't exist yet, so resize the array, move null pointer over 115 * one, save our string over the old null pointer, and return resized 116 * array. 117 */ 118 p = (char **) realloc((void *) envp, 119 (unsigned) ((count+1) * sizeof(char *))); 120 if (p == NULL) { 121 /* XXX env_free(envp); */ 122 errno = ENOMEM; 123 return NULL; 124 } 125 p[count] = p[count-1]; 126 if ((p[count-1] = strdup(envstr)) == NULL) { 127 env_free(p); 128 errno = ENOMEM; 129 return NULL; 130 } 131 return (p); 132 } 133 134 135 /* return ERR = end of file 136 * FALSE = not an env setting (file was repositioned) 137 * TRUE = was an env setting 138 */ 139 int 140 load_env(envstr, f) 141 char *envstr; 142 FILE *f; 143 { 144 long filepos; 145 int fileline; 146 char name[MAX_ENVSTR], val[MAX_ENVSTR]; 147 int fields; 148 149 filepos = ftell(f); 150 fileline = LineNumber; 151 skip_comments(f); 152 if (EOF == get_string(envstr, MAX_ENVSTR, f, "\n")) 153 return (ERR); 154 155 Debug(DPARS, ("load_env, read <%s>\n", envstr)) 156 157 name[0] = val[0] = '\0'; 158 fields = sscanf(envstr, "%[^ =] = %[^\n#]", name, val); 159 if (fields != 2) { 160 Debug(DPARS, ("load_env, not 2 fields (%d)\n", fields)) 161 fseek(f, filepos, 0); 162 Set_LineNum(fileline); 163 return (FALSE); 164 } 165 166 /* 2 fields from scanf; looks like an env setting 167 */ 168 169 /* 170 * process value string 171 */ 172 /*local*/{ 173 int len = strdtb(val); 174 175 if (len >= 2) { 176 if (val[0] == '\'' || val[0] == '"') { 177 if (val[len-1] == val[0]) { 178 val[len-1] = '\0'; 179 (void) strcpy(val, val+1); 180 } 181 } 182 } 183 } 184 185 if (strlen(name) + 1 + strlen(val) >= MAX_ENVSTR-1) 186 return (FALSE); 187 (void) sprintf(envstr, "%s=%s", name, val); 188 Debug(DPARS, ("load_env, <%s> <%s> -> <%s>\n", name, val, envstr)) 189 return (TRUE); 190 } 191 192 193 char * 194 env_get(name, envp) 195 register char *name; 196 register char **envp; 197 { 198 register int len = strlen(name); 199 register char *p, *q; 200 201 while ((p = *envp++)) { 202 if (!(q = strchr(p, '='))) 203 continue; 204 if ((q - p) == len && !strncmp(p, name, len)) 205 return (q+1); 206 } 207 return (NULL); 208 } 209