1/* MiniDLNA project
2 *
3 * http://sourceforge.net/projects/minidlna/
4 * (c) 2008-2009 Justin Maggard
5 * This software is subject to the conditions detailed
6 * in the LICENCE file provided within the distribution
7 *
8 * Portions of the code (c) Thomas Bernard, subject to
9 * the conditions detailed in the LICENSE.miniupnpd file.
10 */
11#include <stdlib.h>
12#include <unistd.h>
13#include <string.h>
14#include <stdio.h>
15#include <ctype.h>
16#include <sys/types.h>
17#include <sys/socket.h>
18#include <netinet/in.h>
19#include <arpa/inet.h>
20#include <fcntl.h>
21#include <sys/file.h>
22#include <sys/time.h>
23#include <time.h>
24#include <signal.h>
25#include <sys/param.h>
26#include <errno.h>
27#include <pthread.h>
28#include <pwd.h>
29
30/* unix sockets */
31#include "config.h"
32
33#include "upnpglobalvars.h"
34#include "sql.h"
35#include "upnphttp.h"
36#include "upnpdescgen.h"
37#include "minidlnapath.h"
38#include "getifaddr.h"
39#include "upnpsoap.h"
40#include "options.h"
41#include "utils.h"
42#include "minissdp.h"
43#include "minidlnatypes.h"
44#include "daemonize.h"
45#include "upnpevents.h"
46#include "scanner.h"
47#include "inotify.h"
48#include "log.h"
49#ifdef TIVO_SUPPORT
50#include "tivo_beacon.h"
51#include "tivo_utils.h"
52#endif
53
54#if SQLITE_VERSION_NUMBER < 3005001
55# warning "Your SQLite3 library appears to be too old!  Please use 3.5.1 or newer."
56# define sqlite3_threadsafe() 0
57#endif
58
59/* OpenAndConfHTTPSocket() :
60 * setup the socket used to handle incoming HTTP connections. */
61static int
62OpenAndConfHTTPSocket(unsigned short port)
63{
64	int s;
65	int i = 1;
66	struct sockaddr_in listenname;
67
68	/* Initialize client type cache */
69	memset(&clients, 0, sizeof(struct client_cache_s));
70
71	if( (s = socket(PF_INET, SOCK_STREAM, 0)) < 0)
72	{
73		DPRINTF(E_ERROR, L_GENERAL, "socket(http): %s\n", strerror(errno));
74		return -1;
75	}
76
77	if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)) < 0)
78	{
79		DPRINTF(E_WARN, L_GENERAL, "setsockopt(http, SO_REUSEADDR): %s\n", strerror(errno));
80	}
81
82	memset(&listenname, 0, sizeof(struct sockaddr_in));
83	listenname.sin_family = AF_INET;
84	listenname.sin_port = htons(port);
85	listenname.sin_addr.s_addr = htonl(INADDR_ANY);
86
87	if(bind(s, (struct sockaddr *)&listenname, sizeof(struct sockaddr_in)) < 0)
88	{
89		DPRINTF(E_ERROR, L_GENERAL, "bind(http): %s\n", strerror(errno));
90		close(s);
91		return -1;
92	}
93
94	if(listen(s, 6) < 0)
95	{
96		DPRINTF(E_ERROR, L_GENERAL, "listen(http): %s\n", strerror(errno));
97		close(s);
98		return -1;
99	}
100
101	return s;
102}
103
104/* Handler for the SIGTERM signal (kill)
105 * SIGINT is also handled */
106static void
107sigterm(int sig)
108{
109	/*int save_errno = errno;*/
110	signal(sig, SIG_IGN);	/* Ignore this signal while we are quitting */
111
112	DPRINTF(E_WARN, L_GENERAL, "received signal %d, good-bye\n", sig);
113
114	quitting = 1;
115	/*errno = save_errno;*/
116}
117
118/* record the startup time, for returning uptime */
119static void
120set_startup_time(void)
121{
122	startup_time = time(NULL);
123}
124
125/* parselanaddr()
126 * parse address with mask
127 * ex: 192.168.1.1/24
128 * return value :
129 *    0 : ok
130 *   -1 : error */
131static int
132parselanaddr(struct lan_addr_s * lan_addr, const char * str)
133{
134	const char * p;
135	int nbits = 24;
136	int n;
137	p = str;
138	while(*p && *p != '/' && !isspace(*p))
139		p++;
140	n = p - str;
141	if(*p == '/')
142	{
143		nbits = atoi(++p);
144		while(*p && !isspace(*p))
145			p++;
146	}
147	if(n>15)
148	{
149		DPRINTF(E_OFF, L_GENERAL, "Error parsing address/mask: %s\n", str);
150		return -1;
151	}
152	memcpy(lan_addr->str, str, n);
153	lan_addr->str[n] = '\0';
154	if(!inet_aton(lan_addr->str, &lan_addr->addr))
155	{
156		DPRINTF(E_OFF, L_GENERAL, "Error parsing address/mask: %s\n", str);
157		return -1;
158	}
159	lan_addr->mask.s_addr = htonl(nbits ? (0xffffffff << (32 - nbits)) : 0);
160	return 0;
161}
162
163void
164getfriendlyname(char * buf, int len)
165{
166	char * dot = NULL;
167	char * hn = calloc(1, 256);
168	if( gethostname(hn, 256) == 0 )
169	{
170		strncpy(buf, hn, len-1);
171		buf[len] = '\0';
172		dot = index(buf, '.');
173		if( dot )
174			*dot = '\0';
175	}
176	else
177	{
178		strcpy(buf, "Unknown");
179	}
180	free(hn);
181	strcat(buf, ": ");
182	#ifdef READYNAS
183	strncat(buf, "ReadyNAS", len-strlen(buf)-1);
184	#else
185	char * logname;
186	logname = getenv("LOGNAME");
187#if 1 // Disable for static linking
188	if( !logname )
189	{
190		struct passwd * pwent;
191		pwent = getpwuid(getuid());
192		if( pwent )
193			logname = pwent->pw_name;
194	}
195#endif
196	strncat(buf, logname?logname:"Unknown", len-strlen(buf)-1);
197	#endif
198}
199
200int
201open_db(void)
202{
203	char path[PATH_MAX];
204	int new_db = 0;
205
206	snprintf(path, sizeof(path), "%s/files.db", db_path);
207	if( access(path, F_OK) != 0 )
208	{
209		new_db = 1;
210		make_dir(db_path, S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO);
211	}
212	if( sqlite3_open(path, &db) != SQLITE_OK )
213	{
214		DPRINTF(E_FATAL, L_GENERAL, "ERROR: Failed to open sqlite database!  Exiting...\n");
215	}
216	sqlite3_busy_timeout(db, 5000);
217	sql_exec(db, "pragma page_size = 4096");
218	sql_exec(db, "pragma journal_mode = OFF");
219	sql_exec(db, "pragma synchronous = OFF;");
220	sql_exec(db, "pragma default_cache_size = 8192;");
221	return new_db;
222}
223
224/* init phase :
225 * 1) read configuration file
226 * 2) read command line arguments
227 * 3) daemonize
228 * 4) check and write pid file
229 * 5) set startup time stamp
230 * 6) compute presentation URL
231 * 7) set signal handlers */
232static int
233init(int argc, char * * argv)
234{
235	int i;
236	int pid;
237	int debug_flag = 0;
238	int options_flag = 0;
239	struct sigaction sa;
240	/*const char * logfilename = 0;*/
241	const char * presurl = 0;
242	const char * optionsfile = "/etc/minidlna.conf";
243	char mac_str[13];
244	char * string, * word;
245	enum media_types type;
246	char * path;
247	char real_path[PATH_MAX];
248	char ext_ip_addr[INET_ADDRSTRLEN] = {'\0'};
249
250	/* first check if "-f" option is used */
251	for(i=2; i<argc; i++)
252	{
253		if(0 == strcmp(argv[i-1], "-f"))
254		{
255			optionsfile = argv[i];
256			options_flag = 1;
257			break;
258		}
259	}
260
261	/* set up uuid based on mac address */
262	if( getsyshwaddr(mac_str, sizeof(mac_str)) < 0 )
263	{
264		DPRINTF(E_OFF, L_GENERAL, "No MAC address found.  Falling back to generic UUID.\n");
265		strcpy(mac_str, "554e4b4e4f57");
266	}
267	strcpy(uuidvalue+5, "4d696e69-444c-164e-9d41-");
268	strncat(uuidvalue, mac_str, 12);
269
270	getfriendlyname(friendly_name, FRIENDLYNAME_MAX_LEN);
271
272	runtime_vars.port = -1;
273	runtime_vars.notify_interval = 895;	/* seconds between SSDP announces */
274
275	/* read options file first since
276	 * command line arguments have final say */
277	if(readoptionsfile(optionsfile) < 0)
278	{
279		/* only error if file exists or using -f */
280		if(access(optionsfile, F_OK) == 0 || options_flag)
281			fprintf(stderr, "Error reading configuration file %s\n", optionsfile);
282	}
283	else
284	{
285		for(i=0; i<num_options; i++)
286		{
287			switch(ary_options[i].id)
288			{
289			case UPNPIFNAME:
290				if(getifaddr(ary_options[i].value, ext_ip_addr, INET_ADDRSTRLEN) >= 0)
291				{
292					if( *ext_ip_addr && parselanaddr(&lan_addr[n_lan_addr], ext_ip_addr) == 0 )
293						n_lan_addr++;
294				}
295				else
296					fprintf(stderr, "Interface %s not found, ignoring.\n", ary_options[i].value);
297				break;
298			case UPNPLISTENING_IP:
299				if(n_lan_addr < MAX_LAN_ADDR)
300				{
301					if(parselanaddr(&lan_addr[n_lan_addr],
302					             ary_options[i].value) == 0)
303						n_lan_addr++;
304				}
305				else
306				{
307					fprintf(stderr, "Too many listening ips (max: %d), ignoring %s\n",
308			    		    MAX_LAN_ADDR, ary_options[i].value);
309				}
310				break;
311			case UPNPPORT:
312				runtime_vars.port = atoi(ary_options[i].value);
313				break;
314			case UPNPPRESENTATIONURL:
315				presurl = ary_options[i].value;
316				break;
317			case UPNPNOTIFY_INTERVAL:
318				runtime_vars.notify_interval = atoi(ary_options[i].value);
319				break;
320			case UPNPSERIAL:
321				strncpy(serialnumber, ary_options[i].value, SERIALNUMBER_MAX_LEN);
322				serialnumber[SERIALNUMBER_MAX_LEN-1] = '\0';
323				break;
324			case UPNPMODEL_NUMBER:
325				strncpy(modelnumber, ary_options[i].value, MODELNUMBER_MAX_LEN);
326				modelnumber[MODELNUMBER_MAX_LEN-1] = '\0';
327				break;
328			case UPNPFRIENDLYNAME:
329				strncpy(friendly_name, ary_options[i].value, FRIENDLYNAME_MAX_LEN);
330				friendly_name[FRIENDLYNAME_MAX_LEN-1] = '\0';
331				break;
332			case UPNPMEDIADIR:
333				type = ALL_MEDIA;
334				char * myval = NULL;
335				switch( ary_options[i].value[0] )
336				{
337				case 'A':
338				case 'a':
339					if( ary_options[i].value[0] == 'A' || ary_options[i].value[0] == 'a' )
340						type = AUDIO_ONLY;
341				case 'V':
342				case 'v':
343					if( ary_options[i].value[0] == 'V' || ary_options[i].value[0] == 'v' )
344						type = VIDEO_ONLY;
345				case 'P':
346				case 'p':
347					if( ary_options[i].value[0] == 'P' || ary_options[i].value[0] == 'p' )
348						type = IMAGES_ONLY;
349					myval = index(ary_options[i].value, '/');
350				case '/':
351					path = realpath(myval ? myval:ary_options[i].value, real_path);
352					if( !path )
353						path = (myval ? myval:ary_options[i].value);
354					if( access(path, F_OK) != 0 )
355					{
356						fprintf(stderr, "Media directory not accessible! [%s]\n",
357						        path);
358						break;
359					}
360					struct media_dir_s * this_dir = calloc(1, sizeof(struct media_dir_s));
361					this_dir->path = strdup(path);
362					this_dir->type = type;
363					if( !media_dirs )
364					{
365						media_dirs = this_dir;
366					}
367					else
368					{
369						struct media_dir_s * all_dirs = media_dirs;
370						while( all_dirs->next )
371							all_dirs = all_dirs->next;
372						all_dirs->next = this_dir;
373					}
374					break;
375				default:
376					fprintf(stderr, "Media directory entry not understood! [%s]\n",
377					        ary_options[i].value);
378					break;
379				}
380				break;
381			case UPNPALBUMART_NAMES:
382				for( string = ary_options[i].value; (word = strtok(string, "/")); string = NULL ) {
383					struct album_art_name_s * this_name = calloc(1, sizeof(struct album_art_name_s));
384					this_name->name = strdup(word);
385					if( !album_art_names )
386					{
387						album_art_names = this_name;
388					}
389					else
390					{
391						struct album_art_name_s * all_names = album_art_names;
392						while( all_names->next )
393							all_names = all_names->next;
394						all_names->next = this_name;
395					}
396				}
397				break;
398			case UPNPDBDIR:
399				path = realpath(ary_options[i].value, real_path);
400				if( !path )
401					path = (ary_options[i].value);
402				make_dir(path, S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO);
403				if( access(path, F_OK) != 0 )
404				{
405					DPRINTF(E_FATAL, L_GENERAL, "Database path not accessible! [%s]\n", path);
406					break;
407				}
408				strncpy(db_path, path, PATH_MAX);
409				break;
410			case UPNPINOTIFY:
411				if( (strcmp(ary_options[i].value, "yes") != 0) && !atoi(ary_options[i].value) )
412					CLEARFLAG(INOTIFY_MASK);
413				break;
414			case ENABLE_TIVO:
415				if( (strcmp(ary_options[i].value, "yes") == 0) || atoi(ary_options[i].value) )
416					SETFLAG(TIVO_MASK);
417				break;
418			case ENABLE_DLNA_STRICT:
419				if( (strcmp(ary_options[i].value, "yes") == 0) || atoi(ary_options[i].value) )
420					SETFLAG(DLNA_STRICT_MASK);
421				break;
422			default:
423				fprintf(stderr, "Unknown option in file %s\n",
424				        optionsfile);
425			}
426		}
427	}
428
429	/* command line arguments processing */
430	for(i=1; i<argc; i++)
431	{
432		if(argv[i][0]!='-')
433		{
434			fprintf(stderr, "Unknown option: %s\n", argv[i]);
435		}
436		else if(strcmp(argv[i], "--help")==0)
437		{
438			runtime_vars.port = 0;
439			break;
440		}
441		else switch(argv[i][1])
442		{
443		case 't':
444			if(i+1 < argc)
445				runtime_vars.notify_interval = atoi(argv[++i]);
446			else
447				fprintf(stderr, "Option -%c takes one argument.\n", argv[i][1]);
448			break;
449		case 's':
450			if(i+1 < argc)
451				strncpy(serialnumber, argv[++i], SERIALNUMBER_MAX_LEN);
452			else
453				fprintf(stderr, "Option -%c takes one argument.\n", argv[i][1]);
454			serialnumber[SERIALNUMBER_MAX_LEN-1] = '\0';
455			break;
456		case 'm':
457			if(i+1 < argc)
458				strncpy(modelnumber, argv[++i], MODELNUMBER_MAX_LEN);
459			else
460				fprintf(stderr, "Option -%c takes one argument.\n", argv[i][1]);
461			modelnumber[MODELNUMBER_MAX_LEN-1] = '\0';
462			break;
463		/*case 'l':
464			logfilename = argv[++i];
465			break;*/
466		case 'p':
467			if(i+1 < argc)
468				runtime_vars.port = atoi(argv[++i]);
469			else
470				fprintf(stderr, "Option -%c takes one argument.\n", argv[i][1]);
471			break;
472		case 'P':
473			if(i+1 < argc)
474				pidfilename = argv[++i];
475			else
476				fprintf(stderr, "Option -%c takes one argument.\n", argv[i][1]);
477			break;
478		case 'd':
479			debug_flag = 1;
480			break;
481		case 'w':
482			if(i+1 < argc)
483				presurl = argv[++i];
484			else
485				fprintf(stderr, "Option -%c takes one argument.\n", argv[i][1]);
486			break;
487		case 'a':
488			if(i+1 < argc)
489			{
490				int address_already_there = 0;
491				int j;
492				i++;
493				for(j=0; j<n_lan_addr; j++)
494				{
495					struct lan_addr_s tmpaddr;
496					parselanaddr(&tmpaddr, argv[i]);
497					if(0 == strcmp(lan_addr[j].str, tmpaddr.str))
498						address_already_there = 1;
499				}
500				if(address_already_there)
501					break;
502				if(n_lan_addr < MAX_LAN_ADDR)
503				{
504					if(parselanaddr(&lan_addr[n_lan_addr], argv[i]) == 0)
505						n_lan_addr++;
506				}
507				else
508				{
509					fprintf(stderr, "Too many listening ips (max: %d), ignoring %s\n",
510				    	    MAX_LAN_ADDR, argv[i]);
511				}
512			}
513			else
514				fprintf(stderr, "Option -%c takes one argument.\n", argv[i][1]);
515			break;
516		case 'i':
517			if(i+1 < argc)
518			{
519				int address_already_there = 0;
520				int j;
521				i++;
522				if( getifaddr(argv[i], ext_ip_addr, INET_ADDRSTRLEN) < 0 )
523				{
524					fprintf(stderr, "Network interface '%s' not found.\n",
525						argv[i]);
526					exit(-1);
527				}
528				for(j=0; j<n_lan_addr; j++)
529				{
530					struct lan_addr_s tmpaddr;
531					parselanaddr(&tmpaddr, ext_ip_addr);
532					if(0 == strcmp(lan_addr[j].str, tmpaddr.str))
533						address_already_there = 1;
534				}
535				if(address_already_there)
536					break;
537				if(n_lan_addr < MAX_LAN_ADDR)
538				{
539					if(parselanaddr(&lan_addr[n_lan_addr], ext_ip_addr) == 0)
540						n_lan_addr++;
541				}
542				else
543				{
544					fprintf(stderr, "Too many listening ips (max: %d), ignoring %s\n",
545				    	    MAX_LAN_ADDR, argv[i]);
546				}
547			}
548			else
549				fprintf(stderr, "Option -%c takes one argument.\n", argv[i][1]);
550			break;
551		case 'f':
552			i++;	/* discarding, the config file is already read */
553			break;
554		case 'h':
555			runtime_vars.port = 0; // triggers help display
556			break;
557		case 'R':
558			snprintf(real_path, sizeof(real_path), "rm -rf %s", db_path);
559			system(real_path);
560			break;
561		case 'V':
562			printf("Version " MINIDLNA_VERSION "\n");
563			exit(0);
564			break;
565		default:
566			fprintf(stderr, "Unknown option: %s\n", argv[i]);
567		}
568	}
569	/* If no IP was specified, try to detect one */
570	if( n_lan_addr < 1 )
571	{
572		if( (getsysaddr(ext_ip_addr, INET_ADDRSTRLEN) < 0) &&
573		    (getifaddr("eth0", ext_ip_addr, INET_ADDRSTRLEN) < 0) &&
574		    (getifaddr("eth1", ext_ip_addr, INET_ADDRSTRLEN) < 0) )
575		{
576			DPRINTF(E_OFF, L_GENERAL, "No IP address automatically detected!\n");
577		}
578		if( *ext_ip_addr && parselanaddr(&lan_addr[n_lan_addr], ext_ip_addr) == 0 )
579		{
580			n_lan_addr++;
581		}
582	}
583
584	if( (n_lan_addr==0) || (runtime_vars.port<=0) )
585	{
586		fprintf(stderr, "Usage:\n\t"
587		        "%s [-d] [-f config_file]\n"
588			"\t\t[-a listening_ip] [-p port]\n"
589			/*"[-l logfile] " not functionnal */
590			"\t\t[-s serial] [-m model_number] \n"
591			"\t\t[-t notify_interval] [-P pid_filename]\n"
592			"\t\t[-w url] [-R] [-V] [-h]\n"
593		        "\nNotes:\n\tNotify interval is in seconds. Default is 895 seconds.\n"
594			"\tDefault pid file is %s.\n"
595			"\tWith -d minidlna will run in debug mode (not daemonize).\n"
596			"\t-w sets the presentation url. Default is http address on port 80\n"
597			"\t-h displays this text\n"
598			"\t-R forces a full rescan\n"
599			"\t-V print the version number\n",
600		        argv[0], pidfilename);
601		return 1;
602	}
603
604	if(debug_flag)
605	{
606		pid = getpid();
607		log_init(NULL, "general,artwork,database,inotify,scanner,metadata,http,ssdp,tivo=debug");
608	}
609	else
610	{
611#ifdef USE_DAEMON
612		if(daemon(0, 0)<0) {
613			perror("daemon()");
614		}
615		pid = getpid();
616#else
617		pid = daemonize();
618#endif
619		#ifdef READYNAS
620		log_init("/var/log/upnp-av.log", "general,artwork,database,inotify,scanner,metadata,http,ssdp,tivo=warn");
621		#else
622		if( access(db_path, F_OK) != 0 )
623			make_dir(db_path, S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO);
624		sprintf(real_path, "%s/minidlna.log", db_path);
625		log_init(real_path, "general,artwork,database,inotify,scanner,metadata,http,ssdp,tivo=warn");
626		#endif
627	}
628
629	if(checkforrunning(pidfilename) < 0)
630	{
631		DPRINTF(E_ERROR, L_GENERAL, "MiniDLNA is already running. EXITING.\n");
632		return 1;
633	}
634
635	set_startup_time();
636
637	/* presentation url */
638	if(presurl)
639	{
640		strncpy(presentationurl, presurl, PRESENTATIONURL_MAX_LEN);
641		presentationurl[PRESENTATIONURL_MAX_LEN-1] = '\0';
642		strncpy(device_url, presurl, PRESENTATIONURL_MAX_LEN);
643		device_url[PRESENTATIONURL_MAX_LEN-1] = '\0';
644	}
645	else
646	{
647#ifdef READYNAS
648		snprintf(presentationurl, PRESENTATIONURL_MAX_LEN,
649		         "http://%s/admin/", lan_addr[0].str);
650#else
651		snprintf(presentationurl, PRESENTATIONURL_MAX_LEN,
652		         "http://%s:%d", lan_addr[0].str, runtime_vars.port);
653		snprintf(device_url, PRESENTATIONURL_MAX_LEN,
654			 "http://%s", lan_addr[0].str);
655#endif
656	}
657
658	/* set signal handler */
659	signal(SIGCLD, SIG_IGN);
660	memset(&sa, 0, sizeof(struct sigaction));
661	sa.sa_handler = sigterm;
662	if (sigaction(SIGTERM, &sa, NULL))
663	{
664		DPRINTF(E_FATAL, L_GENERAL, "Failed to set SIGTERM handler. EXITING.\n");
665	}
666	if (sigaction(SIGINT, &sa, NULL))
667	{
668		DPRINTF(E_FATAL, L_GENERAL, "Failed to set SIGINT handler. EXITING.\n");
669	}
670
671	if(signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
672		DPRINTF(E_FATAL, L_GENERAL, "Failed to ignore SIGPIPE signals. EXITING.\n");
673	}
674
675	writepidfile(pidfilename, pid);
676
677	return 0;
678}
679
680/* === main === */
681/* process HTTP or SSDP requests */
682int
683main(int argc, char * * argv)
684{
685	int i;
686	int sudp = -1, shttpl = -1;
687	int snotify[MAX_LAN_ADDR];
688	LIST_HEAD(httplisthead, upnphttp) upnphttphead;
689	struct upnphttp * e = 0;
690	struct upnphttp * next;
691	fd_set readset;	/* for select() */
692	fd_set writeset;
693	struct timeval timeout, timeofday, lastnotifytime = {0, 0}, lastupdatetime = {0, 0};
694	int max_fd = -1;
695	int last_changecnt = 0;
696	short int new_db = 0;
697	pid_t scanner_pid = 0;
698	pthread_t inotify_thread = 0;
699#ifdef TIVO_SUPPORT
700	unsigned short int beacon_interval = 5;
701	int sbeacon = -1;
702	struct sockaddr_in tivo_bcast;
703	struct timeval lastbeacontime = {0, 0};
704#endif
705
706	if(init(argc, argv) != 0)
707		return 1;
708
709#ifdef READYNAS
710	DPRINTF(E_WARN, L_GENERAL, "Starting ReadyDLNA version " MINIDLNA_VERSION ".\n");
711	unlink("/ramfs/.upnp-av_scan");
712#else
713	DPRINTF(E_WARN, L_GENERAL, "Starting MiniDLNA version " MINIDLNA_VERSION " [SQLite %s].\n", sqlite3_libversion());
714	if( !sqlite3_threadsafe() )
715	{
716		DPRINTF(E_ERROR, L_GENERAL, "SQLite library is not threadsafe!  "
717		                            "Scanning must be finished before file serving can begin, "
718		                            "and inotify will be disabled.\n");
719	}
720	if( sqlite3_libversion_number() < 3005001 )
721	{
722		DPRINTF(E_WARN, L_GENERAL, "SQLite library is old.  Please use version 3.5.1 or newer.\n");
723	}
724#endif
725	LIST_INIT(&upnphttphead);
726
727	new_db = open_db();
728	if( !new_db )
729	{
730		updateID = sql_get_int_field(db, "SELECT UPDATE_ID from SETTINGS");
731	}
732	if( sql_get_int_field(db, "pragma user_version") != DB_VERSION )
733	{
734		if( new_db )
735		{
736			DPRINTF(E_WARN, L_GENERAL, "Creating new database...\n");
737		}
738		else
739		{
740			DPRINTF(E_WARN, L_GENERAL, "Database version mismatch; need to recreate...\n");
741		}
742		sqlite3_close(db);
743		char *cmd;
744		asprintf(&cmd, "rm -rf %s/files.db %s/art_cache", db_path, db_path);
745		system(cmd);
746		free(cmd);
747		open_db();
748		if( CreateDatabase() != 0 )
749		{
750			DPRINTF(E_FATAL, L_GENERAL, "ERROR: Failed to create sqlite database!  Exiting...\n");
751		}
752#if USE_FORK
753		scanning = 1;
754		sqlite3_close(db);
755		scanner_pid = fork();
756		open_db();
757		if( !scanner_pid ) // child (scanner) process
758		{
759			start_scanner();
760			sqlite3_close(db);
761			exit(EXIT_SUCCESS);
762		}
763#else
764		start_scanner();
765#endif
766	}
767	if( sqlite3_threadsafe() && sqlite3_libversion_number() >= 3005001 &&
768	    GETFLAG(INOTIFY_MASK) && pthread_create(&inotify_thread, NULL, start_inotify, NULL) )
769	{
770		DPRINTF(E_FATAL, L_GENERAL, "ERROR: pthread_create() failed for start_inotify.\n");
771	}
772
773	sudp = OpenAndConfSSDPReceiveSocket(n_lan_addr, lan_addr);
774	if(sudp < 0)
775	{
776		DPRINTF(E_FATAL, L_GENERAL, "Failed to open socket for receiving SSDP. EXITING\n");
777	}
778	/* open socket for HTTP connections. Listen on the 1st LAN address */
779	shttpl = OpenAndConfHTTPSocket(runtime_vars.port);
780	if(shttpl < 0)
781	{
782		DPRINTF(E_FATAL, L_GENERAL, "Failed to open socket for HTTP. EXITING\n");
783	}
784	DPRINTF(E_WARN, L_GENERAL, "HTTP listening on port %d\n", runtime_vars.port);
785
786	/* open socket for sending notifications */
787	if(OpenAndConfSSDPNotifySockets(snotify) < 0)
788	{
789		DPRINTF(E_FATAL, L_GENERAL, "Failed to open sockets for sending SSDP notify "
790	                "messages. EXITING\n");
791	}
792
793#ifdef TIVO_SUPPORT
794	if( GETFLAG(TIVO_MASK) )
795	{
796		DPRINTF(E_WARN, L_GENERAL, "TiVo support is enabled.\n");
797		/* Add TiVo-specific randomize function to sqlite */
798		if( sqlite3_create_function(db, "tivorandom", 1, SQLITE_UTF8, NULL, &TiVoRandomSeedFunc, NULL, NULL) != SQLITE_OK )
799		{
800			DPRINTF(E_ERROR, L_TIVO, "ERROR: Failed to add sqlite randomize function for TiVo!\n");
801		}
802		/* open socket for sending Tivo notifications */
803		sbeacon = OpenAndConfTivoBeaconSocket();
804		if(sbeacon < 0)
805		{
806			DPRINTF(E_FATAL, L_GENERAL, "Failed to open sockets for sending Tivo beacon notify "
807		                "messages. EXITING\n");
808		}
809		tivo_bcast.sin_family = AF_INET;
810		tivo_bcast.sin_addr.s_addr = htonl(getBcastAddress());
811		tivo_bcast.sin_port = htons(2190);
812	}
813	else
814	{
815		sbeacon = -1;
816	}
817#endif
818
819	SendSSDPGoodbye(snotify, n_lan_addr);
820
821	/* main loop */
822	while(!quitting)
823	{
824		/* Check if we need to send SSDP NOTIFY messages and do it if
825		 * needed */
826		if(gettimeofday(&timeofday, 0) < 0)
827		{
828			DPRINTF(E_ERROR, L_GENERAL, "gettimeofday(): %s\n", strerror(errno));
829			timeout.tv_sec = runtime_vars.notify_interval;
830			timeout.tv_usec = 0;
831		}
832		else
833		{
834			/* the comparaison is not very precise but who cares ? */
835			if(timeofday.tv_sec >= (lastnotifytime.tv_sec + runtime_vars.notify_interval))
836			{
837				SendSSDPNotifies2(snotify,
838			                  (unsigned short)runtime_vars.port,
839			                  (runtime_vars.notify_interval << 1)+10);
840				memcpy(&lastnotifytime, &timeofday, sizeof(struct timeval));
841				timeout.tv_sec = runtime_vars.notify_interval;
842				timeout.tv_usec = 0;
843			}
844			else
845			{
846				timeout.tv_sec = lastnotifytime.tv_sec + runtime_vars.notify_interval
847				                 - timeofday.tv_sec;
848				if(timeofday.tv_usec > lastnotifytime.tv_usec)
849				{
850					timeout.tv_usec = 1000000 + lastnotifytime.tv_usec
851					                  - timeofday.tv_usec;
852					timeout.tv_sec--;
853				}
854				else
855				{
856					timeout.tv_usec = lastnotifytime.tv_usec - timeofday.tv_usec;
857				}
858			}
859#ifdef TIVO_SUPPORT
860			if( GETFLAG(TIVO_MASK) )
861			{
862				if(timeofday.tv_sec >= (lastbeacontime.tv_sec + beacon_interval))
863				{
864   					sendBeaconMessage(sbeacon, &tivo_bcast, sizeof(struct sockaddr_in), 1);
865					memcpy(&lastbeacontime, &timeofday, sizeof(struct timeval));
866					if( timeout.tv_sec > beacon_interval )
867					{
868						timeout.tv_sec = beacon_interval;
869						timeout.tv_usec = 0;
870					}
871					/* Beacons should be sent every 5 seconds or so for the first minute,
872					 * then every minute or so thereafter. */
873					if( beacon_interval == 5 && (timeofday.tv_sec - startup_time) > 60 )
874					{
875						beacon_interval = 60;
876					}
877				}
878				else if( timeout.tv_sec > (lastbeacontime.tv_sec + beacon_interval + 1 - timeofday.tv_sec) )
879				{
880					timeout.tv_sec = lastbeacontime.tv_sec + beacon_interval - timeofday.tv_sec;
881				}
882			}
883#endif
884		}
885
886		if( scanning )
887		{
888			if( !scanner_pid || kill(scanner_pid, 0) )
889				scanning = 0;
890		}
891
892		/* select open sockets (SSDP, HTTP listen, and all HTTP soap sockets) */
893		FD_ZERO(&readset);
894
895		if (sudp >= 0)
896		{
897			FD_SET(sudp, &readset);
898			max_fd = MAX( max_fd, sudp);
899		}
900
901		if (shttpl >= 0)
902		{
903			FD_SET(shttpl, &readset);
904			max_fd = MAX( max_fd, shttpl);
905		}
906
907		i = 0;	/* active HTTP connections count */
908		for(e = upnphttphead.lh_first; e != NULL; e = e->entries.le_next)
909		{
910			if((e->socket >= 0) && (e->state <= 2))
911			{
912				FD_SET(e->socket, &readset);
913				max_fd = MAX( max_fd, e->socket);
914				i++;
915			}
916		}
917		/* for debug */
918#ifdef DEBUG
919		if(i > 1)
920		{
921			DPRINTF(E_DEBUG, L_GENERAL, "%d active incoming HTTP connections\n", i);
922		}
923#endif
924
925		FD_ZERO(&writeset);
926		upnpevents_selectfds(&readset, &writeset, &max_fd);
927
928		if(select(max_fd+1, &readset, &writeset, 0, &timeout) < 0)
929		{
930			if(quitting) goto shutdown;
931			DPRINTF(E_ERROR, L_GENERAL, "select(all): %s\n", strerror(errno));
932			DPRINTF(E_FATAL, L_GENERAL, "Failed to select open sockets. EXITING\n");
933		}
934		upnpevents_processfds(&readset, &writeset);
935		/* process SSDP packets */
936		if(sudp >= 0 && FD_ISSET(sudp, &readset))
937		{
938			/*DPRINTF(E_DEBUG, L_GENERAL, "Received UDP Packet\n");*/
939			ProcessSSDPRequest(sudp, (unsigned short)runtime_vars.port);
940		}
941		/* increment SystemUpdateID if the content database has changed,
942		 * and if there is an active HTTP connection, at most once every 2 seconds */
943		if( i && (time(NULL) >= (lastupdatetime.tv_sec + 2)) )
944		{
945			if( sqlite3_total_changes(db) != last_changecnt )
946			{
947				updateID++;
948				last_changecnt = sqlite3_total_changes(db);
949				upnp_event_var_change_notify(EContentDirectory);
950				memcpy(&lastupdatetime, &timeofday, sizeof(struct timeval));
951			}
952		}
953		/* process active HTTP connections */
954		for(e = upnphttphead.lh_first; e != NULL; e = e->entries.le_next)
955		{
956			if(  (e->socket >= 0) && (e->state <= 2)
957				&&(FD_ISSET(e->socket, &readset)) )
958			{
959				Process_upnphttp(e);
960			}
961		}
962		/* process incoming HTTP connections */
963		if(shttpl >= 0 && FD_ISSET(shttpl, &readset))
964		{
965			int shttp;
966			socklen_t clientnamelen;
967			struct sockaddr_in clientname;
968			clientnamelen = sizeof(struct sockaddr_in);
969			shttp = accept(shttpl, (struct sockaddr *)&clientname, &clientnamelen);
970			if(shttp<0)
971			{
972				DPRINTF(E_ERROR, L_GENERAL, "accept(http): %s\n", strerror(errno));
973			}
974			else
975			{
976				struct upnphttp * tmp = 0;
977				DPRINTF(E_DEBUG, L_GENERAL, "HTTP connection from %s:%d\n",
978					inet_ntoa(clientname.sin_addr),
979					ntohs(clientname.sin_port) );
980				/*if (fcntl(shttp, F_SETFL, O_NONBLOCK) < 0) {
981					DPRINTF(E_ERROR, L_GENERAL, "fcntl F_SETFL, O_NONBLOCK");
982				}*/
983				/* Create a new upnphttp object and add it to
984				 * the active upnphttp object list */
985				tmp = New_upnphttp(shttp);
986				if(tmp)
987				{
988					tmp->clientaddr = clientname.sin_addr;
989					LIST_INSERT_HEAD(&upnphttphead, tmp, entries);
990				}
991				else
992				{
993					DPRINTF(E_ERROR, L_GENERAL, "New_upnphttp() failed\n");
994					close(shttp);
995				}
996			}
997		}
998		/* delete finished HTTP connections */
999		for(e = upnphttphead.lh_first; e != NULL; )
1000		{
1001			next = e->entries.le_next;
1002			if(e->state >= 100)
1003			{
1004				LIST_REMOVE(e, entries);
1005				Delete_upnphttp(e);
1006			}
1007			e = next;
1008		}
1009	}
1010
1011shutdown:
1012	/* kill the scanner */
1013	if( scanning && scanner_pid )
1014	{
1015		kill(scanner_pid, 9);
1016	}
1017	/* close out open sockets */
1018	while(upnphttphead.lh_first != NULL)
1019	{
1020		e = upnphttphead.lh_first;
1021		LIST_REMOVE(e, entries);
1022		Delete_upnphttp(e);
1023	}
1024
1025	if (sudp >= 0) close(sudp);
1026	if (shttpl >= 0) close(shttpl);
1027	#ifdef TIVO_SUPPORT
1028	if (sbeacon >= 0) close(sbeacon);
1029	#endif
1030
1031	if(SendSSDPGoodbye(snotify, n_lan_addr) < 0)
1032	{
1033		DPRINTF(E_ERROR, L_GENERAL, "Failed to broadcast good-bye notifications\n");
1034	}
1035	for(i=0; i<n_lan_addr; i++)
1036		close(snotify[i]);
1037
1038	if( inotify_thread )
1039		pthread_join(inotify_thread, NULL);
1040
1041	sql_exec(db, "UPDATE SETTINGS set UPDATE_ID = %u", updateID);
1042	sqlite3_close(db);
1043
1044	struct media_dir_s * media_path = media_dirs;
1045	struct media_dir_s * last_path;
1046	while( media_path )
1047	{
1048		free(media_path->path);
1049		last_path = media_path;
1050		media_path = media_path->next;
1051		free(last_path);
1052	}
1053	struct album_art_name_s * art_names = album_art_names;
1054	struct album_art_name_s * last_name;
1055	while( art_names )
1056	{
1057		free(art_names->name);
1058		last_name = art_names;
1059		art_names = art_names->next;
1060		free(last_name);
1061	}
1062
1063	if(unlink(pidfilename) < 0)
1064	{
1065		DPRINTF(E_ERROR, L_GENERAL, "Failed to remove pidfile %s: %s\n", pidfilename, strerror(errno));
1066	}
1067
1068	freeoptions();
1069
1070	exit(EXIT_SUCCESS);
1071}
1072
1073