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