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