1 /* 2 * Copyright (C) 1993-2005 by Darren Reed. 3 * See the IPFILTER.LICENCE file for details on licencing. 4 */ 5 6 #include <ctype.h> 7 8 #include "ipf.h" 9 10 typedef struct variable { 11 struct variable *v_next; 12 char *v_name; 13 char *v_value; 14 } variable_t; 15 16 static variable_t *vtop = NULL; 17 18 static variable_t *find_var __P((char *)); 19 static char *expand_string __P((char *, int)); 20 21 22 static variable_t *find_var(name) 23 char *name; 24 { 25 variable_t *v; 26 27 for (v = vtop; v != NULL; v = v->v_next) 28 if (!strcmp(name, v->v_name)) 29 return v; 30 return NULL; 31 } 32 33 34 char *get_variable(string, after, line) 35 char *string, **after; 36 int line; 37 { 38 char c, *s, *t, *value; 39 variable_t *v; 40 41 s = string; 42 43 if (*s == '{') { 44 s++; 45 for (t = s; *t != '\0'; t++) 46 if (*t == '}') 47 break; 48 if (*t == '\0') { 49 fprintf(stderr, "%d: { without }\n", line); 50 return NULL; 51 } 52 } else if (ISALPHA(*s)) { 53 for (t = s + 1; *t != '\0'; t++) 54 if (!ISALPHA(*t) && !ISDIGIT(*t) && (*t != '_')) 55 break; 56 } else { 57 fprintf(stderr, "%d: variables cannot start with '%c'\n", 58 line, *s); 59 return NULL; 60 } 61 62 if (after != NULL) 63 *after = t; 64 c = *t; 65 *t = '\0'; 66 v = find_var(s); 67 *t = c; 68 if (v == NULL) { 69 fprintf(stderr, "%d: unknown variable '%s'\n", line, s); 70 return NULL; 71 } 72 73 s = strdup(v->v_value); 74 value = expand_string(s, line); 75 if (value != s) 76 free(s); 77 return value; 78 } 79 80 81 static char *expand_string(oldstring, line) 82 char *oldstring; 83 int line; 84 { 85 char c, *s, *p1, *p2, *p3, *newstring, *value; 86 int len; 87 88 p3 = NULL; 89 newstring = oldstring; 90 91 for (s = oldstring; *s != '\0'; s++) 92 if (*s == '$') { 93 *s = '\0'; 94 s++; 95 96 switch (*s) 97 { 98 case '$' : 99 bcopy(s, s - 1, strlen(s)); 100 break; 101 default : 102 c = *s; 103 if (c == '\0') 104 return newstring; 105 106 value = get_variable(s, &p3, line); 107 if (value == NULL) 108 return NULL; 109 110 p2 = expand_string(value, line); 111 if (p2 == NULL) 112 return NULL; 113 114 len = strlen(newstring) + strlen(p2); 115 if (p3 != NULL) { 116 if (c == '{' && *p3 == '}') 117 p3++; 118 len += strlen(p3); 119 } 120 p1 = malloc(len + 1); 121 if (p1 == NULL) 122 return NULL; 123 124 *(s - 1) = '\0'; 125 strcpy(p1, newstring); 126 strcat(p1, p2); 127 if (p3 != NULL) 128 strcat(p1, p3); 129 130 s = p1 + len - strlen(p3) - 1; 131 if (newstring != oldstring) 132 free(newstring); 133 newstring = p1; 134 break; 135 } 136 } 137 return newstring; 138 } 139 140 141 void set_variable(name, value) 142 char *name; 143 char *value; 144 { 145 variable_t *v; 146 int len; 147 148 if (name == NULL || value == NULL || *name == '\0') 149 return; 150 151 v = find_var(name); 152 if (v != NULL) { 153 free(v->v_value); 154 v->v_value = strdup(value); 155 return; 156 } 157 158 len = strlen(value); 159 160 if ((*value == '"' && value[len - 1] == '"') || 161 (*value == '\'' && value[len - 1] == '\'')) { 162 value[len - 1] = '\0'; 163 value++; 164 len -=2; 165 } 166 167 v = (variable_t *)malloc(sizeof(*v)); 168 if (v == NULL) 169 return; 170 v->v_name = strdup(name); 171 v->v_value = strdup(value); 172 v->v_next = vtop; 173 vtop = v; 174 } 175