Expand %VAR% references. Any unknown vars or unrecognized * syntax leaves the raw chars unchanged. */
| 165 | /* Expand %VAR% references. Any unknown vars or unrecognized |
| 166 | * syntax leaves the raw chars unchanged. */ |
| 167 | static char *expand_vars(const char *str) |
| 168 | { |
| 169 | char *buf, *t; |
| 170 | const char *f; |
| 171 | int bufsize; |
| 172 | |
| 173 | if (!str || !strchr(str, '%')) |
| 174 | return (char *)str; /* TODO change return value to const char* at some point. */ |
| 175 | |
| 176 | bufsize = strlen(str) + 2048; |
| 177 | buf = new_array(char, bufsize+1); /* +1 for trailing '\0' */ |
| 178 | |
| 179 | for (t = buf, f = str; bufsize && *f; ) { |
| 180 | if (*f == '%' && isUpper(f+1)) { |
| 181 | const char *percent = strchr(f+1, '%'); |
| 182 | if (percent && percent - f < bufsize) { |
| 183 | char *val; |
| 184 | strlcpy(t, f+1, percent - f); |
| 185 | val = getenv(t); |
| 186 | if (val) { |
| 187 | int len = strlcpy(t, val, bufsize+1); |
| 188 | if (len > bufsize) |
| 189 | break; |
| 190 | bufsize -= len; |
| 191 | t += len; |
| 192 | f = percent + 1; |
| 193 | continue; |
| 194 | } |
| 195 | } |
| 196 | } |
| 197 | *t++ = *f++; |
| 198 | bufsize--; |
| 199 | } |
| 200 | *t = '\0'; |
| 201 | |
| 202 | if (*f) { |
| 203 | rprintf(FLOG, "Overflowed buf in expand_vars() trying to expand: %s\n", str); |
| 204 | exit_cleanup(RERR_MALLOC); |
| 205 | } |
| 206 | |
| 207 | if (bufsize && (buf = realloc(buf, t - buf + 1)) == NULL) |
| 208 | out_of_memory("expand_vars"); |
| 209 | |
| 210 | return buf; |
| 211 | } |
| 212 | |
| 213 | /* Each "char* foo" has an associated "BOOL foo_EXP" that tracks if the string has been expanded yet or not. */ |
| 214 |
no test coverage detected