1 /* MiniDLNA project
2  *
3  * http://sourceforge.net/projects/minidlna/
4  *
5  * MiniDLNA media server
6  * Copyright (C) 2008-2012  Justin Maggard
7  *
8  * This file is part of MiniDLNA.
9  *
10  * MiniDLNA is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  *
14  * MiniDLNA is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with MiniDLNA. If not, see <http://www.gnu.org/licenses/>.
21  *
22  * Portions of the code from the MiniUPnP project:
23  *
24  * Copyright (c) 2006-2007, Thomas Bernard
25  * All rights reserved.
26  *
27  * Redistribution and use in source and binary forms, with or without
28  * modification, are permitted provided that the following conditions are met:
29  *     * Redistributions of source code must retain the above copyright
30  *       notice, this list of conditions and the following disclaimer.
31  *     * Redistributions in binary form must reproduce the above copyright
32  *       notice, this list of conditions and the following disclaimer in the
33  *       documentation and/or other materials provided with the distribution.
34  *     * The name of the author may not be used to endorse or promote products
35  *       derived from this software without specific prior written permission.
36  *
37  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
38  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
40  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
41  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
43  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
44  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
45  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
47  * POSSIBILITY OF SUCH DAMAGE.
48  */
49 #include <stdlib.h>
50 #include <unistd.h>
51 #include <string.h>
52 #include <stdio.h>
53 #include <ctype.h>
54 #include <sys/types.h>
55 #include <sys/socket.h>
56 #include <sys/wait.h>
57 #include <sys/file.h>
58 #include <sys/time.h>
59 #include <sys/param.h>
60 #include <sys/stat.h>
61 #include <netinet/in.h>
62 #include <arpa/inet.h>
63 #include <fcntl.h>
64 #include <time.h>
65 #include <signal.h>
66 #include <errno.h>
67 #include <limits.h>
68 #include <libgen.h>
69 #include <pwd.h>
70 #include <grp.h>
71 
72 #include "config.h"
73 
74 #ifdef ENABLE_NLS
75 #include <locale.h>
76 #include <libintl.h>
77 #endif
78 
79 #include "event.h"
80 #include "upnpglobalvars.h"
81 #include "sql.h"
82 #include "upnphttp.h"
83 #include "upnpdescgen.h"
84 #include "minidlnapath.h"
85 #include "getifaddr.h"
86 #include "upnpsoap.h"
87 #include "options.h"
88 #include "utils.h"
89 #include "minissdp.h"
90 #include "minidlnatypes.h"
91 #include "process.h"
92 #include "upnpevents.h"
93 #include "scanner.h"
94 #include "monitor.h"
95 #include "libav.h"
96 #include "log.h"
97 #include "tivo_beacon.h"
98 #include "tivo_utils.h"
99 #include "avahi.h"
100 
101 #if SQLITE_VERSION_NUMBER < 3005001
102 # warning "Your SQLite3 library appears to be too old!  Please use 3.5.1 or newer."
103 # define sqlite3_threadsafe() 0
104 #endif
105 
106 static LIST_HEAD(httplisthead, upnphttp) upnphttphead;
107 
108 /* OpenAndConfHTTPSocket() :
109  * setup the socket used to handle incoming HTTP connections. */
110 static int
OpenAndConfHTTPSocket(unsigned short port)111 OpenAndConfHTTPSocket(unsigned short port)
112 {
113 	int s;
114 	int i = 1;
115 	struct sockaddr_in listenname;
116 
117 	/* Initialize client type cache */
118 	memset(&clients, 0, sizeof(struct client_cache_s));
119 
120 	s = socket(PF_INET, SOCK_STREAM, 0);
121 	if (s < 0)
122 	{
123 		DPRINTF(E_ERROR, L_GENERAL, "socket(http): %s\n", strerror(errno));
124 		return -1;
125 	}
126 
127 	if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)) < 0)
128 		DPRINTF(E_WARN, L_GENERAL, "setsockopt(http, SO_REUSEADDR): %s\n", strerror(errno));
129 
130 	memset(&listenname, 0, sizeof(struct sockaddr_in));
131 	listenname.sin_family = AF_INET;
132 	listenname.sin_port = htons(port);
133 	listenname.sin_addr.s_addr = htonl(INADDR_ANY);
134 
135 	if (bind(s, (struct sockaddr *)&listenname, sizeof(struct sockaddr_in)) < 0)
136 	{
137 		DPRINTF(E_ERROR, L_GENERAL, "bind(http): %s\n", strerror(errno));
138 		close(s);
139 		return -1;
140 	}
141 
142 	if (listen(s, 16) < 0)
143 	{
144 		DPRINTF(E_ERROR, L_GENERAL, "listen(http): %s\n", strerror(errno));
145 		close(s);
146 		return -1;
147 	}
148 
149 	return s;
150 }
151 
152 /* ProcessListen() :
153  * accept incoming HTTP connection. */
154 static void
ProcessListen(struct event * ev)155 ProcessListen(struct event *ev)
156 {
157 	int shttp;
158 	socklen_t clientnamelen;
159 	struct sockaddr_in clientname;
160 	clientnamelen = sizeof(struct sockaddr_in);
161 
162 	shttp = accept(ev->fd, (struct sockaddr *)&clientname, &clientnamelen);
163 	if (shttp<0)
164 	{
165 		DPRINTF(E_ERROR, L_GENERAL, "accept(http): %s\n", strerror(errno));
166 	}
167 	else
168 	{
169 		struct upnphttp * tmp = 0;
170 		DPRINTF(E_DEBUG, L_GENERAL, "HTTP connection from %s:%d\n",
171 			inet_ntoa(clientname.sin_addr),
172 			ntohs(clientname.sin_port) );
173 		/*if (fcntl(shttp, F_SETFL, O_NONBLOCK) < 0) {
174 			DPRINTF(E_ERROR, L_GENERAL, "fcntl F_SETFL, O_NONBLOCK\n");
175 		}*/
176 		/* Create a new upnphttp object and add it to
177 		 * the active upnphttp object list */
178 		tmp = New_upnphttp(shttp);
179 		if (tmp)
180 		{
181 			tmp->clientaddr = clientname.sin_addr;
182 			LIST_INSERT_HEAD(&upnphttphead, tmp, entries);
183 		}
184 		else
185 		{
186 			DPRINTF(E_ERROR, L_GENERAL, "New_upnphttp() failed\n");
187 			close(shttp);
188 		}
189 	}
190 }
191 
192 /* Handler for the SIGTERM signal (kill)
193  * SIGINT is also handled */
194 static void
sigterm(int sig)195 sigterm(int sig)
196 {
197 	signal(sig, SIG_IGN);	/* Ignore this signal while we are quitting */
198 
199 	DPRINTF(E_WARN, L_GENERAL, "received signal %d, good-bye\n", sig);
200 
201 	quitting = 1;
202 }
203 
204 static void
sigusr1(int sig)205 sigusr1(int sig)
206 {
207 	signal(sig, sigusr1);
208 	DPRINTF(E_WARN, L_GENERAL, "received signal %d, clear cache\n", sig);
209 
210 	memset(&clients, '\0', sizeof(clients));
211 }
212 
213 static void
sighup(int sig)214 sighup(int sig)
215 {
216 	signal(sig, sighup);
217 	DPRINTF(E_WARN, L_GENERAL, "received signal %d, reloading\n", sig);
218 
219 	reload_ifaces(1);
220 	log_reopen();
221 }
222 
223 /* record the startup time */
224 static void
set_startup_time(void)225 set_startup_time(void)
226 {
227 	startup_time = time(NULL);
228 }
229 
230 static void
getfriendlyname(char * buf,int len)231 getfriendlyname(char *buf, int len)
232 {
233 	char *p = NULL;
234 	char hn[63];
235 	int off;
236 
237 	if (gethostname(hn, sizeof(hn)) == 0)
238 	{
239 		strncpyt(buf, hn, len);
240 		p = strchr(buf, '.');
241 		if (p)
242 			*p = '\0';
243 	}
244 	else
245 		strcpy(buf, "Unknown");
246 
247 	off = strlen(buf);
248 	off += snprintf(buf+off, len-off, ": ");
249 #ifdef READYNAS
250 	FILE *info;
251 	char ibuf[64], *key, *val;
252 	snprintf(buf+off, len-off, "ReadyNAS");
253 	info = fopen("/proc/sys/dev/boot/info", "r");
254 	if (!info)
255 		return;
256 	while ((val = fgets(ibuf, 64, info)) != NULL)
257 	{
258 		key = strsep(&val, ": \t");
259 		val = trim(val);
260 		if (strcmp(key, "model") == 0)
261 		{
262 			snprintf(buf+off, len-off, "%s", val);
263 			key = strchr(val, ' ');
264 			if (key)
265 			{
266 				strncpyt(modelnumber, key+1, MODELNUMBER_MAX_LEN);
267 				*key = '\0';
268 			}
269 			snprintf(modelname, MODELNAME_MAX_LEN,
270 				"Windows Media Connect compatible (%s)", val);
271 		}
272 		else if (strcmp(key, "serial") == 0)
273 		{
274 			strncpyt(serialnumber, val, SERIALNUMBER_MAX_LEN);
275 			if (serialnumber[0] == '\0')
276 			{
277 				char mac_str[13];
278 				if (getsyshwaddr(mac_str, sizeof(mac_str)) == 0)
279 					strcpy(serialnumber, mac_str);
280 				else
281 					strcpy(serialnumber, "0");
282 			}
283 			break;
284 		}
285 	}
286 	fclose(info);
287 #else
288 	char * logname;
289 	logname = getenv("USER");
290 	if (!logname)
291         {
292 		logname = getenv("LOGNAME");
293 #ifndef STATIC // Disable for static linking
294 		if (!logname)
295 		{
296 			struct passwd *pwent = getpwuid(geteuid());
297 			if (pwent)
298 				logname = pwent->pw_name;
299 		}
300 #endif
301 	}
302 	snprintf(buf+off, len-off, "%s", logname?logname:"Unknown");
303 #endif
304 }
305 
306 static time_t
_get_dbtime(void)307 _get_dbtime(void)
308 {
309 	char path[PATH_MAX];
310 	struct stat st;
311 
312 	snprintf(path, sizeof(path), "%s/files.db", db_path);
313 	if (stat(path, &st) != 0)
314 		return 0;
315 	return st.st_mtime;
316 }
317 
318 static int
open_db(sqlite3 ** sq3)319 open_db(sqlite3 **sq3)
320 {
321 	char path[PATH_MAX];
322 	int new_db = 0;
323 
324 	snprintf(path, sizeof(path), "%s/files.db", db_path);
325 	if (access(path, F_OK) != 0)
326 	{
327 		new_db = 1;
328 		make_dir(db_path, S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO);
329 	}
330 	if (sqlite3_open(path, &db) != SQLITE_OK)
331 		DPRINTF(E_FATAL, L_GENERAL, "ERROR: Failed to open sqlite database!  Exiting...\n");
332 	if (sq3)
333 		*sq3 = db;
334 	sqlite3_busy_timeout(db, 5000);
335 	sql_exec(db, "pragma page_size = 4096");
336 	sql_exec(db, "pragma journal_mode = OFF");
337 	sql_exec(db, "pragma synchronous = OFF;");
338 	sql_exec(db, "pragma default_cache_size = 8192;");
339 
340 	return new_db;
341 }
342 
343 static void
check_db(sqlite3 * db,int new_db,pid_t * scanner_pid)344 check_db(sqlite3 *db, int new_db, pid_t *scanner_pid)
345 {
346 	struct media_dir_s *media_path = NULL;
347 	char cmd[PATH_MAX*2];
348 	char **result;
349 	int i, rows = 0;
350 	int ret;
351 
352 	if (!new_db)
353 	{
354 		/* Check if any new media dirs appeared */
355 		media_path = media_dirs;
356 		while (media_path)
357 		{
358 			ret = sql_get_int_field(db, "SELECT TIMESTAMP as TYPE from DETAILS where PATH = %Q",
359 						media_path->path);
360 			if (ret != media_path->types)
361 			{
362 				ret = 1;
363 				goto rescan;
364 			}
365 			media_path = media_path->next;
366 		}
367 		/* Check if any media dirs disappeared */
368 		sql_get_table(db, "SELECT VALUE from SETTINGS where KEY = 'media_dir'", &result, &rows, NULL);
369 		for (i=1; i <= rows; i++)
370 		{
371 			media_path = media_dirs;
372 			while (media_path)
373 			{
374 				if (strcmp(result[i], media_path->path) == 0)
375 					break;
376 				media_path = media_path->next;
377 			}
378 			if (!media_path)
379 			{
380 				ret = 2;
381 				sqlite3_free_table(result);
382 				goto rescan;
383 			}
384 		}
385 		sqlite3_free_table(result);
386 	}
387 
388 	ret = db_upgrade(db);
389 	if (ret != 0)
390 	{
391 rescan:
392 		CLEARFLAG(RESCAN_MASK);
393 		if (ret < 0)
394 			DPRINTF(E_WARN, L_GENERAL, "Creating new database at %s/files.db\n", db_path);
395 		else if (ret == 1)
396 			DPRINTF(E_WARN, L_GENERAL, "New media_dir detected; rebuilding...\n");
397 		else if (ret == 2)
398 			DPRINTF(E_WARN, L_GENERAL, "Removed media_dir detected; rebuilding...\n");
399 		else
400 			DPRINTF(E_WARN, L_GENERAL, "Database version mismatch (%d => %d); need to recreate...\n",
401 				ret, DB_VERSION);
402 		sqlite3_close(db);
403 
404 		snprintf(cmd, sizeof(cmd), "rm -rf %s/files.db %s/art_cache", db_path, db_path);
405 		if (system(cmd) != 0)
406 			DPRINTF(E_FATAL, L_GENERAL, "Failed to clean old file cache!  Exiting...\n");
407 
408 		open_db(&db);
409 		if (CreateDatabase() != 0)
410 			DPRINTF(E_FATAL, L_GENERAL, "ERROR: Failed to create sqlite database!  Exiting...\n");
411 	}
412 	if (ret || GETFLAG(RESCAN_MASK))
413 	{
414 #if USE_FORK
415 		sqlite3_close(db);
416 		*scanner_pid = fork();
417 		open_db(&db);
418 		if (*scanner_pid == 0) /* child (scanner) process */
419 		{
420 			start_scanner();
421 			sqlite3_close(db);
422 			log_close();
423 			freeoptions();
424 			free(children);
425 			exit(EXIT_SUCCESS);
426 		}
427 		else if (*scanner_pid < 0)
428 		{
429 			start_scanner();
430 		}
431 		else
432 			SETFLAG(SCANNING_MASK);
433 #else
434 		start_scanner();
435 #endif
436 	}
437 }
438 
439 static int
writepidfile(const char * fname,int pid,uid_t uid)440 writepidfile(const char *fname, int pid, uid_t uid)
441 {
442 	FILE *pidfile;
443 	struct stat st;
444 	char path[PATH_MAX], *dir;
445 	int ret = 0;
446 
447 	if(!fname || *fname == '\0')
448 		return -1;
449 
450 	/* Create parent directory if it doesn't already exist */
451 	strncpyt(path, fname, sizeof(path));
452 	dir = dirname(path);
453 	if (stat(dir, &st) == 0)
454 	{
455 		if (!S_ISDIR(st.st_mode))
456 		{
457 			DPRINTF(E_ERROR, L_GENERAL, "Pidfile path is not a directory: %s\n",
458 				fname);
459 			return -1;
460 		}
461 	}
462 	else
463 	{
464 		if (make_dir(dir, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) != 0)
465 		{
466 			DPRINTF(E_ERROR, L_GENERAL, "Unable to create pidfile directory: %s\n",
467 				fname);
468 			return -1;
469 		}
470 		if (uid > 0)
471 		{
472 			if (chown(dir, uid, -1) != 0)
473 				DPRINTF(E_WARN, L_GENERAL, "Unable to change pidfile %s ownership: %s\n",
474 					dir, strerror(errno));
475 		}
476 	}
477 
478 	pidfile = fopen(fname, "w");
479 	if (!pidfile)
480 	{
481 		DPRINTF(E_ERROR, L_GENERAL, "Unable to open pidfile for writing %s: %s\n",
482 			fname, strerror(errno));
483 		return -1;
484 	}
485 
486 	if (fprintf(pidfile, "%d\n", pid) <= 0)
487 	{
488 		DPRINTF(E_ERROR, L_GENERAL,
489 			"Unable to write to pidfile %s: %s\n", fname, strerror(errno));
490 		ret = -1;
491 	}
492 	if (uid > 0)
493 	{
494 		if (fchown(fileno(pidfile), uid, -1) != 0)
495 			DPRINTF(E_WARN, L_GENERAL, "Unable to change pidfile %s ownership: %s\n",
496 				fname, strerror(errno));
497 	}
498 
499 	fclose(pidfile);
500 
501 	return ret;
502 }
503 
strtobool(const char * str)504 static int strtobool(const char *str)
505 {
506 	return ((strcasecmp(str, "yes") == 0) ||
507 		(strcasecmp(str, "true") == 0) ||
508 		(atoi(str) == 1));
509 }
510 
init_nls(void)511 static void init_nls(void)
512 {
513 #ifdef ENABLE_NLS
514 	const char *messages, *ctype, *locale_dir;
515 
516 	ctype = setlocale(LC_CTYPE, "");
517 	if (!ctype || !strcmp(ctype, "C"))
518 		ctype = setlocale(LC_CTYPE, "en_US.utf8");
519 	if (!ctype)
520 		DPRINTF(E_WARN, L_GENERAL, "Unset locale\n");
521 	else if (!strstr(ctype, "utf8") && !strstr(ctype, "UTF8") &&
522 		 !strstr(ctype, "utf-8") && !strstr(ctype, "UTF-8"))
523 		DPRINTF(E_WARN, L_GENERAL, "Using unsupported non-utf8 locale '%s'\n", ctype);
524 	messages = setlocale(LC_MESSAGES, "");
525 	if (!messages)
526 		messages = "unset";
527 	locale_dir = bindtextdomain("minidlna", getenv("TEXTDOMAINDIR"));
528 	DPRINTF(E_DEBUG, L_GENERAL, "Using locale dir '%s' and locale langauge %s/%s\n", locale_dir, messages, ctype);
529 	textdomain("minidlna");
530 #endif
531 }
532 
533 /* init phase :
534  * 1) read configuration file
535  * 2) read command line arguments
536  * 3) daemonize
537  * 4) check and write pid file
538  * 5) set startup time stamp
539  * 6) compute presentation URL
540  * 7) set signal handlers */
541 static int
init(int argc,char ** argv)542 init(int argc, char **argv)
543 {
544 	int i;
545 	int pid;
546 	int debug_flag = 0;
547 	int verbose_flag = 0;
548 	int options_flag = 0;
549 	struct sigaction sa;
550 	const char * presurl = NULL;
551 	const char * optionsfile = "/etc/minidlna.conf";
552 	char mac_str[13];
553 	char *string, *word;
554 	char *path;
555 	char buf[PATH_MAX];
556 	char log_str[75] = "general,artwork,database,inotify,scanner,metadata,http,ssdp,tivo=warn";
557 	char *log_level = NULL;
558 	struct media_dir_s *media_dir;
559 	int ifaces = 0;
560 	media_types types;
561 	uid_t uid = 0;
562 	gid_t gid = 0;
563 	int error;
564 
565 	/* first check if "-f" option is used */
566 	for (i=2; i<argc; i++)
567 	{
568 		if (strcmp(argv[i-1], "-f") == 0)
569 		{
570 			optionsfile = argv[i];
571 			options_flag = 1;
572 			break;
573 		}
574 	}
575 
576 	/* set up uuid based on mac address */
577 	if (getsyshwaddr(mac_str, sizeof(mac_str)) < 0)
578 	{
579 		DPRINTF(E_OFF, L_GENERAL, "No MAC address found.  Falling back to generic UUID.\n");
580 		strcpy(mac_str, "554e4b4e4f57");
581 	}
582 	snprintf(uuidvalue+5, UUIDVALUE_MAX_LEN-5, "4d696e69-444c-164e-9d41-%s", mac_str);
583 
584 	getfriendlyname(friendly_name, FRIENDLYNAME_MAX_LEN);
585 
586 	runtime_vars.port = 8200;
587 	runtime_vars.notify_interval = 895;	/* seconds between SSDP announces */
588 	runtime_vars.max_connections = 50;
589 	runtime_vars.root_container = NULL;
590 	runtime_vars.ifaces[0] = NULL;
591 
592 	/* read options file first since
593 	 * command line arguments have final say */
594 	if (readoptionsfile(optionsfile) < 0)
595 	{
596 		/* only error if file exists or using -f */
597 		if(access(optionsfile, F_OK) == 0 || options_flag)
598 			DPRINTF(E_FATAL, L_GENERAL, "Error reading configuration file %s\n", optionsfile);
599 	}
600 
601 	for (i=0; i<num_options; i++)
602 	{
603 		switch (ary_options[i].id)
604 		{
605 		case UPNPIFNAME:
606 			for (string = ary_options[i].value; (word = strtok(string, ",")); string = NULL)
607 			{
608 				if (ifaces >= MAX_LAN_ADDR)
609 				{
610 					DPRINTF(E_ERROR, L_GENERAL, "Too many interfaces (max: %d), ignoring %s\n",
611 						MAX_LAN_ADDR, word);
612 					break;
613 				}
614 				while (isspace(*word))
615 					word++;
616 				runtime_vars.ifaces[ifaces++] = word;
617 			}
618 			break;
619 		case UPNPPORT:
620 			runtime_vars.port = atoi(ary_options[i].value);
621 			break;
622 		case UPNPPRESENTATIONURL:
623 			presurl = ary_options[i].value;
624 			break;
625 		case UPNPNOTIFY_INTERVAL:
626 			runtime_vars.notify_interval = atoi(ary_options[i].value);
627 			break;
628 		case UPNPSERIAL:
629 			strncpyt(serialnumber, ary_options[i].value, SERIALNUMBER_MAX_LEN);
630 			break;
631 		case UPNPMODEL_NAME:
632 			strncpyt(modelname, ary_options[i].value, MODELNAME_MAX_LEN);
633 			break;
634 		case UPNPMODEL_NUMBER:
635 			strncpyt(modelnumber, ary_options[i].value, MODELNUMBER_MAX_LEN);
636 			break;
637 		case UPNPFRIENDLYNAME:
638 			strncpyt(friendly_name, ary_options[i].value, FRIENDLYNAME_MAX_LEN);
639 			break;
640 		case UPNPMEDIADIR:
641 			types = ALL_MEDIA;
642 			path = ary_options[i].value;
643 			word = strchr(path, ',');
644 			if (word && (access(path, F_OK) != 0))
645 			{
646 				types = 0;
647 				while (*path)
648 				{
649 					if (*path == ',')
650 					{
651 						path++;
652 						break;
653 					}
654 					else if (*path == 'A' || *path == 'a')
655 						types |= TYPE_AUDIO;
656 					else if (*path == 'V' || *path == 'v')
657 						types |= TYPE_VIDEO;
658 					else if (*path == 'P' || *path == 'p')
659 						types |= TYPE_IMAGE;
660 					else
661 						DPRINTF(E_FATAL, L_GENERAL, "Media directory entry not understood [%s]\n",
662 							ary_options[i].value);
663 					path++;
664 				}
665 			}
666 			path = realpath(path, buf);
667 			if (!path || access(path, F_OK) != 0)
668 			{
669 				DPRINTF(E_ERROR, L_GENERAL, "Media directory \"%s\" not accessible [%s]\n",
670 					ary_options[i].value, strerror(errno));
671 				break;
672 			}
673 			media_dir = calloc(1, sizeof(struct media_dir_s));
674 			media_dir->path = strdup(path);
675 			media_dir->types = types;
676 			if (media_dirs)
677 			{
678 				struct media_dir_s *all_dirs = media_dirs;
679 				while( all_dirs->next )
680 					all_dirs = all_dirs->next;
681 				all_dirs->next = media_dir;
682 			}
683 			else
684 				media_dirs = media_dir;
685 			break;
686 		case UPNPALBUMART_NAMES:
687 			for (string = ary_options[i].value; (word = strtok(string, "/")); string = NULL)
688 			{
689 				struct album_art_name_s * this_name = calloc(1, sizeof(struct album_art_name_s));
690 				int len = strlen(word);
691 				if (word[len-1] == '*')
692 				{
693 					word[len-1] = '\0';
694 					this_name->wildcard = 1;
695 				}
696 				this_name->name = strdup(word);
697 				if (album_art_names)
698 				{
699 					struct album_art_name_s * all_names = album_art_names;
700 					while( all_names->next )
701 						all_names = all_names->next;
702 					all_names->next = this_name;
703 				}
704 				else
705 					album_art_names = this_name;
706 			}
707 			break;
708 		case UPNPDBDIR:
709 			path = realpath(ary_options[i].value, buf);
710 			if (!path)
711 				path = (ary_options[i].value);
712 			make_dir(path, S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO);
713 			if (access(path, F_OK) != 0)
714 				DPRINTF(E_FATAL, L_GENERAL, "Database path not accessible! [%s]\n", path);
715 			strncpyt(db_path, path, sizeof(db_path));
716 			break;
717 		case UPNPLOGDIR:
718 			path = realpath(ary_options[i].value, buf);
719 			if (!path)
720 				path = ary_options[i].value;
721 			if (snprintf(log_path, sizeof(log_path), "%s", path) > sizeof(log_path))
722 				DPRINTF(E_FATAL, L_GENERAL, "Log path too long! [%s]\n", path);
723 			make_dir(log_path, S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO);
724 			break;
725 		case UPNPLOGLEVEL:
726 			log_level = ary_options[i].value;
727 			break;
728 		case UPNPINOTIFY:
729 			if (!strtobool(ary_options[i].value))
730 				CLEARFLAG(INOTIFY_MASK);
731 			break;
732 		case ENABLE_TIVO:
733 			if (strtobool(ary_options[i].value))
734 				SETFLAG(TIVO_MASK);
735 			break;
736 		case ENABLE_DLNA_STRICT:
737 			if (strtobool(ary_options[i].value))
738 				SETFLAG(DLNA_STRICT_MASK);
739 			break;
740 		case ROOT_CONTAINER:
741 			switch (ary_options[i].value[0]) {
742 			case '.':
743 				runtime_vars.root_container = NULL;
744 				break;
745 			case 'B':
746 			case 'b':
747 				runtime_vars.root_container = BROWSEDIR_ID;
748 				break;
749 			case 'M':
750 			case 'm':
751 				runtime_vars.root_container = MUSIC_ID;
752 				break;
753 			case 'V':
754 			case 'v':
755 				runtime_vars.root_container = VIDEO_ID;
756 				break;
757 			case 'P':
758 			case 'p':
759 				runtime_vars.root_container = IMAGE_ID;
760 				break;
761 			default:
762 				runtime_vars.root_container = ary_options[i].value;
763 				DPRINTF(E_WARN, L_GENERAL, "Using arbitrary root container [%s]\n",
764 					ary_options[i].value);
765 				break;
766 			}
767 			break;
768 		case UPNPMINISSDPDSOCKET:
769 			minissdpdsocketpath = ary_options[i].value;
770 			break;
771 		case UPNPUUID:
772 			strcpy(uuidvalue+5, ary_options[i].value);
773 			break;
774 		case USER_ACCOUNT:
775 			uid = strtoul(ary_options[i].value, &string, 0);
776 			if (*string)
777 			{
778 				/* Symbolic username given, not UID. */
779 				struct passwd *entry = getpwnam(ary_options[i].value);
780 				if (!entry)
781 					DPRINTF(E_FATAL, L_GENERAL, "Bad user '%s'.\n",
782 						ary_options[i].value);
783 				uid = entry->pw_uid;
784 				if (!gid)
785 					gid = entry->pw_gid;
786 			}
787 			break;
788 		case FORCE_SORT_CRITERIA:
789 			force_sort_criteria = ary_options[i].value;
790 			if (force_sort_criteria[0] == '!')
791 			{
792 				SETFLAG(FORCE_ALPHASORT_MASK);
793 				force_sort_criteria++;
794 			}
795 			break;
796 		case MAX_CONNECTIONS:
797 			runtime_vars.max_connections = atoi(ary_options[i].value);
798 			break;
799 		case MERGE_MEDIA_DIRS:
800 			if (strtobool(ary_options[i].value))
801 				SETFLAG(MERGE_MEDIA_DIRS_MASK);
802 			break;
803 		case WIDE_LINKS:
804 			if (strtobool(ary_options[i].value))
805 				SETFLAG(WIDE_LINKS_MASK);
806 			break;
807 		case TIVO_DISCOVERY:
808 			if (strcasecmp(ary_options[i].value, "beacon") == 0)
809 				CLEARFLAG(TIVO_BONJOUR_MASK);
810 			break;
811 		case ENABLE_SUBTITLES:
812 			if (!strtobool(ary_options[i].value))
813 				CLEARFLAG(SUBTITLES_MASK);
814 			break;
815 		default:
816 			DPRINTF(E_ERROR, L_GENERAL, "Unknown option in file %s\n",
817 				optionsfile);
818 		}
819 	}
820 	if (!log_path[0])
821 		strncpyt(log_path, DEFAULT_LOG_PATH, sizeof(log_path));
822 	if (!db_path[0])
823 		strncpyt(db_path, DEFAULT_DB_PATH, sizeof(db_path));
824 
825 	/* command line arguments processing */
826 	for (i=1; i<argc; i++)
827 	{
828 		if (argv[i][0] != '-')
829 		{
830 			DPRINTF(E_FATAL, L_GENERAL, "Unknown option: %s\n", argv[i]);
831 		}
832 		else if (strcmp(argv[i], "--help") == 0)
833 		{
834 			runtime_vars.port = -1;
835 			break;
836 		}
837 		else switch(argv[i][1])
838 		{
839 		case 't':
840 			if (i+1 < argc)
841 				runtime_vars.notify_interval = atoi(argv[++i]);
842 			else
843 				DPRINTF(E_FATAL, L_GENERAL, "Option -%c takes one argument.\n", argv[i][1]);
844 			break;
845 		case 's':
846 			if (i+1 < argc)
847 				strncpyt(serialnumber, argv[++i], SERIALNUMBER_MAX_LEN);
848 			else
849 				DPRINTF(E_FATAL, L_GENERAL, "Option -%c takes one argument.\n", argv[i][1]);
850 			break;
851 		case 'm':
852 			if (i+1 < argc)
853 				strncpyt(modelnumber, argv[++i], MODELNUMBER_MAX_LEN);
854 			else
855 				DPRINTF(E_FATAL, L_GENERAL, "Option -%c takes one argument.\n", argv[i][1]);
856 			break;
857 		case 'p':
858 			if (i+1 < argc)
859 				runtime_vars.port = atoi(argv[++i]);
860 			else
861 				DPRINTF(E_FATAL, L_GENERAL, "Option -%c takes one argument.\n", argv[i][1]);
862 			break;
863 		case 'P':
864 			if (i+1 < argc)
865 			{
866 				if (argv[++i][0] != '/')
867 					DPRINTF(E_FATAL, L_GENERAL, "Option -%c requires an absolute filename.\n", argv[i-1][1]);
868 				else
869 					pidfilename = argv[i];
870 			}
871 			else
872 				DPRINTF(E_FATAL, L_GENERAL, "Option -%c takes one argument.\n", argv[i][1]);
873 			break;
874 		case 'd':
875 			debug_flag = 1;
876 		case 'v':
877 			verbose_flag = 1;
878 			break;
879 		case 'L':
880 			SETFLAG(NO_PLAYLIST_MASK);
881 			break;
882 		case 'w':
883 			if (i+1 < argc)
884 				presurl = argv[++i];
885 			else
886 				DPRINTF(E_FATAL, L_GENERAL, "Option -%c takes one argument.\n", argv[i][1]);
887 			break;
888 		case 'i':
889 			if (i+1 < argc)
890 			{
891 				i++;
892 				if (ifaces >= MAX_LAN_ADDR)
893 				{
894 					DPRINTF(E_ERROR, L_GENERAL, "Too many interfaces (max: %d), ignoring %s\n",
895 						MAX_LAN_ADDR, argv[i]);
896 					break;
897 				}
898 				runtime_vars.ifaces[ifaces++] = argv[i];
899 			}
900 			else
901 				DPRINTF(E_FATAL, L_GENERAL, "Option -%c takes one argument.\n", argv[i][1]);
902 			break;
903 		case 'f':
904 			i++;	/* discarding, the config file is already read */
905 			break;
906 		case 'h':
907 			runtime_vars.port = -1; // triggers help display
908 			break;
909 		case 'r':
910 			SETFLAG(RESCAN_MASK);
911 			break;
912 		case 'R':
913 			snprintf(buf, sizeof(buf), "rm -rf %s/files.db %s/art_cache", db_path, db_path);
914 			if (system(buf) != 0)
915 				DPRINTF(E_FATAL, L_GENERAL, "Failed to clean old file cache %s. EXITING\n", db_path);
916 			break;
917 		case 'u':
918 			if (i+1 != argc)
919 			{
920 				i++;
921 				uid = strtoul(argv[i], &string, 0);
922 				if (*string)
923 				{
924 					/* Symbolic username given, not UID. */
925 					struct passwd *entry = getpwnam(argv[i]);
926 					if (!entry)
927 						DPRINTF(E_FATAL, L_GENERAL, "Bad user '%s'.\n", argv[i]);
928 					uid = entry->pw_uid;
929 					if (!gid)
930 						gid = entry->pw_gid;
931 				}
932 			}
933 			else
934 				DPRINTF(E_FATAL, L_GENERAL, "Option -%c takes one argument.\n", argv[i][1]);
935 			break;
936 		case 'g':
937 			if (i+1 != argc)
938 			{
939 				i++;
940 				gid = strtoul(argv[i], &string, 0);
941 				if (*string)
942 				{
943 					/* Symbolic group given, not GID. */
944 					struct group *grp = getgrnam(argv[i]);
945 					if (!grp)
946 						DPRINTF(E_FATAL, L_GENERAL, "Bad group '%s'.\n", argv[i]);
947 					gid = grp->gr_gid;
948 				}
949 			}
950 			else
951 				DPRINTF(E_FATAL, L_GENERAL, "Option -%c takes one argument.\n", argv[i][1]);
952 			break;
953 #if defined(__linux__) || defined(__APPLE__)
954 		case 'S':
955 			SETFLAG(SYSTEMD_MASK);
956 			break;
957 #endif
958 		case 'V':
959 			printf("Version " MINIDLNA_VERSION "\n");
960 			exit(0);
961 			break;
962 		default:
963 			DPRINTF(E_ERROR, L_GENERAL, "Unknown option: %s\n", argv[i]);
964 			runtime_vars.port = -1; // triggers help display
965 		}
966 	}
967 
968 	if (runtime_vars.port <= 0)
969 	{
970 		printf("Usage:\n\t"
971 			"%s [-d] [-v] [-f config_file] [-p port]\n"
972 			"\t\t[-i network_interface] [-u uid_to_run_as] [-g group_to_run_as]\n"
973 			"\t\t[-t notify_interval] [-P pid_filename]\n"
974 			"\t\t[-s serial] [-m model_number]\n"
975 #ifdef __linux__
976 			"\t\t[-w url] [-r] [-R] [-L] [-S] [-V] [-h]\n"
977 #else
978 			"\t\t[-w url] [-r] [-R] [-L] [-V] [-h]\n"
979 #endif
980 			"\nNotes:\n\tNotify interval is in seconds. Default is 895 seconds.\n"
981 			"\tDefault pid file is %s.\n"
982 			"\tWith -d minidlna will run in debug mode (not daemonize).\n"
983 			"\t-w sets the presentation url. Default is http address on port 80\n"
984 			"\t-v enables verbose output\n"
985 			"\t-h displays this text\n"
986 			"\t-r forces a rescan\n"
987 			"\t-R forces a rebuild\n"
988 			"\t-L do not create playlists\n"
989 #if defined(__linux__) || defined(__APPLE__)
990 			"\t-S changes behaviour for systemd/launchd\n"
991 #endif
992 			"\t-V print the version number\n",
993 			argv[0], pidfilename);
994 		return 1;
995 	}
996 
997 	if (verbose_flag)
998 	{
999 		strcpy(log_str+65, "debug");
1000 		log_level = log_str;
1001 	}
1002 	else if (!log_level)
1003 		log_level = log_str;
1004 
1005 	/* Set the default log to stdout */
1006 	if (debug_flag)
1007 	{
1008 		pid = getpid();
1009 		strcpy(log_str+65, "maxdebug");
1010 		log_level = log_str;
1011 		log_path[0] = '\0';
1012 	}
1013 	else if (GETFLAG(SYSTEMD_MASK))
1014 	{
1015 		pid = getpid();
1016 		log_path[0] = '\0';
1017 	}
1018 	else
1019 	{
1020 		pid = process_daemonize();
1021 		if (access(db_path, F_OK) != 0)
1022 			make_dir(db_path, S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO);
1023 	}
1024 	if (log_init(log_level) < 0)
1025 		DPRINTF(E_FATAL, L_GENERAL, "Failed to open log file '%s/" LOGFILE_NAME "': %s\n",
1026 			log_path, strerror(errno));
1027 
1028 	if (process_check_if_running(pidfilename) < 0)
1029 		DPRINTF(E_FATAL, L_GENERAL, SERVER_NAME " is already running. EXITING.\n");
1030 
1031 	set_startup_time();
1032 
1033 	/* presentation url */
1034 	if (presurl)
1035 		strncpyt(presentationurl, presurl, PRESENTATIONURL_MAX_LEN);
1036 	else
1037 		strcpy(presentationurl, "/");
1038 
1039 	/* set signal handlers */
1040 	memset(&sa, 0, sizeof(struct sigaction));
1041 	sa.sa_handler = sigterm;
1042 	if (sigaction(SIGTERM, &sa, NULL))
1043 		DPRINTF(E_FATAL, L_GENERAL, "Failed to set %s handler. EXITING.\n", "SIGTERM");
1044 	if (sigaction(SIGINT, &sa, NULL))
1045 		DPRINTF(E_FATAL, L_GENERAL, "Failed to set %s handler. EXITING.\n", "SIGINT");
1046 	if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
1047 		DPRINTF(E_FATAL, L_GENERAL, "Failed to set %s handler. EXITING.\n", "SIGPIPE");
1048 	if (signal(SIGHUP, &sighup) == SIG_ERR)
1049 		DPRINTF(E_FATAL, L_GENERAL, "Failed to set %s handler. EXITING.\n", "SIGHUP");
1050 	if (signal(SIGUSR2, SIG_IGN) == SIG_ERR)
1051 		DPRINTF(E_FATAL, L_GENERAL, "Failed to set %s handler. EXITING.\n", "SIGUSR2");
1052 	signal(SIGUSR1, &sigusr1);
1053 	sa.sa_handler = process_handle_child_termination;
1054 	if (sigaction(SIGCHLD, &sa, NULL))
1055 		DPRINTF(E_FATAL, L_GENERAL, "Failed to set %s handler. EXITING.\n", "SIGCHLD");
1056 
1057 	if (writepidfile(pidfilename, pid, uid) != 0)
1058 		pidfilename = NULL;
1059 
1060 	if (uid > 0)
1061 	{
1062 		struct stat st;
1063 		if (stat(db_path, &st) == 0 && st.st_uid != uid && chown(db_path, uid, -1) != 0)
1064 			DPRINTF(E_ERROR, L_GENERAL, "Unable to set db_path [%s] ownership to %d: %s\n",
1065 				db_path, uid, strerror(errno));
1066 	}
1067 
1068 	if (gid > 0 && setgid(gid) == -1)
1069 		DPRINTF(E_FATAL, L_GENERAL, "Failed to switch to gid '%d'. [%s] EXITING.\n",
1070 			gid, strerror(errno));
1071 
1072 	if (uid > 0 && setuid(uid) == -1)
1073 		DPRINTF(E_FATAL, L_GENERAL, "Failed to switch to uid '%d'. [%s] EXITING.\n",
1074 			uid, strerror(errno));
1075 
1076 	children = calloc(runtime_vars.max_connections, sizeof(struct child));
1077 	if (!children)
1078 	{
1079 		DPRINTF(E_ERROR, L_GENERAL, "Allocation failed\n");
1080 		return 1;
1081 	}
1082 
1083 	if ((error = event_module.init()) != 0)
1084 		DPRINTF(E_FATAL, L_GENERAL, "Failed to init event module. "
1085 		    "[%s] EXITING.\n", strerror(error));
1086 
1087 	return 0;
1088 }
1089 
1090 #ifdef HAVE_WATCH
1091 void
start_monitor()1092 start_monitor()
1093 {
1094 
1095 	if (!GETFLAG(INOTIFY_MASK))
1096 		return;
1097 
1098 	lav_register_all();
1099 	monitor_start();
1100 }
1101 #endif
1102 
1103 /* === main === */
1104 /* process HTTP or SSDP requests */
1105 int
main(int argc,char ** argv)1106 main(int argc, char **argv)
1107 {
1108 	int ret, i;
1109 	int shttpl = -1;
1110 	int smonitor = -1;
1111 	struct upnphttp * e = 0;
1112 	struct upnphttp * next;
1113 	struct timeval tv, timeofday, lastnotifytime = {0, 0};
1114 	time_t lastupdatetime = 0, lastdbtime = 0;
1115 	int last_changecnt = 0;
1116 	pid_t scanner_pid = 0;
1117 	struct event ssdpev, httpev, monev;
1118 #ifdef TIVO_SUPPORT
1119 	uint8_t beacon_interval = 5;
1120 	int sbeacon = -1;
1121 	struct sockaddr_in tivo_bcast;
1122 	struct timeval lastbeacontime = {0, 0};
1123 	struct event beaconev;
1124 #endif
1125 
1126 	for (i = 0; i < L_MAX; i++)
1127 		log_level[i] = E_WARN;
1128 
1129 	ret = init(argc, argv);
1130 	if (ret != 0)
1131 		return 1;
1132 	init_nls();
1133 
1134 	DPRINTF(E_WARN, L_GENERAL, "Starting " SERVER_NAME " version " MINIDLNA_VERSION ".\n");
1135 	if (sqlite3_libversion_number() < 3005001)
1136 	{
1137 		DPRINTF(E_WARN, L_GENERAL, "SQLite library is old.  Please use version 3.5.1 or newer.\n");
1138 	}
1139 
1140 	LIST_INIT(&upnphttphead);
1141 
1142 	ret = open_db(NULL);
1143 	if (ret == 0)
1144 	{
1145 		updateID = sql_get_int_field(db, "SELECT VALUE from SETTINGS where KEY = 'UPDATE_ID'");
1146 		if (updateID == -1)
1147 			ret = -1;
1148 	}
1149 	check_db(db, ret, &scanner_pid);
1150 	lastdbtime = _get_dbtime();
1151 
1152 #ifdef HAVE_WATCH
1153 	if (!GETFLAG(SCANNING_MASK))
1154 		start_monitor();
1155 #endif
1156 
1157 	smonitor = OpenAndConfMonitorSocket();
1158 	if (smonitor > 0)
1159 	{
1160 		monev = (struct event ){ .fd = smonitor, .rdwr = EVENT_READ, .process = ProcessMonitorEvent };
1161 		event_module.add(&monev);
1162 	}
1163 
1164 	sssdp = OpenAndConfSSDPReceiveSocket();
1165 	if (sssdp < 0)
1166 	{
1167 		DPRINTF(E_INFO, L_GENERAL, "Failed to open socket for receiving SSDP. Trying to use MiniSSDPd\n");
1168 		reload_ifaces(0);	/* populate lan_addr[0].str */
1169 		if (SubmitServicesToMiniSSDPD(lan_addr[0].str, runtime_vars.port) < 0)
1170 			DPRINTF(E_FATAL, L_GENERAL, "Failed to connect to MiniSSDPd. EXITING");
1171 	}
1172 	else
1173 	{
1174 		ssdpev = (struct event ){ .fd = sssdp, .rdwr = EVENT_READ, .process = ProcessSSDPRequest };
1175 		event_module.add(&ssdpev);
1176 	}
1177 
1178 	/* open socket for HTTP connections. */
1179 	shttpl = OpenAndConfHTTPSocket(runtime_vars.port);
1180 	if (shttpl < 0)
1181 		DPRINTF(E_FATAL, L_GENERAL, "Failed to open socket for HTTP. EXITING\n");
1182 	DPRINTF(E_WARN, L_GENERAL, "HTTP listening on port %d\n", runtime_vars.port);
1183 	httpev = (struct event ){ .fd = shttpl, .rdwr = EVENT_READ, .process = ProcessListen };
1184 	event_module.add(&httpev);
1185 
1186 	if (gettimeofday(&timeofday, 0) < 0)
1187 		DPRINTF(E_FATAL, L_GENERAL, "gettimeofday(): %s\n", strerror(errno));
1188 
1189 #ifdef TIVO_SUPPORT
1190 	if (GETFLAG(TIVO_MASK))
1191 	{
1192 		DPRINTF(E_WARN, L_GENERAL, "TiVo support is enabled.\n");
1193 		/* Add TiVo-specific randomize function to sqlite */
1194 		ret = sqlite3_create_function(db, "tivorandom", 1, SQLITE_UTF8, NULL, &TiVoRandomSeedFunc, NULL, NULL);
1195 		if (ret != SQLITE_OK)
1196 			DPRINTF(E_ERROR, L_TIVO, "ERROR: Failed to add sqlite randomize function for TiVo!\n");
1197 		if (GETFLAG(TIVO_BONJOUR_MASK))
1198 		{
1199 			tivo_bonjour_register();
1200 		}
1201 		else
1202 		{
1203 			/* open socket for sending Tivo notifications */
1204 			sbeacon = OpenAndConfTivoBeaconSocket();
1205 			if(sbeacon < 0)
1206 				DPRINTF(E_FATAL, L_GENERAL, "Failed to open sockets for sending Tivo beacon notify "
1207 					"messages. EXITING\n");
1208 			beaconev = (struct event ){ .fd = sbeacon, .rdwr = EVENT_READ, .process = ProcessTiVoBeacon };
1209 			event_module.add(&beaconev);
1210 			tivo_bcast.sin_family = AF_INET;
1211 			tivo_bcast.sin_addr.s_addr = htonl(getBcastAddress());
1212 			tivo_bcast.sin_port = htons(2190);
1213 			lastbeacontime = timeofday;
1214 		}
1215 	}
1216 #endif
1217 
1218 	reload_ifaces(0);	/* sends SSDP notifies */
1219 	lastnotifytime = timeofday;
1220 
1221 	/* main loop */
1222 	while (!quitting)
1223 	{
1224 		/* Check if we need to send SSDP NOTIFY messages and do it if
1225 		 * needed */
1226 		tv = lastnotifytime;
1227 		tv.tv_sec += runtime_vars.notify_interval;
1228 		if (timevalcmp(&timeofday, &tv, >=))
1229 		{
1230 			DPRINTF(E_DEBUG, L_SSDP, "Sending SSDP notifies\n");
1231 			for (i = 0; i < n_lan_addr; i++)
1232 			{
1233 				SendSSDPNotifies(lan_addr[i].snotify, lan_addr[i].str,
1234 					runtime_vars.port, runtime_vars.notify_interval);
1235 			}
1236 			lastnotifytime = timeofday;
1237 			tv.tv_sec = runtime_vars.notify_interval;
1238 			tv.tv_usec = 0;
1239 		}
1240 		else
1241 		{
1242 			timevalsub(&tv, &timeofday);
1243 		}
1244 #ifdef TIVO_SUPPORT
1245 		if (sbeacon >= 0)
1246 		{
1247 			struct timeval beacontv;
1248 
1249 			beacontv = lastbeacontime;
1250 			beacontv.tv_sec += beacon_interval;
1251 			if (timevalcmp(&timeofday, &beacontv, >=))
1252 			{
1253 				sendBeaconMessage(sbeacon, &tivo_bcast, sizeof(struct sockaddr_in), 1);
1254 				lastbeacontime = timeofday;
1255 				/* Beacons should be sent every 5 seconds or
1256 				 * so for the first minute, then every minute
1257 				 * or so thereafter. */
1258 				if (beacon_interval == 5 && (timeofday.tv_sec - startup_time) > 60)
1259 					beacon_interval = 60;
1260 				beacontv.tv_sec = beacon_interval;
1261 				beacontv.tv_usec = 0;
1262 			}
1263 			else
1264 			{
1265 				timevalsub(&beacontv, &timeofday);
1266 			}
1267 			if (timevalcmp(&tv, &beacontv, >))
1268 				tv = beacontv;
1269 		}
1270 #endif
1271 
1272 		if (GETFLAG(SCANNING_MASK)) {
1273 			if (kill(scanner_pid, 0) != 0) {
1274 				DPRINTF(E_INFO, L_GENERAL, "Scanner exited\n");
1275 				CLEARFLAG(SCANNING_MASK);
1276 				if (_get_dbtime() != lastdbtime)
1277 					updateID++;
1278 #ifdef HAVE_WATCH
1279 				start_monitor();
1280 #endif
1281 			} else
1282 				/* Keep checking for the scanner every sec. */
1283 				tv.tv_sec = 1;
1284 		}
1285 
1286 		event_module.process(&tv);
1287 		if (quitting)
1288 			goto shutdown;
1289 
1290 		if (gettimeofday(&timeofday, 0) < 0)
1291 			DPRINTF(E_FATAL, L_GENERAL, "gettimeofday(): %s\n", strerror(errno));
1292 
1293 		upnpevents_gc();
1294 
1295 		/* increment SystemUpdateID if the content database has changed,
1296 		 * and if there is an active HTTP connection, at most once every 2 seconds */
1297 		if (!LIST_EMPTY(&upnphttphead) &&
1298 		    (timeofday.tv_sec >= (lastupdatetime + 2)))
1299 		{
1300 			if (GETFLAG(SCANNING_MASK))
1301 			{
1302 				time_t dbtime = _get_dbtime();
1303 				if (dbtime != lastdbtime)
1304 				{
1305 					lastdbtime = dbtime;
1306 					last_changecnt = -1;
1307 				}
1308 			}
1309 			if (sqlite3_total_changes(db) != last_changecnt)
1310 			{
1311 				updateID++;
1312 				last_changecnt = sqlite3_total_changes(db);
1313 				upnp_event_var_change_notify(EContentDirectory);
1314 				lastupdatetime = timeofday.tv_sec;
1315 			}
1316 		}
1317 		/* delete finished HTTP connections */
1318 		for (e = upnphttphead.lh_first; e != NULL; e = next)
1319 		{
1320 			next = e->entries.le_next;
1321 			if(e->state >= 100)
1322 			{
1323 				LIST_REMOVE(e, entries);
1324 				Delete_upnphttp(e);
1325 			}
1326 		}
1327 	}
1328 
1329 shutdown:
1330 	/* kill the scanner */
1331 	if (GETFLAG(SCANNING_MASK) && scanner_pid)
1332 		kill(scanner_pid, SIGKILL);
1333 
1334 	/* close out open sockets */
1335 	while (upnphttphead.lh_first != NULL)
1336 	{
1337 		e = upnphttphead.lh_first;
1338 		LIST_REMOVE(e, entries);
1339 		Delete_upnphttp(e);
1340 	}
1341 	if (sssdp >= 0)
1342 		close(sssdp);
1343 	if (shttpl >= 0)
1344 		close(shttpl);
1345 #ifdef TIVO_SUPPORT
1346 	if (sbeacon >= 0)
1347 		close(sbeacon);
1348 #endif
1349 	if (smonitor >= 0)
1350 		close(smonitor);
1351 
1352 	for (i = 0; i < n_lan_addr; i++)
1353 	{
1354 		SendSSDPGoodbyes(lan_addr[i].snotify);
1355 		close(lan_addr[i].snotify);
1356 	}
1357 
1358 #ifdef HAVE_WATCH
1359 	monitor_stop();
1360 #endif
1361 
1362 	/* kill other child processes */
1363 	process_reap_children();
1364 	free(children);
1365 
1366 	event_module.fini();
1367 
1368 	sql_exec(db, "UPDATE SETTINGS set VALUE = '%u' where KEY = 'UPDATE_ID'", updateID);
1369 	sqlite3_close(db);
1370 
1371 	upnpevents_removeSubscribers();
1372 
1373 	if (pidfilename && unlink(pidfilename) < 0)
1374 		DPRINTF(E_ERROR, L_GENERAL, "Failed to remove pidfile %s: %s\n", pidfilename, strerror(errno));
1375 
1376 	log_close();
1377 	freeoptions();
1378 
1379 	exit(EXIT_SUCCESS);
1380 }
1381 
1382