Busybox: Upgrade to 1.21.1 (stable). lsof active.
[tomato.git] / release / src / router / miniupnpd / options.c
blobdc886a5895b47257db1cf6b3aa3cae04cb7c286c
1 /* $Id: options.c,v 1.26 2012/06/29 19:26:09 nanard Exp $ */
2 /* MiniUPnP project
3 * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
4 * author: Ryan Wagoner
5 * (c) 2006-2012 Thomas Bernard
6 * This software is subject to the conditions detailed
7 * in the LICENCE file provided within the distribution */
9 #include <stdio.h>
10 #include <string.h>
11 #include <stdlib.h>
12 #include <ctype.h>
13 #include <syslog.h>
14 #include "config.h"
15 #include "options.h"
16 #include "upnppermissions.h"
17 #include "upnpglobalvars.h"
19 #ifndef DISABLE_CONFIG_FILE
20 struct option * ary_options = NULL;
21 static char * string_repo = NULL;
22 unsigned int num_options = 0;
24 static const struct {
25 enum upnpconfigoptions id;
26 const char * name;
27 } optionids[] = {
28 { UPNPEXT_IFNAME, "ext_ifname" },
29 { UPNPEXT_IP, "ext_ip" },
30 { UPNPLISTENING_IP, "listening_ip" },
31 { UPNPPORT, "port" },
32 { UPNPBITRATE_UP, "bitrate_up" },
33 { UPNPBITRATE_DOWN, "bitrate_down" },
34 { UPNPPRESENTATIONURL, "presentation_url" },
35 { UPNPFRIENDLY_NAME, "friendly_name" },
36 { UPNPNOTIFY_INTERVAL, "notify_interval" },
37 { UPNPSYSTEM_UPTIME, "system_uptime" },
38 { UPNPPACKET_LOG, "packet_log" },
39 { UPNPUUID, "uuid"},
40 { UPNPSERIAL, "serial"},
41 { UPNPMODEL_NUMBER, "model_number"},
42 { UPNPCLEANTHRESHOLD, "clean_ruleset_threshold"},
43 { UPNPCLEANINTERVAL, "clean_ruleset_interval"},
44 #ifdef USE_NETFILTER
45 { UPNPFORWARDCHAIN, "upnp_forward_chain"},
46 { UPNPNATCHAIN, "upnp_nat_chain"},
47 #endif
48 #ifdef ENABLE_NATPMP
49 { UPNPENABLENATPMP, "enable_natpmp"},
50 #endif
51 { UPNPENABLE, "enable_upnp"},
52 #ifdef USE_PF
53 { UPNPANCHOR, "anchor"},
54 { UPNPQUEUE, "queue"},
55 { UPNPTAG, "tag"},
56 #endif
57 #ifdef PF_ENABLE_FILTER_RULES
58 { UPNPQUICKRULES, "quickrules" },
59 #endif
60 #ifdef ENABLE_LEASEFILE
61 { UPNPLEASEFILE, "lease_file"},
62 #endif
63 { UPNPMINISSDPDSOCKET, "minissdpdsocket"},
64 { UPNPSECUREMODE, "secure_mode"}
67 int
68 readoptionsfile(const char * fname)
70 FILE *hfile = NULL;
71 char buffer[1024];
72 char *equals;
73 char *name;
74 char *value;
75 char *t;
76 int linenum = 0;
77 unsigned int i;
78 enum upnpconfigoptions id;
79 size_t string_repo_len = 0;
80 size_t len;
81 void *tmp;
83 if(!fname || (strlen(fname) == 0))
84 return -1;
86 memset(buffer, 0, sizeof(buffer));
88 #ifdef DEBUG
89 printf("Reading configuration from file %s\n", fname);
90 #endif
92 if(!(hfile = fopen(fname, "r")))
93 return -1;
95 if(ary_options != NULL)
97 free(ary_options);
98 num_options = 0;
101 while(fgets(buffer, sizeof(buffer), hfile))
103 linenum++;
104 t = strchr(buffer, '\n');
105 if(t)
107 *t = '\0';
108 t--;
109 /* remove spaces at the end of the line */
110 while((t >= buffer) && isspace(*t))
112 *t = '\0';
113 t--;
117 /* skip leading whitespaces */
118 name = buffer;
119 while(isspace(*name))
120 name++;
122 /* check for comments or empty lines */
123 if(name[0] == '#' || name[0] == '\0') continue;
125 /* check for UPnP permissions rule */
126 if(0 == memcmp(name, "allow", 5) || 0 == memcmp(name, "deny", 4))
128 tmp = realloc(upnppermlist, sizeof(struct upnpperm) * (num_upnpperm+1));
129 if(tmp == NULL)
131 fprintf(stderr, "memory allocation error. Permission line in file %s line %d\n",
132 fname, linenum);
134 else
136 upnppermlist = tmp;
137 /* parse the rule */
138 if(read_permission_line(upnppermlist + num_upnpperm, name) >= 0)
140 num_upnpperm++;
142 else
144 fprintf(stderr, "parsing error file %s line %d : %s\n",
145 fname, linenum, name);
148 continue;
150 if(!(equals = strchr(name, '=')))
152 fprintf(stderr, "parsing error file %s line %d : %s\n",
153 fname, linenum, name);
154 continue;
157 /* remove ending whitespaces */
158 for(t=equals-1; t>name && isspace(*t); t--)
159 *t = '\0';
161 *equals = '\0';
162 value = equals+1;
164 /* skip leading whitespaces */
165 while(isspace(*value))
166 value++;
168 id = UPNP_INVALID;
169 for(i=0; i<sizeof(optionids)/sizeof(optionids[0]); i++)
171 /*printf("%2d %2d %s %s\n", i, optionids[i].id, name,
172 optionids[i].name); */
174 if(0 == strcmp(name, optionids[i].name))
176 id = optionids[i].id;
177 break;
181 if(id == UPNP_INVALID)
183 fprintf(stderr, "invalid option in file %s line %d : %s=%s\n",
184 fname, linenum, name, value);
186 else
188 tmp = realloc(ary_options, (num_options + 1) * sizeof(struct option));
189 if(tmp == NULL)
191 fprintf(stderr, "memory allocation error. Option in file %s line %d.\n",
192 fname, linenum);
194 else
196 ary_options = tmp;
197 len = strlen(value) + 1; /* +1 for terminating '\0' */
198 tmp = realloc(string_repo, string_repo_len + len);
199 if(tmp == NULL)
201 fprintf(stderr, "memory allocation error, Option value in file %s line %d : %s=%s\n",
202 fname, linenum, name, value);
204 else
206 string_repo = tmp;
207 memcpy(string_repo + string_repo_len, value, len);
208 ary_options[num_options].id = id;
209 /* save the offset instead of the absolute address because realloc() could
210 * change it */
211 ary_options[num_options].value = (const char *)string_repo_len;
212 num_options += 1;
213 string_repo_len += len;
220 fclose(hfile);
222 for(i = 0; i < num_options; i++)
224 /* add start address of string_repo to get right pointer */
225 ary_options[i].value = string_repo + (size_t)ary_options[i].value;
228 return 0;
231 void
232 freeoptions(void)
234 if(ary_options)
236 free(ary_options);
237 ary_options = NULL;
238 num_options = 0;
240 if(string_repo)
242 free(string_repo);
243 string_repo = NULL;
245 if(upnppermlist)
247 free(upnppermlist);
248 upnppermlist = NULL;
249 num_upnpperm = 0;
253 #endif /* DISABLE_CONFIG_FILE */