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