xref: /onnv-gate/usr/src/cmd/ipf/lib/common/var.c (revision 2393:76e0289ce525)
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