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