1*2393Syz155240 /* 2*2393Syz155240 * Copyright (C) 1993-2005 by Darren Reed. 3*2393Syz155240 * See the IPFILTER.LICENCE file for details on licencing. 4*2393Syz155240 */ 5*2393Syz155240 60Sstevel@tonic-gate #include <ctype.h> 70Sstevel@tonic-gate 80Sstevel@tonic-gate #include "ipf.h" 90Sstevel@tonic-gate 100Sstevel@tonic-gate typedef struct variable { 110Sstevel@tonic-gate struct variable *v_next; 120Sstevel@tonic-gate char *v_name; 130Sstevel@tonic-gate char *v_value; 140Sstevel@tonic-gate } variable_t; 150Sstevel@tonic-gate 160Sstevel@tonic-gate static variable_t *vtop = NULL; 170Sstevel@tonic-gate 180Sstevel@tonic-gate static variable_t *find_var __P((char *)); 190Sstevel@tonic-gate static char *expand_string __P((char *, int)); 200Sstevel@tonic-gate 210Sstevel@tonic-gate 220Sstevel@tonic-gate static variable_t *find_var(name) 230Sstevel@tonic-gate char *name; 240Sstevel@tonic-gate { 250Sstevel@tonic-gate variable_t *v; 260Sstevel@tonic-gate 270Sstevel@tonic-gate for (v = vtop; v != NULL; v = v->v_next) 280Sstevel@tonic-gate if (!strcmp(name, v->v_name)) 290Sstevel@tonic-gate return v; 300Sstevel@tonic-gate return NULL; 310Sstevel@tonic-gate } 320Sstevel@tonic-gate 330Sstevel@tonic-gate 340Sstevel@tonic-gate char *get_variable(string, after, line) 350Sstevel@tonic-gate char *string, **after; 360Sstevel@tonic-gate int line; 370Sstevel@tonic-gate { 380Sstevel@tonic-gate char c, *s, *t, *value; 390Sstevel@tonic-gate variable_t *v; 400Sstevel@tonic-gate 410Sstevel@tonic-gate s = string; 420Sstevel@tonic-gate 430Sstevel@tonic-gate if (*s == '{') { 440Sstevel@tonic-gate s++; 450Sstevel@tonic-gate for (t = s; *t != '\0'; t++) 460Sstevel@tonic-gate if (*t == '}') 470Sstevel@tonic-gate break; 480Sstevel@tonic-gate if (*t == '\0') { 490Sstevel@tonic-gate fprintf(stderr, "%d: { without }\n", line); 500Sstevel@tonic-gate return NULL; 510Sstevel@tonic-gate } 52*2393Syz155240 } else if (ISALPHA(*s)) { 530Sstevel@tonic-gate for (t = s + 1; *t != '\0'; t++) 54*2393Syz155240 if (!ISALPHA(*t) && !ISDIGIT(*t) && (*t != '_')) 550Sstevel@tonic-gate break; 560Sstevel@tonic-gate } else { 570Sstevel@tonic-gate fprintf(stderr, "%d: variables cannot start with '%c'\n", 580Sstevel@tonic-gate line, *s); 590Sstevel@tonic-gate return NULL; 600Sstevel@tonic-gate } 610Sstevel@tonic-gate 620Sstevel@tonic-gate if (after != NULL) 630Sstevel@tonic-gate *after = t; 640Sstevel@tonic-gate c = *t; 650Sstevel@tonic-gate *t = '\0'; 660Sstevel@tonic-gate v = find_var(s); 670Sstevel@tonic-gate *t = c; 680Sstevel@tonic-gate if (v == NULL) { 690Sstevel@tonic-gate fprintf(stderr, "%d: unknown variable '%s'\n", line, s); 700Sstevel@tonic-gate return NULL; 710Sstevel@tonic-gate } 720Sstevel@tonic-gate 730Sstevel@tonic-gate s = strdup(v->v_value); 740Sstevel@tonic-gate value = expand_string(s, line); 750Sstevel@tonic-gate if (value != s) 760Sstevel@tonic-gate free(s); 770Sstevel@tonic-gate return value; 780Sstevel@tonic-gate } 790Sstevel@tonic-gate 800Sstevel@tonic-gate 810Sstevel@tonic-gate static char *expand_string(oldstring, line) 820Sstevel@tonic-gate char *oldstring; 830Sstevel@tonic-gate int line; 840Sstevel@tonic-gate { 850Sstevel@tonic-gate char c, *s, *p1, *p2, *p3, *newstring, *value; 860Sstevel@tonic-gate int len; 870Sstevel@tonic-gate 880Sstevel@tonic-gate p3 = NULL; 890Sstevel@tonic-gate newstring = oldstring; 900Sstevel@tonic-gate 910Sstevel@tonic-gate for (s = oldstring; *s != '\0'; s++) 920Sstevel@tonic-gate if (*s == '$') { 930Sstevel@tonic-gate *s = '\0'; 940Sstevel@tonic-gate s++; 950Sstevel@tonic-gate 960Sstevel@tonic-gate switch (*s) 970Sstevel@tonic-gate { 980Sstevel@tonic-gate case '$' : 990Sstevel@tonic-gate bcopy(s, s - 1, strlen(s)); 1000Sstevel@tonic-gate break; 1010Sstevel@tonic-gate default : 1020Sstevel@tonic-gate c = *s; 103*2393Syz155240 if (c == '\0') 104*2393Syz155240 return newstring; 105*2393Syz155240 1060Sstevel@tonic-gate value = get_variable(s, &p3, line); 1070Sstevel@tonic-gate if (value == NULL) 1080Sstevel@tonic-gate return NULL; 1090Sstevel@tonic-gate 1100Sstevel@tonic-gate p2 = expand_string(value, line); 1110Sstevel@tonic-gate if (p2 == NULL) 1120Sstevel@tonic-gate return NULL; 1130Sstevel@tonic-gate 1140Sstevel@tonic-gate len = strlen(newstring) + strlen(p2); 1150Sstevel@tonic-gate if (p3 != NULL) { 1160Sstevel@tonic-gate if (c == '{' && *p3 == '}') 1170Sstevel@tonic-gate p3++; 1180Sstevel@tonic-gate len += strlen(p3); 1190Sstevel@tonic-gate } 1200Sstevel@tonic-gate p1 = malloc(len + 1); 1210Sstevel@tonic-gate if (p1 == NULL) 1220Sstevel@tonic-gate return NULL; 1230Sstevel@tonic-gate 1240Sstevel@tonic-gate *(s - 1) = '\0'; 1250Sstevel@tonic-gate strcpy(p1, newstring); 1260Sstevel@tonic-gate strcat(p1, p2); 1270Sstevel@tonic-gate if (p3 != NULL) 1280Sstevel@tonic-gate strcat(p1, p3); 1290Sstevel@tonic-gate 130*2393Syz155240 s = p1 + len - strlen(p3) - 1; 1310Sstevel@tonic-gate if (newstring != oldstring) 1320Sstevel@tonic-gate free(newstring); 1330Sstevel@tonic-gate newstring = p1; 1340Sstevel@tonic-gate break; 1350Sstevel@tonic-gate } 1360Sstevel@tonic-gate } 1370Sstevel@tonic-gate return newstring; 1380Sstevel@tonic-gate } 1390Sstevel@tonic-gate 1400Sstevel@tonic-gate 1410Sstevel@tonic-gate void set_variable(name, value) 1420Sstevel@tonic-gate char *name; 1430Sstevel@tonic-gate char *value; 1440Sstevel@tonic-gate { 1450Sstevel@tonic-gate variable_t *v; 1460Sstevel@tonic-gate int len; 1470Sstevel@tonic-gate 1480Sstevel@tonic-gate if (name == NULL || value == NULL || *name == '\0') 1490Sstevel@tonic-gate return; 1500Sstevel@tonic-gate 1510Sstevel@tonic-gate v = find_var(name); 1520Sstevel@tonic-gate if (v != NULL) { 1530Sstevel@tonic-gate free(v->v_value); 1540Sstevel@tonic-gate v->v_value = strdup(value); 1550Sstevel@tonic-gate return; 1560Sstevel@tonic-gate } 1570Sstevel@tonic-gate 1580Sstevel@tonic-gate len = strlen(value); 1590Sstevel@tonic-gate 1600Sstevel@tonic-gate if ((*value == '"' && value[len - 1] == '"') || 1610Sstevel@tonic-gate (*value == '\'' && value[len - 1] == '\'')) { 1620Sstevel@tonic-gate value[len - 1] = '\0'; 1630Sstevel@tonic-gate value++; 1640Sstevel@tonic-gate len -=2; 1650Sstevel@tonic-gate } 1660Sstevel@tonic-gate 1670Sstevel@tonic-gate v = (variable_t *)malloc(sizeof(*v)); 1680Sstevel@tonic-gate if (v == NULL) 1690Sstevel@tonic-gate return; 1700Sstevel@tonic-gate v->v_name = strdup(name); 1710Sstevel@tonic-gate v->v_value = strdup(value); 1720Sstevel@tonic-gate v->v_next = vtop; 1730Sstevel@tonic-gate vtop = v; 1740Sstevel@tonic-gate } 175