Mercurial > pt1.oyama
comparison src/cfgparser.c @ 125:e413158cae13
Add ushare project files.
author | naoyan@johnstown.minaminoshima.org |
---|---|
date | Sun, 03 Oct 2010 11:35:19 +0900 |
parents | |
children | 863ac6807ee3 |
comparison
equal
deleted
inserted
replaced
124:9c7bc6c0327e | 125:e413158cae13 |
---|---|
1 /* | |
2 * cfgparser.c : GeeXboX uShare config file parser. | |
3 * Originally developped for the GeeXboX project. | |
4 * Copyright (C) 2005-2007 Alexis Saettler <asbin@asbin.org> | |
5 * | |
6 * This program is free software; you can redistribute it and/or modify | |
7 * it under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; either version 2 of the License, or | |
9 * (at your option) any later version. | |
10 * | |
11 * This program is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 * GNU Library General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License along | |
17 * with this program; if not, write to the Free Software Foundation, | |
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
19 */ | |
20 | |
21 #include <stdio.h> | |
22 #include <stdlib.h> | |
23 #include <string.h> | |
24 #include <getopt.h> | |
25 #include <stdbool.h> | |
26 #include <limits.h> | |
27 | |
28 #include "config.h" | |
29 #include "gettext.h" | |
30 #include "cfgparser.h" | |
31 #include "ushare.h" | |
32 #include "trace.h" | |
33 #include "osdep.h" | |
34 | |
35 #define USHARE_DIR_DELIM "," | |
36 | |
37 static bool | |
38 ignore_line (const char *line) | |
39 { | |
40 int i; | |
41 size_t len; | |
42 | |
43 /* commented line */ | |
44 if (line[0] == '#' ) | |
45 return true; | |
46 | |
47 len = strlen (line); | |
48 | |
49 for (i = 0 ; i < (int) len ; i++ ) | |
50 if (line[i] != ' ' && line[i] != '\t' && line[i] != '\n') | |
51 return false; | |
52 | |
53 return true; | |
54 } | |
55 | |
56 static char * | |
57 strdup_trim (const char *s) | |
58 { | |
59 size_t begin, end; | |
60 char *r = NULL; | |
61 | |
62 if (!s) | |
63 return NULL; | |
64 | |
65 end = strlen (s) - 1; | |
66 | |
67 for (begin = 0 ; begin < end ; begin++) | |
68 if (s[begin] != ' ' && s[begin] != '\t' && s[begin] != '"') | |
69 break; | |
70 | |
71 for (; begin < end ; end--) | |
72 if (s[end] != ' ' && s[end] != '\t' && s[end] != '"' && s[end] != '\n') | |
73 break; | |
74 | |
75 r = strndup (s + begin, end - begin + 1); | |
76 | |
77 return r; | |
78 } | |
79 | |
80 static void | |
81 ushare_set_name (struct ushare_t *ut, const char *name) | |
82 { | |
83 if (!ut || !name) | |
84 return; | |
85 | |
86 if (ut->name) | |
87 { | |
88 free (ut->name); | |
89 ut->name = NULL; | |
90 } | |
91 | |
92 ut->name = strdup_trim (name); | |
93 } | |
94 | |
95 static void | |
96 ushare_set_interface (struct ushare_t *ut, const char *iface) | |
97 { | |
98 if (!ut || !iface) | |
99 return; | |
100 | |
101 if (ut->interface) | |
102 { | |
103 free (ut->interface); | |
104 ut->interface = NULL; | |
105 } | |
106 | |
107 ut->interface = strdup_trim (iface); | |
108 } | |
109 | |
110 static void | |
111 ushare_add_contentdir (struct ushare_t *ut, const char *dir) | |
112 { | |
113 if (!ut || !dir) | |
114 return; | |
115 | |
116 ut->contentlist = content_add (ut->contentlist, dir); | |
117 } | |
118 | |
119 static void | |
120 ushare_set_cfg_file (struct ushare_t *ut, const char *file) | |
121 { | |
122 if (!ut || !file) | |
123 return; | |
124 | |
125 ut->cfg_file = strdup (file); | |
126 } | |
127 | |
128 static void | |
129 ushare_set_dir (struct ushare_t *ut, const char *dirlist) | |
130 { | |
131 char *x = NULL, *token = NULL; | |
132 char *m_buffer = NULL, *buffer; | |
133 | |
134 if (!ut || !dirlist) | |
135 return; | |
136 | |
137 x = strdup_trim (dirlist); | |
138 if (x) | |
139 { | |
140 m_buffer = (char*) malloc (strlen (x) * sizeof (char)); | |
141 if (m_buffer) | |
142 { | |
143 buffer = m_buffer; | |
144 token = strtok_r (x, USHARE_DIR_DELIM, &buffer); | |
145 while (token) | |
146 { | |
147 ushare_add_contentdir (ut, token); | |
148 token = strtok_r (NULL, USHARE_DIR_DELIM, &buffer); | |
149 } | |
150 free (m_buffer); | |
151 } | |
152 free (x); | |
153 } | |
154 } | |
155 | |
156 static void | |
157 ushare_set_port (struct ushare_t *ut, const char *port) | |
158 { | |
159 if (!ut || !port) | |
160 return; | |
161 | |
162 ut->port = atoi (port); | |
163 if (ut->port < 49152) | |
164 { | |
165 fprintf (stderr, | |
166 _("Warning: port doesn't fit IANA port assignements.\n")); | |
167 | |
168 fprintf (stderr, _("Warning: Only Dynamic or Private Ports can be used " | |
169 "(from 49152 through 65535)\n")); | |
170 ut->port = 0; | |
171 } | |
172 } | |
173 | |
174 static void | |
175 ushare_set_telnet_port (struct ushare_t *ut, const char *port) | |
176 { | |
177 if (!ut || !port) | |
178 return; | |
179 | |
180 ut->telnet_port = atoi (port); | |
181 } | |
182 | |
183 static void | |
184 ushare_use_web (struct ushare_t *ut, const char *val) | |
185 { | |
186 if (!ut || !val) | |
187 return; | |
188 | |
189 ut->use_presentation = (!strcmp (val, "yes")) ? true : false; | |
190 } | |
191 | |
192 static void | |
193 ushare_use_telnet (struct ushare_t *ut, const char *val) | |
194 { | |
195 if (!ut || !val) | |
196 return; | |
197 | |
198 ut->use_telnet = (!strcmp (val, "yes")) ? true : false; | |
199 } | |
200 | |
201 static void | |
202 ushare_use_xbox (struct ushare_t *ut, const char *val) | |
203 { | |
204 if (!ut || !val) | |
205 return; | |
206 | |
207 ut->xbox360 = (!strcmp (val, "yes")) ? true : false; | |
208 } | |
209 | |
210 static void | |
211 ushare_use_dlna (struct ushare_t *ut, const char *val) | |
212 { | |
213 if (!ut || !val) | |
214 return; | |
215 | |
216 #ifdef HAVE_DLNA | |
217 ut->dlna_enabled = (!strcmp (val, "yes")) ? true : false; | |
218 #endif /* HAVE_DLNA */ | |
219 } | |
220 | |
221 static void | |
222 ushare_set_override_iconv_err (struct ushare_t *ut, const char *arg) | |
223 { | |
224 if (!ut) | |
225 return; | |
226 | |
227 ut->override_iconv_err = false; | |
228 | |
229 if (!strcasecmp (arg, "yes") | |
230 || !strcasecmp (arg, "true") | |
231 || !strcmp (arg, "1")) | |
232 ut->override_iconv_err = true; | |
233 } | |
234 | |
235 static u_configline_t configline[] = { | |
236 { USHARE_NAME, ushare_set_name }, | |
237 { USHARE_IFACE, ushare_set_interface }, | |
238 { USHARE_PORT, ushare_set_port }, | |
239 { USHARE_TELNET_PORT, ushare_set_telnet_port }, | |
240 { USHARE_DIR, ushare_set_dir }, | |
241 { USHARE_OVERRIDE_ICONV_ERR, ushare_set_override_iconv_err }, | |
242 { USHARE_ENABLE_WEB, ushare_use_web }, | |
243 { USHARE_ENABLE_TELNET, ushare_use_telnet }, | |
244 { USHARE_ENABLE_XBOX, ushare_use_xbox }, | |
245 { USHARE_ENABLE_DLNA, ushare_use_dlna }, | |
246 { NULL, NULL }, | |
247 }; | |
248 | |
249 static void | |
250 parse_config_line (struct ushare_t *ut, const char *line, | |
251 u_configline_t *configline) | |
252 { | |
253 char *s = NULL; | |
254 | |
255 s = strchr (line, '='); | |
256 if (s && s[1] != '\0') | |
257 { | |
258 int i; | |
259 for (i=0 ; configline[i].name ; i++) | |
260 { | |
261 if (!strncmp (line, configline[i].name, strlen (configline[i].name))) | |
262 { | |
263 configline[i].set_var (ut, s + 1); | |
264 break; | |
265 } | |
266 } | |
267 } | |
268 } | |
269 | |
270 int | |
271 parse_config_file (struct ushare_t *ut) | |
272 { | |
273 char filename[PATH_MAX]; | |
274 FILE *conffile; | |
275 char *line = NULL; | |
276 size_t size = 0; | |
277 ssize_t read; | |
278 | |
279 if (!ut) | |
280 return -1; | |
281 | |
282 if (!ut->cfg_file) | |
283 snprintf (filename, PATH_MAX, "%s/%s", SYSCONFDIR, USHARE_CONFIG_FILE); | |
284 else | |
285 snprintf (filename, PATH_MAX, "%s", ut->cfg_file); | |
286 | |
287 conffile = fopen (filename, "r"); | |
288 if (!conffile) | |
289 return -1; | |
290 | |
291 while ((read = getline (&line, &size, conffile)) != -1) | |
292 { | |
293 if (ignore_line (line)) | |
294 continue; | |
295 | |
296 if (line[read-1] == '\n') | |
297 line[read-1] = '\0'; | |
298 | |
299 while (line[0] == ' ' || line[0] == '\t') | |
300 line++; | |
301 | |
302 parse_config_line (ut, line, configline); | |
303 } | |
304 | |
305 fclose (conffile); | |
306 | |
307 if (line) | |
308 free (line); | |
309 | |
310 return 0; | |
311 } | |
312 | |
313 inline static void | |
314 display_usage (void) | |
315 { | |
316 display_headers (); | |
317 printf ("\n"); | |
318 printf (_("Usage: ushare [-n name] [-i interface] [-p port] [-c directory] [[-c directory]...]\n")); | |
319 printf (_("Options:\n")); | |
320 printf (_(" -n, --name=NAME\tSet UPnP Friendly Name (default is '%s')\n"), | |
321 DEFAULT_USHARE_NAME); | |
322 printf (_(" -i, --interface=IFACE\tUse IFACE Network Interface (default is '%s')\n"), | |
323 DEFAULT_USHARE_IFACE); | |
324 printf (_(" -f, --cfg=FILE\t\tConfig file to be used\n")); | |
325 printf (_(" -p, --port=PORT\tForces the HTTP server to run on PORT\n")); | |
326 printf (_(" -q, --telnet-port=PORT\tForces the TELNET server to run on PORT\n")); | |
327 printf (_(" -c, --content=DIR\tShare the content of DIR directory\n")); | |
328 printf (_(" -w, --no-web\t\tDisable the control web page (enabled by default)\n")); | |
329 printf (_(" -t, --no-telnet\tDisable the TELNET control (enabled by default)\n")); | |
330 printf (_(" -o, --override-iconv-err\tIf iconv fails parsing name, still add to media contents (hoping the renderer can handle it)\n")); | |
331 printf (_(" -v, --verbose\t\tSet verbose display\n")); | |
332 printf (_(" -x, --xbox\t\tUse XboX 360 compliant profile\n")); | |
333 #ifdef HAVE_DLNA | |
334 printf (_(" -d, --dlna\t\tUse DLNA compliant profile (PlayStation3 needs this)\n")); | |
335 #endif /* HAVE_DLNA */ | |
336 printf (_(" -D, --daemon\t\tRun as a daemon\n")); | |
337 printf (_(" -V, --version\t\tDisplay the version of uShare and exit\n")); | |
338 printf (_(" -h, --help\t\tDisplay this help\n")); | |
339 } | |
340 | |
341 int | |
342 parse_command_line (struct ushare_t *ut, int argc, char **argv) | |
343 { | |
344 int c, index; | |
345 char short_options[] = "VhvDowtxdn:i:p:q:c:f:"; | |
346 struct option long_options [] = { | |
347 {"version", no_argument, 0, 'V' }, | |
348 {"help", no_argument, 0, 'h' }, | |
349 {"verbose", no_argument, 0, 'v' }, | |
350 {"daemon", no_argument, 0, 'D' }, | |
351 {"override-iconv-err", no_argument, 0, 'o' }, | |
352 {"name", required_argument, 0, 'n' }, | |
353 {"interface", required_argument, 0, 'i' }, | |
354 {"port", required_argument, 0, 'p' }, | |
355 {"telnet-port", required_argument, 0, 'q' }, | |
356 {"content", required_argument, 0, 'c' }, | |
357 {"no-web", no_argument, 0, 'w' }, | |
358 {"no-telnet", no_argument, 0, 't' }, | |
359 {"xbox", no_argument, 0, 'x' }, | |
360 #ifdef HAVE_DLNA | |
361 {"dlna", no_argument, 0, 'd' }, | |
362 #endif /* HAVE_DLNA */ | |
363 {"cfg", required_argument, 0, 'f' }, | |
364 {0, 0, 0, 0 } | |
365 }; | |
366 | |
367 /* command line argument processing */ | |
368 while (true) | |
369 { | |
370 c = getopt_long (argc, argv, short_options, long_options, &index); | |
371 | |
372 if (c == EOF) | |
373 break; | |
374 | |
375 switch (c) | |
376 { | |
377 case 0: | |
378 /* opt = long_options[index].name; */ | |
379 break; | |
380 | |
381 case '?': | |
382 case 'h': | |
383 display_usage (); | |
384 return -1; | |
385 | |
386 case 'V': | |
387 display_headers (); | |
388 return -1; | |
389 | |
390 case 'v': | |
391 ut->verbose = true; | |
392 break; | |
393 | |
394 case 'D': | |
395 ut->daemon = true; | |
396 break; | |
397 | |
398 case 'o': | |
399 ut->override_iconv_err = true; | |
400 break; | |
401 | |
402 case 'n': | |
403 ushare_set_name (ut, optarg); | |
404 break; | |
405 | |
406 case 'i': | |
407 ushare_set_interface (ut, optarg); | |
408 break; | |
409 | |
410 case 'p': | |
411 ushare_set_port (ut, optarg); | |
412 break; | |
413 | |
414 case 'q': | |
415 ushare_set_telnet_port (ut, optarg); | |
416 break; | |
417 | |
418 case 'c': | |
419 ushare_add_contentdir (ut, optarg); | |
420 break; | |
421 | |
422 case 'w': | |
423 ut->use_presentation = false; | |
424 break; | |
425 | |
426 case 't': | |
427 ut->use_telnet = false; | |
428 break; | |
429 | |
430 case 'x': | |
431 ut->xbox360 = true; | |
432 break; | |
433 | |
434 #ifdef HAVE_DLNA | |
435 case 'd': | |
436 ut->dlna_enabled = true; | |
437 break; | |
438 #endif /* HAVE_DLNA */ | |
439 | |
440 case 'f': | |
441 ushare_set_cfg_file (ut, optarg); | |
442 break; | |
443 | |
444 default: | |
445 break; | |
446 } | |
447 } | |
448 | |
449 return 0; | |
450 } |