Annotation of embedaddon/miniupnpd/options.c, revision 1.1.1.2
1.1.1.2 ! misho 1: /* $Id: options.c,v 1.26 2012/06/29 19:26:09 nanard Exp $ */
1.1 misho 2: /* MiniUPnP project
3: * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
4: * author: Ryan Wagoner
1.1.1.2 ! misho 5: * (c) 2006-2012 Thomas Bernard
1.1 misho 6: * This software is subject to the conditions detailed
7: * in the LICENCE file provided within the distribution */
8:
9: #include <stdio.h>
10: #include <string.h>
11: #include <stdlib.h>
12: #include <ctype.h>
13: #include <syslog.h>
1.1.1.2 ! misho 14: #include "config.h"
1.1 misho 15: #include "options.h"
16: #include "upnppermissions.h"
17: #include "upnpglobalvars.h"
18:
1.1.1.2 ! misho 19: #ifndef DISABLE_CONFIG_FILE
1.1 misho 20: struct option * ary_options = NULL;
1.1.1.2 ! misho 21: static char * string_repo = NULL;
! 22: unsigned int num_options = 0;
1.1 misho 23:
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" },
1.1.1.2 ! misho 35: { UPNPFRIENDLY_NAME, "friendly_name" },
1.1 misho 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
1.1.1.2 ! misho 53: { UPNPANCHOR, "anchor"},
1.1 misho 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"}
65: };
66:
67: int
68: readoptionsfile(const char * fname)
69: {
70: FILE *hfile = NULL;
71: char buffer[1024];
72: char *equals;
73: char *name;
74: char *value;
75: char *t;
76: int linenum = 0;
1.1.1.2 ! misho 77: unsigned int i;
1.1 misho 78: enum upnpconfigoptions id;
1.1.1.2 ! misho 79: size_t string_repo_len = 0;
! 80: size_t len;
! 81: void *tmp;
1.1 misho 82:
83: if(!fname || (strlen(fname) == 0))
84: return -1;
85:
86: memset(buffer, 0, sizeof(buffer));
87:
88: #ifdef DEBUG
89: printf("Reading configuration from file %s\n", fname);
90: #endif
91:
92: if(!(hfile = fopen(fname, "r")))
93: return -1;
94:
95: if(ary_options != NULL)
96: {
97: free(ary_options);
98: num_options = 0;
99: }
100:
101: while(fgets(buffer, sizeof(buffer), hfile))
102: {
103: linenum++;
1.1.1.2 ! misho 104: t = strchr(buffer, '\n');
1.1 misho 105: if(t)
106: {
107: *t = '\0';
108: t--;
1.1.1.2 ! misho 109: /* remove spaces at the end of the line */
1.1 misho 110: while((t >= buffer) && isspace(*t))
111: {
112: *t = '\0';
113: t--;
114: }
115: }
1.1.1.2 ! misho 116:
1.1 misho 117: /* skip leading whitespaces */
118: name = buffer;
119: while(isspace(*name))
120: name++;
121:
122: /* check for comments or empty lines */
123: if(name[0] == '#' || name[0] == '\0') continue;
124:
125: /* check for UPnP permissions rule */
126: if(0 == memcmp(name, "allow", 5) || 0 == memcmp(name, "deny", 4))
127: {
1.1.1.2 ! misho 128: tmp = realloc(upnppermlist, sizeof(struct upnpperm) * (num_upnpperm+1));
! 129: if(tmp == NULL)
1.1 misho 130: {
1.1.1.2 ! misho 131: fprintf(stderr, "memory allocation error. Permission line in file %s line %d\n",
! 132: fname, linenum);
1.1 misho 133: }
134: else
135: {
1.1.1.2 ! misho 136: upnppermlist = tmp;
! 137: /* parse the rule */
! 138: if(read_permission_line(upnppermlist + num_upnpperm, name) >= 0)
! 139: {
! 140: num_upnpperm++;
! 141: }
! 142: else
! 143: {
! 144: fprintf(stderr, "parsing error file %s line %d : %s\n",
! 145: fname, linenum, name);
! 146: }
1.1 misho 147: }
148: continue;
149: }
150: if(!(equals = strchr(name, '=')))
151: {
152: fprintf(stderr, "parsing error file %s line %d : %s\n",
153: fname, linenum, name);
154: continue;
155: }
156:
157: /* remove ending whitespaces */
158: for(t=equals-1; t>name && isspace(*t); t--)
159: *t = '\0';
160:
161: *equals = '\0';
162: value = equals+1;
163:
164: /* skip leading whitespaces */
165: while(isspace(*value))
166: value++;
167:
168: id = UPNP_INVALID;
169: for(i=0; i<sizeof(optionids)/sizeof(optionids[0]); i++)
170: {
171: /*printf("%2d %2d %s %s\n", i, optionids[i].id, name,
172: optionids[i].name); */
173:
174: if(0 == strcmp(name, optionids[i].name))
175: {
176: id = optionids[i].id;
177: break;
178: }
179: }
180:
181: if(id == UPNP_INVALID)
182: {
1.1.1.2 ! misho 183: fprintf(stderr, "invalid option in file %s line %d : %s=%s\n",
1.1 misho 184: fname, linenum, name, value);
185: }
186: else
187: {
1.1.1.2 ! misho 188: tmp = realloc(ary_options, (num_options + 1) * sizeof(struct option));
! 189: if(tmp == NULL)
! 190: {
! 191: fprintf(stderr, "memory allocation error. Option in file %s line %d.\n",
! 192: fname, linenum);
! 193: }
! 194: else
! 195: {
! 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)
! 200: {
! 201: fprintf(stderr, "memory allocation error, Option value in file %s line %d : %s=%s\n",
! 202: fname, linenum, name, value);
! 203: }
! 204: else
! 205: {
! 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;
! 214: }
! 215: }
1.1 misho 216: }
217:
218: }
1.1.1.2 ! misho 219:
1.1 misho 220: fclose(hfile);
1.1.1.2 ! misho 221:
! 222: for(i = 0; i < num_options; i++)
! 223: {
! 224: /* add start address of string_repo to get right pointer */
! 225: ary_options[i].value = string_repo + (size_t)ary_options[i].value;
! 226: }
! 227:
1.1 misho 228: return 0;
229: }
230:
231: void
232: freeoptions(void)
233: {
234: if(ary_options)
235: {
236: free(ary_options);
237: ary_options = NULL;
238: num_options = 0;
239: }
1.1.1.2 ! misho 240: if(string_repo)
! 241: {
! 242: free(string_repo);
! 243: string_repo = NULL;
! 244: }
! 245: if(upnppermlist)
! 246: {
! 247: free(upnppermlist);
! 248: upnppermlist = NULL;
! 249: num_upnpperm = 0;
! 250: }
1.1 misho 251: }
252:
1.1.1.2 ! misho 253: #endif /* DISABLE_CONFIG_FILE */
! 254:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>