1/* MiniUPnP project
2 * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
3 * author: Ryan Wagoner
4 *
5 * Copyright (c) 2006, Thomas Bernard
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *     * Redistributions of source code must retain the above copyright
11 *       notice, this list of conditions and the following disclaimer.
12 *     * Redistributions in binary form must reproduce the above copyright
13 *       notice, this list of conditions and the following disclaimer in the
14 *       documentation and/or other materials provided with the distribution.
15 *     * The name of the author may not be used to endorse or promote products
16 *       derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30#include <stdio.h>
31#include <string.h>
32#include <stdlib.h>
33#include <ctype.h>
34#include "options.h"
35#include "utils.h"
36#include "upnpglobalvars.h"
37
38struct option * ary_options = NULL;
39int num_options = 0;
40
41char *adminfolder[256]; //add by lawrence save USB admin floder name ps:max folder number is 255
42
43static const struct {
44	enum upnpconfigoptions id;
45	const char * name;
46} optionids[] = {
47	{ UPNPIFNAME, "network_interface" },
48	{ UPNPPORT, "port" },
49	{ UPNPPRESENTATIONURL, "presentation_url" },
50	{ UPNPNOTIFY_INTERVAL, "notify_interval" },
51	{ UPNPUUID, "uuid"},
52	{ UPNPSERIAL, "serial"},
53	{ UPNPMODEL_NAME, "model_name"},
54	{ UPNPMODEL_NUMBER, "model_number"},
55	{ UPNPFRIENDLYNAME, "friendly_name"},
56	{ UPNPMEDIADIR, "media_dir"},
57	{ UPNPALBUMART_NAMES, "album_art_names"},
58	{ UPNPINOTIFY, "inotify" },
59	{ UPNPDBDIR, "db_dir" },
60	{ UPNPLOGDIR, "log_dir" },
61	{ UPNPLOGLEVEL, "log_level" },
62	{ UPNPMINISSDPDSOCKET, "minissdpdsocket"},
63	{ ENABLE_TIVO, "enable_tivo" },
64	{ ENABLE_DLNA_STRICT, "strict_dlna" },
65	{ ROOT_CONTAINER, "root_container" },
66	{ USER_ACCOUNT, "user" },
67	{ UPNPMEDIADIRADMIN, "media_dir_admin" }, /*add by lawrence save admin folder  */
68	{ FORCE_SORT_CRITERIA, "force_sort_criteria" },
69	{ MAX_CONNECTIONS, "max_connections" },
70	{ MERGE_MEDIA_DIRS, "merge_media_dirs" }
71};
72
73int
74readoptionsfile(const char * fname)
75{
76	FILE *hfile = NULL;
77	char buffer[1024];
78	char *equals;
79	char *name;
80	char *value;
81	char *t;
82	int linenum = 0;
83	int i;
84	enum upnpconfigoptions id;
85
86
87    int j;
88
89	if(!fname || *fname == '\0')
90		return -1;
91
92	memset(buffer, 0, sizeof(buffer));
93
94#ifdef DEBUG
95	printf("Reading configuration from file %s\n", fname);
96#endif
97
98	if(!(hfile = fopen(fname, "r")))
99		return -1;
100
101
102	/*Foxconn add start by lawrence 2013/02/06 fixed all USB folder can acess*/
103    //Setting empty of adminfolder array
104    for(j=0;j<(sizeof(adminfolder)/sizeof(adminfolder[0]));j++)
105	  adminfolder[j]='\0';
106    j=0;
107	/*Foxconn add start by lawrence 2013/02/06 fixed all USB folder can acess*/
108
109	while(fgets(buffer, sizeof(buffer), hfile))
110	{
111		linenum++;
112		t = strchr(buffer, '\n');
113		if(t)
114		{
115			*t = '\0';
116			t--;
117			while((t >= buffer) && isspace(*t))
118			{
119				*t = '\0';
120				t--;
121			}
122		}
123
124		/* skip leading whitespaces */
125		name = buffer;
126		while(isspace(*name))
127			name++;
128
129		/* check for comments or empty lines */
130		if(name[0] == '#' || name[0] == '\0') continue;
131
132		if(!(equals = strchr(name, '=')))
133		{
134			fprintf(stderr, "parsing error file %s line %d : %s\n",
135			        fname, linenum, name);
136			continue;
137		}
138
139		/* remove ending whitespaces */
140		for(t=equals-1; t>name && isspace(*t); t--)
141			*t = '\0';
142
143		*equals = '\0';
144		value = equals+1;
145
146		/* skip leading whitespaces */
147		while(isspace(*value))
148			value++;
149
150		id = UPNP_INVALID;
151		for(i=0; i<sizeof(optionids)/sizeof(optionids[0]); i++)
152		{
153			/*printf("%2d %2d %s %s\n", i, optionids[i].id, name,
154			       optionids[i].name); */
155
156			if(0 == strcmp(name, optionids[i].name))
157			{
158				id = optionids[i].id;
159				break;
160			}
161		}
162
163		if(id == UPNP_INVALID)
164		{
165			if (strcmp(name, "include") == 0)
166				readoptionsfile(value);
167			else
168				fprintf(stderr, "parsing error file %s line %d : %s=%s\n",
169				        fname, linenum, name, value);
170		}
171		else
172		{
173			num_options++;
174			t = realloc(ary_options, num_options * sizeof(struct option));
175			if(!t)
176			{
177				fprintf(stderr, "memory allocation error: %s=%s\n",
178					name, value);
179				num_options--;
180				continue;
181			}
182			else
183				ary_options = (struct option *)t;
184
185			ary_options[num_options-1].id = id;
186			strncpyt(ary_options[num_options-1].value, value, MAX_OPTION_VALUE_LEN);
187		}
188
189		/*Foxconn add start by lawrence 2013/02/06 fixed all folder can acess*/
190		//save the admin folder to adminfolder
191		if(strcmp(name,"media_dir_admin")==0)
192		{
193		   adminfolder[j]=ary_options[num_options-1].value;
194		   j++;
195		}
196		/*Foxconn add start by lawrence 2013/02/06 fixed all folder can acess*/
197
198
199	}
200
201	fclose(hfile);
202
203	return 0;
204}
205
206void
207freeoptions(void)
208{
209	struct media_dir_s *media_path, *last_path;
210	struct album_art_name_s *art_names, *last_name;
211
212	media_path = media_dirs;
213	while (media_path)
214	{
215		free(media_path->path);
216		last_path = media_path;
217		media_path = media_path->next;
218		free(last_path);
219	}
220
221	art_names = album_art_names;
222	while (art_names)
223	{
224		free(art_names->name);
225		last_name = art_names;
226		art_names = art_names->next;
227		free(last_name);
228	}
229
230	if(ary_options)
231	{
232		free(ary_options);
233		ary_options = NULL;
234		num_options = 0;
235	}
236}
237
238