1 /* 2 * ENVIRON.C 3 * 4 * Written 1998 by Tobias Ernst and release to the Public Domain 5 * 6 * Environment variable (%MAILBOXDRIVE% -> E: and so on) expander. 7 */ 8 9 #include <string.h> 10 #include <ctype.h> 11 #include <stdlib.h> 12 #include "memextra.h" 13 14 #undef isalnum env_expand(char * line)15char *env_expand(char *line) 16 { char *cpTemp; 17 char var[82]; char *cpvar, *cpsrc, *cpdest; 18 int isVar=0, l=0, invar=0; 19 size_t maxlen=2*strlen(line); 20 21 start: 22 cpvar=var; cpsrc=line; 23 cpTemp=xmalloc(maxlen+1); 24 cpdest=cpTemp; 25 26 while (*cpsrc) 27 { if (*cpsrc=='%') 28 { 29 if (isVar) 30 { *cpvar=0; isVar=0; 31 #ifndef UNIX 32 /* On all systems except unix, environment variables are stored in 33 uppercase alwys, but the user can access them via lowercase as 34 well. As getenv is case-sensitive, we uppercase the variable 35 name before passing it to getenv. */ 36 for (cpvar=var;*cpvar;cpvar++) 37 *cpvar=toupper(*cpvar); 38 #endif 39 if (!strlen(var)) 40 { *(cpdest++)='%'; if ((++l)>=maxlen) goto error; } 41 else 42 { 43 if ((cpvar=getenv(var))!=NULL) 44 for (;*cpvar;*(cpdest++)=*(cpvar++)) 45 if ((++l)>=maxlen) goto error; 46 } 47 cpvar=var; 48 } 49 else 50 { 51 isVar=1; invar = 0; 52 } 53 } 54 else 55 { 56 if (isVar) 57 { int novar = 0; 58 59 *(cpvar++) = (*cpsrc); invar++; 60 if (invar > 80) 61 { 62 novar = 1; 63 } 64 if ( ! ((*cpsrc >= 'A' && *cpsrc <= 'Z') || 65 (*cpsrc >= 'a' && *cpsrc <= 'z') || 66 (*cpsrc >= '0' && *cpsrc <= '9') || 67 (*cpsrc == '_'))) 68 { 69 novar = 1; 70 } 71 if (novar) 72 { isVar=0; *cpvar=0; 73 *(cpdest++)='%'; 74 if ((++l)>=maxlen) goto error; 75 for (cpvar=var;*cpvar;*(cpdest++)=*(cpvar++)) 76 if ((++l)>=maxlen) goto error; 77 cpvar=var; 78 } else; 79 } 80 else 81 { *cpdest++=*cpsrc; 82 if ((++l)>=maxlen) goto error; 83 } 84 } 85 86 cpsrc++; 87 } 88 if (isVar) 89 { isVar=0; *cpvar=0; 90 *(cpdest++)='%'; 91 if ((++l)>=maxlen) goto error; 92 for (cpvar=var;*cpvar;*(cpdest++)=*(cpvar++)) 93 if ((++l)>=maxlen) goto error; 94 cpvar=var; 95 } 96 *cpdest=0; 97 98 return cpTemp; 99 100 error: /* our estimate for the new buffer was too small */ 101 xfree(cpTemp); 102 maxlen=maxlen+80; 103 goto start; 104 } 105 106