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
find_var(name)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
get_variable(string,after,line)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
expand_string(oldstring,line)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
set_variable(name,value)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