1 /*
2  * MOC - music on console
3  * Copyright (C) 2003 - 2005 Damian Pietras <daper@daper.net>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  */
11 
12 #ifdef HAVE_CONFIG_H
13 # include "config.h"
14 #endif
15 
16 #include <stdio.h>
17 #include <sys/socket.h>
18 #ifdef HAVE_SYS_SELECT_H
19 # include <sys/select.h>
20 #endif
21 #include <sys/time.h>
22 #ifdef HAVE_GETRLIMIT
23 # include <sys/resource.h>
24 #endif
25 #include <sys/un.h>
26 #include <time.h>
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include <string.h>
30 #include <strings.h>
31 #include <signal.h>
32 #include <errno.h>
33 #include <stdarg.h>
34 #include <pthread.h>
35 #include <assert.h>
36 
37 #define DEBUG
38 
39 #include "common.h"
40 #include "log.h"
41 #include "protocol.h"
42 #include "audio.h"
43 #include "oss.h"
44 #include "options.h"
45 #include "server.h"
46 #include "playlist.h"
47 #include "tags_cache.h"
48 #include "files.h"
49 #include "softmixer.h"
50 #include "equalizer.h"
51 
52 #define SERVER_LOG	"mocp_server_log"
53 #define PID_FILE	"pid"
54 
55 struct client
56 {
57 	int socket; 		/* -1 if inactive */
58 	int wants_plist_events;	/* requested playlist events? */
59 	struct event_queue events;
60 	pthread_mutex_t events_mutex;
61 	int requests_plist;	/* is the client waiting for the playlist? */
62 	int can_send_plist;	/* can this client send a playlist? */
63 	int lock;		/* is this client locking us? */
64 	int serial;		/* used for generating unique serial numbers */
65 };
66 
67 static struct client clients[CLIENTS_MAX];
68 
69 /* Thread ID of the server thread. */
70 static pthread_t server_tid;
71 
72 /* Pipe used to wake up the server from select() from another thread. */
73 static int wake_up_pipe[2];
74 
75 /* Set to 1 when a signal arrived causing the program to exit. */
76 static volatile int server_quit = 0;
77 
78 /* Information about currently played file */
79 static struct {
80 	int avg_bitrate;
81 	int bitrate;
82 	int rate;
83 	int channels;
84 } sound_info = {
85 	-1,
86 	-1,
87 	-1,
88 	-1
89 };
90 
91 static struct tags_cache tags_cache;
92 
93 extern char **environ;
94 
write_pid_file()95 static void write_pid_file ()
96 {
97 	char *fname = create_file_name (PID_FILE);
98 	FILE *file;
99 
100 	if ((file = fopen(fname, "w")) == NULL)
101 		fatal ("Can't open pid file for writing: %s", strerror(errno));
102 	fprintf (file, "%d\n", getpid());
103 	fclose (file);
104 }
105 
106 /* Check if there is a pid file and if it is valid, return the pid, else 0 */
check_pid_file()107 static int check_pid_file ()
108 {
109 	FILE *file;
110 	pid_t pid;
111 	char *fname = create_file_name (PID_FILE);
112 
113 	/* Read the pid file */
114 	if ((file = fopen(fname, "r")) == NULL)
115 		return 0;
116 	if (fscanf(file, "%d", &pid) != 1) {
117 		fclose (file);
118 		return 0;
119 	}
120 	fclose (file);
121 
122 	return pid;
123 }
124 
sig_exit(int sig)125 static void sig_exit (int sig)
126 {
127 	log_signal (sig);
128 	server_quit = 1;
129 
130 	// FIXME (JCF): pthread_*() are not async-signal-safe and
131 	//              should not be used within signal handlers.
132 	if (!pthread_equal (server_tid, pthread_self()))
133 		pthread_kill (server_tid, sig);
134 }
135 
clients_init()136 static void clients_init ()
137 {
138 	int i;
139 
140 	for (i = 0; i < CLIENTS_MAX; i++) {
141 		clients[i].socket = -1;
142 		pthread_mutex_init (&clients[i].events_mutex, NULL);
143 	}
144 }
145 
clients_cleanup()146 static void clients_cleanup ()
147 {
148 	int i, rc;
149 
150 	for (i = 0; i < CLIENTS_MAX; i++) {
151 		clients[i].socket = -1;
152 		rc = pthread_mutex_destroy (&clients[i].events_mutex);
153 		if (rc != 0)
154 			logit ("Can't destroy events mutex: %s", strerror (rc));
155 	}
156 }
157 
158 /* Add a client to the list, return 1 if ok, 0 on error (max clients exceeded) */
add_client(int sock)159 static int add_client (int sock)
160 {
161 	int i;
162 
163 	for (i = 0; i < CLIENTS_MAX; i++)
164 		if (clients[i].socket == -1) {
165 			clients[i].wants_plist_events = 0;
166 			LOCK (clients[i].events_mutex);
167 			event_queue_free (&clients[i].events);
168 			event_queue_init (&clients[i].events);
169 			UNLOCK (clients[i].events_mutex);
170 			clients[i].socket = sock;
171 			clients[i].requests_plist = 0;
172 			clients[i].can_send_plist = 0;
173 			clients[i].lock = 0;
174 			tags_cache_clear_queue (&tags_cache, i);
175 			return 1;
176 		}
177 
178 	return 0;
179 }
180 
181 /* Return index of a client that has a lock acquired. Return -1 if there is no
182  * lock. */
locking_client()183 static int locking_client ()
184 {
185 	int i;
186 
187 	for (i = 0; i < CLIENTS_MAX; i++)
188 		if (clients[i].socket != -1 && clients[i].lock)
189 			return i;
190 	return -1;
191 }
192 
193 /* Acquire a lock for this client. Return 0 on error. */
client_lock(struct client * cli)194 static int client_lock (struct client *cli)
195 {
196 	if (cli->lock) {
197 		logit ("Client wants deadlock");
198 		return 0;
199 	}
200 
201 	assert (locking_client() == -1);
202 
203 	cli->lock = 1;
204 	logit ("Lock acquired for client with fd %d", cli->socket);
205 	return 1;
206 }
207 
208 /* Return != 0 if this client holds a lock. */
is_locking(const struct client * cli)209 static int is_locking (const struct client *cli)
210 {
211 	return cli->lock;
212 }
213 
214 /* Release the lock hold by the client. Return 0 on error. */
client_unlock(struct client * cli)215 static int client_unlock (struct client *cli)
216 {
217 	if (!cli->lock) {
218 		logit ("Client wants to unlock when there is no lock");
219 		return 0;
220 	}
221 
222 	cli->lock = 0;
223 	logit ("Lock released by client with fd %d", cli->socket);
224 	return 1;
225 }
226 
227 /* Return the client index from the clients table. */
client_index(const struct client * cli)228 static int client_index (const struct client *cli)
229 {
230 	int i;
231 
232 	for (i = 0; i < CLIENTS_MAX; i++)
233 		if (clients[i].socket == cli->socket)
234 			return i;
235 	return -1;
236 }
237 
del_client(struct client * cli)238 static void del_client (struct client *cli)
239 {
240 	cli->socket = -1;
241 	LOCK (cli->events_mutex);
242 	event_queue_free (&cli->events);
243 	tags_cache_clear_queue (&tags_cache, client_index(cli));
244 	UNLOCK (cli->events_mutex);
245 }
246 
247 /* Check if the process with given PID exists. Return != 0 if so. */
valid_pid(const int pid)248 static int valid_pid (const int pid)
249 {
250 	return kill(pid, 0) == 0 ? 1 : 0;
251 }
252 
wake_up_server()253 static void wake_up_server ()
254 {
255 	int w = 1;
256 
257 	debug ("Waking up the server");
258 
259 	if (write(wake_up_pipe[1], &w, sizeof(w)) < 0)
260 		logit ("Can't wake up the server: (write() failed) %s",
261 				strerror(errno));
262 }
263 
264 /* Thread-safe signal() version */
thread_signal(const int signum,void (* func)(int))265 static void thread_signal (const int signum, void (*func)(int))
266 {
267 	struct sigaction act;
268 
269 	act.sa_handler = func;
270 	act.sa_flags = 0;
271 	sigemptyset (&act.sa_mask);
272 
273 	if (sigaction(signum, &act, 0) == -1)
274 		fatal ("sigaction() failed: %s", strerror(errno));
275 }
276 
redirect_output(FILE * stream)277 static void redirect_output (FILE *stream)
278 {
279 	FILE *rc;
280 
281 	if (stream == stdin)
282 		rc = freopen ("/dev/null", "r", stream);
283 	else
284 		rc = freopen ("/dev/null", "w", stream);
285 
286 	if (!rc)
287 		fatal ("Can't open /dev/null: %s", strerror (errno));
288 }
289 
log_process_stack_size()290 static void log_process_stack_size ()
291 {
292 #ifdef HAVE_GETRLIMIT
293 	int rc;
294 	struct rlimit limits;
295 
296 	rc = getrlimit (RLIMIT_STACK, &limits);
297 	if (rc == 0)
298 		logit ("Process's stack size: %u", (unsigned int)limits.rlim_cur);
299 #endif
300 }
301 
log_pthread_stack_size()302 static void log_pthread_stack_size ()
303 {
304 #ifdef HAVE_PTHREAD_ATTR_GETSTACKSIZE
305 	int rc;
306 	size_t stack_size;
307 	pthread_attr_t attr;
308 
309 	rc = pthread_attr_init (&attr);
310 	if (rc)
311 		return;
312 
313 	rc = pthread_attr_getstacksize (&attr, &stack_size);
314 	if (rc == 0)
315 		logit ("PThread's stack size: %u", (unsigned int)stack_size);
316 
317 	pthread_attr_destroy (&attr);
318 #endif
319 }
320 
321 /* Initialize the server - return fd of the listening socket or -1 on error */
server_init(int debugging,int foreground)322 int server_init (int debugging, int foreground)
323 {
324 	struct sockaddr_un sock_name;
325 	int server_sock;
326 	int pid;
327 
328 	logit ("Starting MOC Server");
329 
330 	pid = check_pid_file ();
331 	if (pid && valid_pid(pid)) {
332 		fprintf (stderr, "\nIt seems that the server is already running"
333 				" with pid %d.\n", pid);
334 		fprintf (stderr, "If it is not true, remove the pid file (%s)"
335 				" and try again.\n",
336 				create_file_name(PID_FILE));
337 		fatal ("Exiting!");
338 	}
339 
340 	if (foreground)
341 		log_init_stream (stdout, "stdout");
342 	else {
343 		FILE *logfp;
344 
345 		logfp = NULL;
346 		if (debugging) {
347 			logfp = fopen (SERVER_LOG, "a");
348 			if (!logfp)
349 				fatal ("Can't open server log file: %s", strerror (errno));
350 		}
351 		log_init_stream (logfp, SERVER_LOG);
352 	}
353 
354 	if (pipe(wake_up_pipe) < 0)
355 		fatal ("pipe() failed: %s", strerror(errno));
356 
357 	unlink (socket_name());
358 
359 	/* Create a socket */
360 	if ((server_sock = socket (PF_LOCAL, SOCK_STREAM, 0)) == -1)
361 		fatal ("Can't create socket: %s", strerror(errno));
362 	sock_name.sun_family = AF_LOCAL;
363 	strcpy (sock_name.sun_path, socket_name());
364 
365 	/* Bind to socket */
366 	if (bind(server_sock, (struct sockaddr *)&sock_name, SUN_LEN(&sock_name)) == -1)
367 		fatal ("Can't bind() to the socket: %s", strerror(errno));
368 
369 	if (listen(server_sock, 1) == -1)
370 		fatal ("listen() failed: %s", strerror(errno));
371 
372 	/* Log stack sizes so stack overflows can be debugged. */
373 	log_process_stack_size ();
374 	log_pthread_stack_size ();
375 
376 	clients_init ();
377 	audio_initialize ();
378 	tags_cache_init (&tags_cache, options_get_int("TagsCacheSize"));
379 	tags_cache_load (&tags_cache, create_file_name("cache"));
380 
381 	server_tid = pthread_self ();
382 	thread_signal (SIGTERM, sig_exit);
383 	thread_signal (SIGINT, foreground ? sig_exit : SIG_IGN);
384 	thread_signal (SIGHUP, SIG_IGN);
385 	thread_signal (SIGQUIT, sig_exit);
386 	thread_signal (SIGPIPE, SIG_IGN);
387 
388 	write_pid_file ();
389 
390 	if (!foreground) {
391 		setsid ();
392 		redirect_output (stdin);
393 		redirect_output (stdout);
394 		redirect_output (stderr);
395 	}
396 
397 	return server_sock;
398 }
399 
400 /* Send EV_DATA and the integer value. Return 0 on error. */
send_data_int(const struct client * cli,const int data)401 static int send_data_int (const struct client *cli, const int data)
402 {
403 	assert (cli->socket != -1);
404 
405 	if (!send_int(cli->socket, EV_DATA) || !send_int(cli->socket, data))
406 		return 0;
407 
408 	return 1;
409 }
410 
411 /* Send EV_DATA and the string value. Return 0 on error. */
send_data_str(const struct client * cli,const char * str)412 static int send_data_str (const struct client *cli, const char *str) {
413 	if (!send_int(cli->socket, EV_DATA) || !send_str(cli->socket, str))
414 		return 0;
415 	return 1;
416 }
417 
418 /* Add event to the client's queue */
add_event(struct client * cli,const int event,void * data)419 static void add_event (struct client *cli, const int event, void *data)
420 {
421 	LOCK (cli->events_mutex);
422 	event_push (&cli->events, event, data);
423 	UNLOCK (cli->events_mutex);
424 }
425 
on_song_change()426 static void on_song_change ()
427 {
428 	static char *last_file = NULL;
429 	static lists_t_strs *on_song_change = NULL;
430 
431 	int ix;
432 	bool same_file, unpaused;
433 	char *curr_file;
434 	char **args, *cmd;
435 	struct file_tags *curr_tags;
436 	lists_t_strs *arg_list;
437 
438 	/* We only need to do OnSongChange tokenisation once. */
439 	if (on_song_change == NULL) {
440 		char *command;
441 
442 		on_song_change = lists_strs_new (4);
443 		command = options_get_str ("OnSongChange");
444 
445 		if (command)
446 			lists_strs_tokenise (on_song_change, command);
447 	}
448 
449 	if (lists_strs_empty (on_song_change))
450 		return;
451 
452 	curr_file = audio_get_sname ();
453 
454 	if (curr_file == NULL)
455 		return;
456 
457 	same_file = (last_file && !strcmp (last_file, curr_file));
458 	unpaused = (audio_get_prev_state () == STATE_PAUSE);
459 	if (same_file && (unpaused || !options_get_bool ("RepeatSongChange"))) {
460 		free (curr_file);
461 		return;
462 	}
463 
464 	curr_tags = tags_cache_get_immediate (&tags_cache, curr_file,
465 	                                      TAGS_COMMENTS | TAGS_TIME);
466 	arg_list = lists_strs_new (lists_strs_size (on_song_change));
467 	for (ix = 0; ix < lists_strs_size (on_song_change); ix += 1) {
468 		char *arg, *str;
469 
470 		arg = lists_strs_at (on_song_change, ix);
471 		if (arg[0] != '%')
472 			lists_strs_append (arg_list, arg);
473 		else if (!curr_tags)
474 			lists_strs_append (arg_list, "");
475 		else {
476 			switch (arg[1]) {
477 			case 'a':
478 				str = curr_tags->artist ? curr_tags->artist : "";
479 				lists_strs_append (arg_list, str);
480 				break;
481 			case 'r':
482 				str = curr_tags->album ? curr_tags->album : "";
483 				lists_strs_append (arg_list, str);
484 				break;
485 			case 't':
486 				str = curr_tags->title ? curr_tags->title : "";
487 				lists_strs_append (arg_list, str);
488 				break;
489 			case 'n':
490 				if (curr_tags->track >= 0) {
491 					str = (char *) xmalloc (sizeof (char) * 4);
492 					snprintf (str, 4, "%d", curr_tags->track);
493 					lists_strs_push (arg_list, str);
494 				}
495 				else
496 					lists_strs_append (arg_list, "");
497 				break;
498 			case 'f':
499 				lists_strs_append (arg_list, curr_file);
500 				break;
501 			case 'D':
502 				if (curr_tags->time >= 0) {
503 					str = (char *) xmalloc (sizeof (char) * 10);
504 					snprintf (str, 10, "%d", curr_tags->time);
505 					lists_strs_push (arg_list, str);
506 				}
507 				else
508 					lists_strs_append (arg_list, "");
509 				break;
510 			case 'd':
511 				if (curr_tags->time >= 0) {
512 					str = (char *) xmalloc (sizeof (char) * 12);
513 					sec_to_min (str, curr_tags->time);
514 					lists_strs_push (arg_list, str);
515 				}
516 				else
517 					lists_strs_append (arg_list, "");
518 				break;
519 			default:
520 				lists_strs_append (arg_list, arg);
521 			}
522 		}
523 	}
524 	tags_free (curr_tags);
525 
526 	cmd = lists_strs_fmt (arg_list, " %s");
527 	debug ("Running command: %s", cmd);
528 	free (cmd);
529 
530 	switch (fork ()) {
531 	case 0:
532 		args = lists_strs_save (arg_list);
533 		execve (args[0], args, environ);
534 		exit (EXIT_FAILURE);
535 	case -1:
536 		logit ("Failed to fork(): %s", strerror (errno));
537 	}
538 
539 	lists_strs_free (arg_list);
540 	free (last_file);
541 	last_file = curr_file;
542 }
543 
544 /* Handle running external command on Stop event. */
on_stop()545 static void on_stop ()
546 {
547 	char *command;
548 
549 	command = xstrdup (options_get_str("OnStop"));
550 
551 	if (command) {
552 		char *args[2];
553 
554 		args[0] = xstrdup (command);
555 		args[1] = NULL;
556 
557 		switch (fork()) {
558 			case 0:
559 				execve (command, args, environ);
560 				exit (EXIT_FAILURE);
561 			case -1:
562 				logit ("Error when running OnStop command '%s': %s",
563 						command, strerror(errno));
564 				break;
565 		}
566 
567 		free (command);
568 		free (args[0]);
569 	}
570 }
571 
572 /* Return true iff 'event' is a playlist event. */
is_plist_event(const int event)573 static inline bool is_plist_event (const int event)
574 {
575 	bool result = false;
576 
577 	switch (event) {
578 	case EV_PLIST_ADD:
579 	case EV_PLIST_DEL:
580 	case EV_PLIST_MOVE:
581 	case EV_PLIST_CLEAR:
582 		result = true;
583 	}
584 
585 	return result;
586 }
587 
add_event_all(const int event,const void * data)588 static void add_event_all (const int event, const void *data)
589 {
590 	int i;
591 	int added = 0;
592 
593 	if (event == EV_STATE) {
594 		switch (audio_get_state()) {
595 			case STATE_PLAY:
596 				on_song_change ();
597 				break;
598 			case STATE_STOP:
599 				on_stop ();
600 				break;
601 		}
602 	}
603 
604 	for (i = 0; i < CLIENTS_MAX; i++) {
605 		void *data_copy = NULL;
606 
607 		if (clients[i].socket == -1)
608 			continue;
609 
610 		if (!clients[i].wants_plist_events && is_plist_event (event))
611 			continue;
612 
613 		if (data) {
614 			if (event == EV_PLIST_ADD
615 					|| event == EV_QUEUE_ADD) {
616 				data_copy = plist_new_item ();
617 				plist_item_copy (data_copy, data);
618 			}
619 			else if (event == EV_PLIST_DEL
620 					|| event == EV_QUEUE_DEL
621 					|| event == EV_STATUS_MSG
622 					|| event == EV_SRV_ERROR) {
623 				data_copy = xstrdup (data);
624 			}
625 			else if (event == EV_PLIST_MOVE
626 					|| event == EV_QUEUE_MOVE)
627 				data_copy = move_ev_data_dup (
628 						(struct move_ev_data *)
629 						data);
630 			else
631 				logit ("Unhandled data!");
632 		}
633 
634 		add_event (&clients[i], event, data_copy);
635 		added++;
636 	}
637 
638 	if (added)
639 		wake_up_server ();
640 	else
641 		debug ("No events have been added because there are no clients");
642 }
643 
644 /* Send events from the queue. Return 0 on error. */
flush_events(struct client * cli)645 static int flush_events (struct client *cli)
646 {
647 	enum noblock_io_status st = NB_IO_OK;
648 
649 	LOCK (cli->events_mutex);
650 	while (!event_queue_empty(&cli->events)
651 			&& (st = event_send_noblock(cli->socket, &cli->events))
652 			== NB_IO_OK)
653 		;
654 	UNLOCK (cli->events_mutex);
655 
656 	return st != NB_IO_ERR ? 1 : 0;
657 }
658 
659 /* Send events to clients whose sockets are ready to write. */
send_events(fd_set * fds)660 static void send_events (fd_set *fds)
661 {
662 	int i;
663 
664 	for (i = 0; i < CLIENTS_MAX; i++)
665 		if (clients[i].socket != -1
666 				&& FD_ISSET(clients[i].socket, fds)) {
667 			debug ("Flushing events for client %d", i);
668 			if (!flush_events (&clients[i])) {
669 				close (clients[i].socket);
670 				del_client (&clients[i]);
671 			}
672 		}
673 }
674 
675 /* End playing and cleanup. */
server_shutdown()676 static void server_shutdown ()
677 {
678 	logit ("Server exiting...");
679 	audio_exit ();
680 	tags_cache_save (&tags_cache, create_file_name("tags_cache"));
681 	tags_cache_destroy (&tags_cache);
682 	unlink (socket_name());
683 	unlink (create_file_name(PID_FILE));
684 	close (wake_up_pipe[0]);
685 	close (wake_up_pipe[1]);
686 	logit ("Server exited");
687 	log_close ();
688 }
689 
690 /* Send EV_BUSY message and close the connection. */
busy(int sock)691 static void busy (int sock)
692 {
693 	logit ("Closing connection due to maximum number of clients reached");
694 	send_int (sock, EV_BUSY);
695 	close (sock);
696 }
697 
698 /* Handle CMD_LIST_ADD, return 1 if ok or 0 on error. */
req_list_add(struct client * cli)699 static int req_list_add (struct client *cli)
700 {
701 	char *file;
702 
703 	file = get_str (cli->socket);
704 	if (!file)
705 		return 0;
706 
707 	logit ("Adding '%s' to the list", file);
708 
709 	audio_plist_add (file);
710 	free (file);
711 
712 	return 1;
713 }
714 
715 /* Handle CMD_QUEUE_ADD, return 1 if ok or 0 on error. */
req_queue_add(const struct client * cli)716 static int req_queue_add (const struct client *cli)
717 {
718 	char *file;
719 	struct plist_item *item;
720 
721 	file = get_str (cli->socket);
722 	if (!file)
723 		return 0;
724 
725 	logit ("Adding '%s' to the queue", file);
726 
727 	audio_queue_add (file);
728 
729 	/* Wrap the filename in struct plist_item.
730 	 * We don't need tags, because the player gets them
731 	 * when playing the file. This may change if there is
732 	 * support for viewing/reordering the queue and here
733 	 * is the place to read the tags and fill them into
734 	 * the item. */
735 
736 	item = plist_new_item ();
737 	item->file = xstrdup (file);
738 	item->type = file_type (file);
739 	item->mtime = get_mtime (file);
740 
741 	add_event_all (EV_QUEUE_ADD, item);
742 
743 	plist_free_item_fields (item);
744 	free (item);
745 	free (file);
746 
747 	return 1;
748 }
749 
750 /* Handle CMD_PLAY, return 1 if ok or 0 on error. */
req_play(struct client * cli)751 static int req_play (struct client *cli)
752 {
753 	char *file;
754 
755 	if (!(file = get_str(cli->socket)))
756 		return 0;
757 
758 	logit ("Playing %s", *file ? file : "first element on the list");
759 	audio_play (file);
760 	free (file);
761 
762 	return 1;
763 }
764 
765 /* Handle CMD_SEEK, return 1 if ok or 0 on error */
req_seek(struct client * cli)766 static int req_seek (struct client *cli)
767 {
768 	int sec;
769 
770 	if (!get_int(cli->socket, &sec))
771 		return 0;
772 
773 	logit ("Seeking %ds", sec);
774 	audio_seek (sec);
775 
776 	return 1;
777 }
778 
779 /* Handle CMD_JUMP_TO, return 1 if ok or 0 on error */
req_jump_to(struct client * cli)780 static int req_jump_to (struct client *cli)
781 {
782 	int sec;
783 
784 	if (!get_int(cli->socket, &sec))
785 		return 0;
786 	logit ("Jumping to %ds", sec);
787 	audio_jump_to (sec);
788 
789 	return 1;
790 }
791 
792 /* Report an error logging it and sending a message to the client. */
server_error(const char * msg)793 void server_error (const char *msg)
794 {
795 	logit ("ERROR: %s", msg);
796 	add_event_all (EV_SRV_ERROR, msg);
797 }
798 
799 /* Send the song name to the client. Return 0 on error. */
send_sname(struct client * cli)800 static int send_sname (struct client *cli)
801 {
802 	int status = 1;
803 	char *sname = audio_get_sname ();
804 
805 	if (!send_data_str(cli, sname ? sname : ""))
806 		status = 0;
807 	free (sname);
808 
809 	return status;
810 }
811 
812 /* Return 0 if an option is valid when getting/setting with the client. */
valid_sync_option(const char * name)813 static int valid_sync_option (const char *name)
814 {
815 	return !strcasecmp(name, "ShowStreamErrors")
816 		|| !strcasecmp(name, "Repeat")
817 		|| !strcasecmp(name, "Shuffle")
818 		|| !strcasecmp(name, "AutoNext");
819 }
820 
821 /* Send requested option value to the client. Return 1 if OK. */
send_option(struct client * cli)822 static int send_option (struct client *cli)
823 {
824 	char *name;
825 
826 	if (!(name = get_str(cli->socket)))
827 		return 0;
828 
829 	/* We can send only a few options, others make no sense here. */
830 	if (!valid_sync_option(name)) {
831 		logit ("Client wanted to get invalid option '%s'", name);
832 		free (name);
833 		return 0;
834 	}
835 
836 	/* All supported options are integer type. */
837 	if (!send_data_int(cli, options_get_int(name))) {
838 		free (name);
839 		return 0;
840 	}
841 
842 	free (name);
843 	return 1;
844 }
845 
846 /* Get and set an option from the client. Return 1 on error. */
get_set_option(struct client * cli)847 static int get_set_option (struct client *cli)
848 {
849 	char *name;
850 	int val;
851 
852 	if (!(name = get_str (cli->socket)))
853 		return 0;
854 	if (!valid_sync_option (name)) {
855 		logit ("Client requested setting invalid option '%s'", name);
856 		return 0;
857 	}
858 	if (!get_int (cli->socket, &val)) {
859 		free (name);
860 		return 0;
861 	}
862 
863 	options_set_int (name, val);
864 	free (name);
865 
866 	add_event_all (EV_OPTIONS, NULL);
867 
868 	return 1;
869 }
870 
871 /* Set the mixer to the value provided by the client. Return 0 on error. */
set_mixer(struct client * cli)872 static int set_mixer (struct client *cli)
873 {
874 	int val;
875 
876 	if (!get_int(cli->socket, &val))
877 		return 0;
878 
879 	audio_set_mixer (val);
880 	return 1;
881 }
882 
883 /* Delete an item from the playlist. Return 0 on error. */
delete_item(struct client * cli)884 static int delete_item (struct client *cli)
885 {
886 	char *file;
887 
888 	if (!(file = get_str(cli->socket)))
889 		return 0;
890 
891 	debug ("Request for deleting %s", file);
892 
893 	audio_plist_delete (file);
894 	free (file);
895 	return 1;
896 }
897 
req_queue_del(const struct client * cli)898 static int req_queue_del (const struct client *cli)
899 {
900 	char *file;
901 
902 	if (!(file = get_str(cli->socket)))
903 		return 0;
904 
905 	debug ("Deleting '%s' from queue", file);
906 
907 	audio_queue_delete (file);
908 	add_event_all (EV_QUEUE_DEL, file);
909 	free (file);
910 
911 	return 1;
912 }
913 
914 /* Return the index of the first client able to send the playlist or -1 if
915  * there isn't any. */
find_sending_plist()916 static int find_sending_plist ()
917 {
918 	int i;
919 
920 	for (i = 0; i < CLIENTS_MAX; i++)
921 		if (clients[i].socket != -1 && clients[i].can_send_plist)
922 			return i;
923 	return -1;
924 }
925 
926 /* Handle CMD_GET_PLIST. Return 0 on error. */
get_client_plist(struct client * cli)927 static int get_client_plist (struct client *cli)
928 {
929 	int first;
930 
931 	debug ("Client with fd %d requests the playlist", cli->socket);
932 
933 	/* Find the first connected client, and ask it to send the playlist.
934 	 * Here, send 1 if there is a client with the playlist, or 0 if there
935 	 * isn't. */
936 
937 	cli->requests_plist = 1;
938 
939 	first = find_sending_plist ();
940 	if (first == -1) {
941 		debug ("No clients with the playlist");
942 		cli->requests_plist = 0;
943 		if (!send_data_int(cli, 0))
944 			return 0;
945 		return 1;
946 	}
947 
948 	if (!send_data_int(cli, 1))
949 		return 0;
950 
951 	if (!send_int(clients[first].socket, EV_SEND_PLIST))
952 		return 0;
953 
954 	return 1;
955 }
956 
957 /* Find the client requesting the playlist. */
find_cli_requesting_plist()958 static int find_cli_requesting_plist ()
959 {
960 	int i;
961 
962 	for (i = 0; i < CLIENTS_MAX; i++)
963 		if (clients[i].requests_plist)
964 			return i;
965 	return -1;
966 }
967 
968 /* Handle CMD_SEND_PLIST. Some client requested to get the playlist, so we asked
969  * another client to send it (EV_SEND_PLIST). */
req_send_plist(struct client * cli)970 static int req_send_plist (struct client *cli)
971 {
972 	int requesting = find_cli_requesting_plist ();
973 	int send_fd;
974 	struct plist_item *item;
975 	int serial;
976 
977 	debug ("Client with fd %d wants to send its playlists", cli->socket);
978 
979 	if (requesting == -1) {
980 		logit ("No clients are requesting the playlist");
981 		send_fd = -1;
982 	}
983 	else {
984 		send_fd = clients[requesting].socket;
985 		if (!send_int(send_fd, EV_DATA)) {
986 			logit ("Error while sending response; disconnecting the client");
987 			close (send_fd);
988 			del_client (&clients[requesting]);
989 			send_fd = -1;
990 		}
991 	}
992 
993 	if (!get_int(cli->socket, &serial)) {
994 		logit ("Error while getting serial");
995 		return 0;
996 	}
997 
998 	if (send_fd != -1 && !send_int(send_fd, serial)) {
999 		error ("Error while sending serial; disconnecting the client");
1000 		close (send_fd);
1001 		del_client (&clients[requesting]);
1002 		send_fd = -1;
1003 	}
1004 
1005 	/* Even if no clients are requesting the playlist, we must read it,
1006 	 * because there is no way to say that we don't need it. */
1007 	while ((item = recv_item(cli->socket)) && item->file[0]) {
1008 		if (send_fd != -1 && !send_item(send_fd, item)) {
1009 			logit ("Error while sending item; disconnecting the client");
1010 			close (send_fd);
1011 			del_client (&clients[requesting]);
1012 			send_fd = -1;
1013 		}
1014 		plist_free_item_fields (item);
1015 		free (item);
1016 	}
1017 
1018 	if (item) {
1019 		plist_free_item_fields (item);
1020 		free (item);
1021 		logit ("Playlist sent");
1022 	}
1023 	else
1024 		logit ("Error while receiving item");
1025 
1026 	if (send_fd != -1 && !send_item (send_fd, NULL)) {
1027 		logit ("Error while sending end of playlist mark; "
1028 		       "disconnecting the client");
1029 		close (send_fd);
1030 		del_client (&clients[requesting]);
1031 		return 0;
1032 	}
1033 
1034 	if (requesting != -1)
1035 		clients[requesting].requests_plist = 0;
1036 
1037 	return item ? 1 : 0;
1038 }
1039 
1040 /* Client requested we send the queue so we get it from audio.c and
1041  * send it to the client. */
req_send_queue(struct client * cli)1042 static int req_send_queue (struct client *cli)
1043 {
1044 	int i;
1045 	struct plist *queue;
1046 
1047 	logit ("Client with fd %d wants queue... sending it", cli->socket);
1048 
1049 	if (!send_int(cli->socket, EV_DATA)) {
1050 		logit ("Error while sending response; disconnecting the client");
1051 		close (cli->socket);
1052 		del_client (cli);
1053 		return 0;
1054 	}
1055 
1056 	queue = audio_queue_get_contents ();
1057 
1058 	for (i = 0; i < queue->num; i++)
1059 		if (!plist_deleted(queue, i)) {
1060 			if(!send_item(cli->socket, &queue->items[i])){
1061 				logit ("Error sending queue; disconnecting the client");
1062 				close (cli->socket);
1063 				del_client (cli);
1064 				free (queue);
1065 				return 0;
1066 			}
1067 		}
1068 
1069 	plist_free (queue);
1070 	free (queue);
1071 
1072 	if (!send_item (cli->socket, NULL)) {
1073 		logit ("Error while sending end of playlist mark; "
1074 		       "disconnecting the client");
1075 		close (cli->socket);
1076 		del_client (cli);
1077 		return 0;
1078 	}
1079 
1080 	logit ("Queue sent");
1081 	return 1;
1082 }
1083 
1084 /* Handle command that synchronises the playlists between interfaces
1085  * (except forwarding the whole list). Return 0 on error. */
plist_sync_cmd(struct client * cli,const int cmd)1086 static int plist_sync_cmd (struct client *cli, const int cmd)
1087 {
1088 	if (cmd == CMD_CLI_PLIST_ADD) {
1089 		struct plist_item *item;
1090 
1091 		debug ("Sending EV_PLIST_ADD");
1092 
1093 		if (!(item = recv_item(cli->socket))) {
1094 			logit ("Error while receiving item");
1095 			return 0;
1096 		}
1097 
1098 		add_event_all (EV_PLIST_ADD, item);
1099 		plist_free_item_fields (item);
1100 		free (item);
1101 	}
1102 	else if (cmd == CMD_CLI_PLIST_DEL) {
1103 		char *file;
1104 
1105 		debug ("Sending EV_PLIST_DEL");
1106 
1107 		if (!(file = get_str(cli->socket))) {
1108 			logit ("Error while receiving file");
1109 			return 0;
1110 		}
1111 
1112 		add_event_all (EV_PLIST_DEL, file);
1113 		free (file);
1114 	}
1115 	else if (cmd == CMD_CLI_PLIST_MOVE) {
1116 		struct move_ev_data m;
1117 
1118 		if (!(m.from = get_str(cli->socket))
1119 				|| !(m.to = get_str(cli->socket))) {
1120 			logit ("Error while receiving file");
1121 			return 0;
1122 		}
1123 
1124 		add_event_all (EV_PLIST_MOVE, &m);
1125 
1126 		free (m.from);
1127 		free (m.to);
1128 	}
1129 	else { /* it can be only CMD_CLI_PLIST_CLEAR */
1130 		debug ("Sending EV_PLIST_CLEAR");
1131 		add_event_all (EV_PLIST_CLEAR, NULL);
1132 	}
1133 
1134 	return 1;
1135 }
1136 
1137 /* Handle CMD_PLIST_GET_SERIAL. Return 0 on error. */
req_plist_get_serial(struct client * cli)1138 static int req_plist_get_serial (struct client *cli)
1139 {
1140 	if (!send_data_int(cli, audio_plist_get_serial()))
1141 		return 0;
1142 	return 1;
1143 }
1144 
1145 /* Handle CMD_PLIST_SET_SERIAL. Return 0 on error. */
req_plist_set_serial(struct client * cli)1146 static int req_plist_set_serial (struct client *cli)
1147 {
1148 	int serial;
1149 
1150 	if (!get_int(cli->socket, &serial))
1151 		return 0;
1152 
1153 	if (serial < 0) {
1154 		logit ("Client wants to set bad serial number");
1155 		return 0;
1156 	}
1157 
1158 	debug ("Setting the playlist serial number to %d", serial);
1159 	audio_plist_set_serial (serial);
1160 
1161 	return 1;
1162 }
1163 
1164 /* Generate a unique playlist serial number. */
gen_serial(const struct client * cli)1165 static int gen_serial (const struct client *cli)
1166 {
1167 	static int seed = 0;
1168 	int serial;
1169 
1170 	/* Each client must always get a different serial number, so we use
1171 	 * also the client index to generate it. It must also not be used by
1172 	 * our playlist to not confuse clients.
1173 	 * There can be 256 different serial number per client, but it's
1174 	 * enough since clients use only two playlists. */
1175 
1176 	do {
1177 		serial = (seed << 8) | client_index(cli);
1178 		seed = (seed + 1) & 0xFF;
1179 	} while (serial == audio_plist_get_serial());
1180 
1181 	debug ("Generated serial %d for client with fd %d", serial, cli->socket);
1182 
1183 	return serial;
1184 }
1185 
1186 /* Send the unique number to the client. Return 0 on error. */
send_serial(struct client * cli)1187 static int send_serial (struct client *cli)
1188 {
1189 	if (!send_data_int(cli, gen_serial(cli))) {
1190 		logit ("Error when sending serial");
1191 		return 0;
1192 	}
1193 	return 1;
1194 }
1195 
1196 /* Send tags to the client. Return 0 on error. */
req_get_tags(struct client * cli)1197 static int req_get_tags (struct client *cli)
1198 {
1199 	struct file_tags *tags;
1200 	int res = 1;
1201 
1202 	debug ("Sending tags to client with fd %d...", cli->socket);
1203 
1204 	if (!send_int(cli->socket, EV_DATA)) {
1205 		logit ("Error when sending EV_DATA");
1206 		return 0;
1207 	}
1208 
1209 	tags = audio_get_curr_tags ();
1210 	if (!send_tags(cli->socket, tags)) {
1211 		logit ("Error when sending tags");
1212 		res = 0;
1213 	}
1214 
1215 	if (tags)
1216 		tags_free (tags);
1217 
1218 	return res;
1219 }
1220 
1221 /* Handle CMD_GET_MIXER_CHANNEL_NAME. Return 0 on error. */
req_get_mixer_channel_name(struct client * cli)1222 int req_get_mixer_channel_name (struct client *cli)
1223 {
1224 	int status = 1;
1225 	char *name = audio_get_mixer_channel_name ();
1226 
1227 	if (!send_data_str(cli, name ? name : ""))
1228 		status = 0;
1229 	free (name);
1230 
1231 	return status;
1232 }
1233 
1234 /* Handle CMD_TOGGLE_MIXER_CHANNEL. */
req_toggle_mixer_channel()1235 void req_toggle_mixer_channel ()
1236 {
1237 	audio_toggle_mixer_channel ();
1238 	add_event_all (EV_MIXER_CHANGE, NULL);
1239 }
1240 
1241 /* Handle CMD_TOGGLE_SOFTMIXER. */
req_toggle_softmixer()1242 void req_toggle_softmixer ()
1243 {
1244 	softmixer_set_active(!softmixer_is_active());
1245 	add_event_all (EV_MIXER_CHANGE, NULL);
1246 }
1247 
update_eq_name()1248 void update_eq_name()
1249 {
1250 	char buffer[27];
1251 
1252 	char *n = equalizer_current_eqname();
1253 
1254 	int l = strlen(n);
1255 
1256 	/* Status message can only take strings up to 25 chars
1257 	 * (Without terminating zero).
1258 	 * The message header has 11 chars (EQ set to...).
1259 	 */
1260 	if (l > 14)
1261 	{
1262 		n[14] = 0;
1263 		n[13] = '.';
1264 		n[12] = '.';
1265 		n[11] = '.';
1266 	}
1267 
1268 	sprintf(buffer, "EQ set to: %s", n);
1269 
1270 	logit("%s", buffer);
1271 
1272 	free(n);
1273 
1274 	status_msg(buffer);
1275 }
1276 
req_toggle_equalizer()1277 void req_toggle_equalizer ()
1278 {
1279 	equalizer_set_active(!equalizer_is_active());
1280 
1281 	update_eq_name();
1282 }
1283 
req_equalizer_refresh()1284 void req_equalizer_refresh()
1285 {
1286 	equalizer_refresh();
1287 
1288 	status_msg("Equalizer refreshed");
1289 
1290 	logit("Equalizer refreshed");
1291 }
1292 
req_equalizer_prev()1293 void req_equalizer_prev()
1294 {
1295 	equalizer_prev();
1296 
1297 	update_eq_name();
1298 }
1299 
req_equalizer_next()1300 void req_equalizer_next()
1301 {
1302 	equalizer_next();
1303 
1304 	update_eq_name();
1305 }
1306 
req_toggle_make_mono()1307 void req_toggle_make_mono()
1308 {
1309 	char buffer[128];
1310 
1311 	softmixer_set_mono(!softmixer_is_mono());
1312 
1313 	sprintf(buffer, "Mono-Mixing set to: %s", softmixer_is_mono()?"on":"off");
1314 
1315 	status_msg(buffer);
1316 }
1317 
1318 /* Handle CMD_GET_FILE_TAGS. Return 0 on error. */
get_file_tags(const int cli_id)1319 static int get_file_tags (const int cli_id)
1320 {
1321 	char *file;
1322 	int tags_sel;
1323 
1324 	if (!(file = get_str(clients[cli_id].socket)))
1325 		return 0;
1326 	if (!get_int(clients[cli_id].socket, &tags_sel)) {
1327 		free (file);
1328 		return 0;
1329 	}
1330 
1331 	tags_cache_add_request (&tags_cache, file, tags_sel, cli_id);
1332 	free (file);
1333 
1334 	return 1;
1335 }
1336 
abort_tags_requests(const int cli_id)1337 static int abort_tags_requests (const int cli_id)
1338 {
1339 	char *file;
1340 
1341 	if (!(file = get_str(clients[cli_id].socket)))
1342 		return 0;
1343 
1344 	tags_cache_clear_up_to (&tags_cache, file, cli_id);
1345 	free (file);
1346 
1347 	return 1;
1348 }
1349 
1350 /* Handle CMD_LIST_MOVE. Return 0 on error. */
req_list_move(struct client * cli)1351 static int req_list_move (struct client *cli)
1352 {
1353 	char *from;
1354 	char *to;
1355 
1356 	if (!(from = get_str(cli->socket)))
1357 		return 0;
1358 	if (!(to = get_str(cli->socket))) {
1359 		free (from);
1360 		return 0;
1361 	}
1362 
1363 	audio_plist_move (from, to);
1364 
1365 	free (from);
1366 	free (to);
1367 
1368 	return 1;
1369 }
1370 
1371 /* Handle CMD_QUEUE_MOVE. Return 0 on error. */
req_queue_move(const struct client * cli)1372 static int req_queue_move (const struct client *cli)
1373 {
1374 	/*char *from;
1375 	char *to;
1376 	*/
1377 	struct move_ev_data m;
1378 
1379 	if (!(m.from = get_str(cli->socket)))
1380 		return 0;
1381 	if (!(m.to = get_str(cli->socket))) {
1382 		free (m.from);
1383 		return 0;
1384 	}
1385 
1386 	audio_queue_move (m.from, m.to);
1387 
1388 	logit ("Swapping %s with %s in the queue", m.from, m.to);
1389 
1390 	/* Broadcast the event to clients */
1391 	add_event_all (EV_QUEUE_MOVE, &m);
1392 
1393 	free (m.from);
1394 	free (m.to);
1395 
1396 	return 1;
1397 }
1398 
1399 /* Receive a command from the client and execute it. */
handle_command(const int client_id)1400 static void handle_command (const int client_id)
1401 {
1402 	int cmd;
1403 	int err = 0;
1404 	struct client *cli = &clients[client_id];
1405 
1406 	if (!get_int(cli->socket, &cmd)) {
1407 		logit ("Failed to get command from the client");
1408 		close (cli->socket);
1409 		del_client (cli);
1410 		return;
1411 	}
1412 
1413 	switch (cmd) {
1414 		case CMD_QUIT:
1415 			logit ("Exit request from the client");
1416 			close (cli->socket);
1417 			del_client (cli);
1418 			server_quit = 1;
1419 			break;
1420 		case CMD_LIST_CLEAR:
1421 			logit ("Clearing the list");
1422 			audio_plist_clear ();
1423 			break;
1424 		case CMD_LIST_ADD:
1425 			if (!req_list_add(cli))
1426 				err = 1;
1427 			break;
1428 		case CMD_PLAY:
1429 			if (!req_play(cli))
1430 				err = 1;
1431 			break;
1432 		case CMD_DISCONNECT:
1433 			logit ("Client disconnected");
1434 			close (cli->socket);
1435 			del_client (cli);
1436 			break;
1437 		case CMD_PAUSE:
1438 			audio_pause ();
1439 			break;
1440 		case CMD_UNPAUSE:
1441 			audio_unpause ();
1442 			break;
1443 		case CMD_STOP:
1444 			audio_stop ();
1445 			break;
1446 		case CMD_GET_CTIME:
1447 			if (!send_data_int(cli, MAX(0, audio_get_time())))
1448 				err = 1;
1449 			break;
1450 		case CMD_SEEK:
1451 			if (!req_seek(cli))
1452 				err = 1;
1453 			break;
1454 		case CMD_JUMP_TO:
1455 			if (!req_jump_to(cli))
1456 				err = 1;
1457 			break;
1458 		case CMD_GET_SNAME:
1459 			if (!send_sname(cli))
1460 				err = 1;
1461 			break;
1462 		case CMD_GET_STATE:
1463 			if (!send_data_int(cli, audio_get_state()))
1464 				err = 1;
1465 			break;
1466 		case CMD_GET_BITRATE:
1467 			if (!send_data_int(cli, sound_info.bitrate))
1468 				err = 1;
1469 			break;
1470 		case CMD_GET_AVG_BITRATE:
1471 			if (!send_data_int(cli, sound_info.avg_bitrate))
1472 				err = 1;
1473 			break;
1474 		case CMD_GET_RATE:
1475 			if (!send_data_int(cli, sound_info.rate))
1476 				err = 1;
1477 			break;
1478 		case CMD_GET_CHANNELS:
1479 			if (!send_data_int(cli, sound_info.channels))
1480 				err = 1;
1481 			break;
1482 		case CMD_NEXT:
1483 			audio_next ();
1484 			break;
1485 		case CMD_PREV:
1486 			audio_prev ();
1487 			break;
1488 		case CMD_PING:
1489 			if (!send_int(cli->socket, EV_PONG))
1490 				err = 1;
1491 			break;
1492 		case CMD_GET_OPTION:
1493 			if (!send_option(cli))
1494 				err = 1;
1495 			break;
1496 		case CMD_SET_OPTION:
1497 			if (!get_set_option(cli))
1498 				err = 1;
1499 			break;
1500 		case CMD_GET_MIXER:
1501 			if (!send_data_int(cli, audio_get_mixer()))
1502 				err = 1;
1503 			break;
1504 		case CMD_SET_MIXER:
1505 			if (!set_mixer(cli))
1506 				err = 1;
1507 			break;
1508 		case CMD_DELETE:
1509 			if (!delete_item(cli))
1510 				err = 1;
1511 			break;
1512 		case CMD_SEND_PLIST_EVENTS:
1513 			cli->wants_plist_events = 1;
1514 			logit ("Request for events");
1515 			break;
1516 		case CMD_GET_PLIST:
1517 			if (!get_client_plist(cli))
1518 				err = 1;
1519 			break;
1520 		case CMD_SEND_PLIST:
1521 			if (!req_send_plist(cli))
1522 				err = 1;
1523 			break;
1524 		case CMD_CAN_SEND_PLIST:
1525 			cli->can_send_plist = 1;
1526 			break;
1527 		case CMD_CLI_PLIST_ADD:
1528 		case CMD_CLI_PLIST_DEL:
1529 		case CMD_CLI_PLIST_CLEAR:
1530 		case CMD_CLI_PLIST_MOVE:
1531 			if (!plist_sync_cmd(cli, cmd))
1532 				err = 1;
1533 			break;
1534 		case CMD_LOCK:
1535 			if (!client_lock(cli))
1536 				err = 1;
1537 			break;
1538 		case CMD_UNLOCK:
1539 			if (!client_unlock(cli))
1540 				err = 1;
1541 			break;
1542 		case CMD_GET_SERIAL:
1543 			if (!send_serial(cli))
1544 				err = 1;
1545 			break;
1546 		case CMD_PLIST_GET_SERIAL:
1547 			if (!req_plist_get_serial(cli))
1548 				err = 1;
1549 			break;
1550 		case CMD_PLIST_SET_SERIAL:
1551 			if (!req_plist_set_serial(cli))
1552 				err = 1;
1553 			break;
1554 		case CMD_GET_TAGS:
1555 			if (!req_get_tags(cli))
1556 				err = 1;
1557 			break;
1558 		case CMD_TOGGLE_MIXER_CHANNEL:
1559 			req_toggle_mixer_channel ();
1560 			break;
1561 		case CMD_TOGGLE_SOFTMIXER:
1562 			req_toggle_softmixer ();
1563 			break;
1564 		case CMD_GET_MIXER_CHANNEL_NAME:
1565 			if (!req_get_mixer_channel_name(cli))
1566 				err = 1;
1567 			break;
1568 		case CMD_GET_FILE_TAGS:
1569 			if (!get_file_tags(client_id))
1570 				err = 1;
1571 			break;
1572 		case CMD_ABORT_TAGS_REQUESTS:
1573 			if (!abort_tags_requests(client_id))
1574 				err = 1;
1575 			break;
1576 		case CMD_LIST_MOVE:
1577 			if (!req_list_move(cli))
1578 				err = 1;
1579 			break;
1580 		case CMD_TOGGLE_EQUALIZER:
1581 			req_toggle_equalizer();
1582 			break;
1583 		case CMD_EQUALIZER_REFRESH:
1584 			req_equalizer_refresh();
1585 			break;
1586 		case CMD_EQUALIZER_PREV:
1587 			req_equalizer_prev();
1588 			break;
1589 		case CMD_EQUALIZER_NEXT:
1590 			req_equalizer_next();
1591 			break;
1592 		case CMD_TOGGLE_MAKE_MONO:
1593 			req_toggle_make_mono();
1594 			break;
1595 		case CMD_QUEUE_ADD:
1596 			if (!req_queue_add(cli))
1597 				err = 1;
1598 			break;
1599 		case CMD_QUEUE_DEL:
1600 			if (!req_queue_del(cli))
1601 				err = 1;
1602 			break;
1603 		case CMD_QUEUE_CLEAR:
1604 			logit ("Clearing the queue");
1605 			audio_queue_clear ();
1606 			add_event_all (EV_QUEUE_CLEAR, NULL);
1607 			break;
1608 		case CMD_QUEUE_MOVE:
1609 			if (!req_queue_move(cli))
1610 				err = 1;
1611 			break;
1612 		case CMD_GET_QUEUE:
1613 			if (!req_send_queue(cli))
1614 				err = 1;
1615 			break;
1616 		default:
1617 			logit ("Bad command (0x%x) from the client", cmd);
1618 			err = 1;
1619 	}
1620 
1621 	if (err) {
1622 		logit ("Closing client connection due to error");
1623 		close (cli->socket);
1624 		del_client (cli);
1625 	}
1626 }
1627 
1628 /* Add clients file descriptors to fds. */
add_clients_fds(fd_set * read,fd_set * write)1629 static void add_clients_fds (fd_set *read, fd_set *write)
1630 {
1631 	int i;
1632 
1633 	for (i = 0; i < CLIENTS_MAX; i++)
1634 		if (clients[i].socket != -1) {
1635 			if (locking_client() == -1 || is_locking(&clients[i]))
1636 				FD_SET (clients[i].socket, read);
1637 
1638 			LOCK (clients[i].events_mutex);
1639 			if (!event_queue_empty(&clients[i].events))
1640 				FD_SET (clients[i].socket, write);
1641 			UNLOCK (clients[i].events_mutex);
1642 		}
1643 }
1644 
1645 /* Return the maximum fd from clients and the argument. */
max_fd(int max)1646 static int max_fd (int max)
1647 {
1648 	int i;
1649 
1650 	if (wake_up_pipe[0] > max)
1651 		max = wake_up_pipe[0];
1652 
1653 	for (i = 0; i < CLIENTS_MAX; i++)
1654 		if (clients[i].socket > max)
1655 			max = clients[i].socket;
1656 	return max;
1657 }
1658 
1659 /* Handle clients whose fds are ready to read. */
handle_clients(fd_set * fds)1660 static void handle_clients (fd_set *fds)
1661 {
1662 	int i;
1663 
1664 	for (i = 0; i < CLIENTS_MAX; i++)
1665 		if (clients[i].socket != -1
1666 				&& FD_ISSET(clients[i].socket, fds)) {
1667 			if (locking_client() == -1
1668 					|| is_locking(&clients[i]))
1669 				handle_command (i);
1670 			else
1671 				debug ("Not getting a command from client with"
1672 						" fd %d because of lock",
1673 						clients[i].socket);
1674 		}
1675 }
1676 
1677 /* Close all client connections sending EV_EXIT. */
close_clients()1678 static void close_clients ()
1679 {
1680 	int i;
1681 
1682 	for (i = 0; i < CLIENTS_MAX; i++)
1683 		if (clients[i].socket != -1) {
1684 			send_int (clients[i].socket, EV_EXIT);
1685 			close (clients[i].socket);
1686 			del_client (&clients[i]);
1687 		}
1688 }
1689 
1690 /* Handle incoming connections */
server_loop(int list_sock)1691 void server_loop (int list_sock)
1692 {
1693 	struct sockaddr_un client_name;
1694 	socklen_t name_len = sizeof (client_name);
1695 	int end = 0;
1696 
1697 	logit ("MOC server started, pid: %d", getpid());
1698 
1699 	do {
1700 		int res;
1701 		fd_set fds_write, fds_read;
1702 
1703 		FD_ZERO (&fds_read);
1704 		FD_ZERO (&fds_write);
1705 		FD_SET (list_sock, &fds_read);
1706 		FD_SET (wake_up_pipe[0], &fds_read);
1707 		add_clients_fds (&fds_read, &fds_write);
1708 
1709 		if (!server_quit)
1710 			res = select (max_fd(list_sock)+1, &fds_read,
1711 					&fds_write, NULL, NULL);
1712 		else
1713 			res = 0;
1714 
1715 		if (res == -1 && errno != EINTR && !server_quit)
1716 			fatal ("select() failed: %s", strerror (errno));
1717 
1718 		if (!server_quit && res >= 0) {
1719 			if (FD_ISSET(list_sock, &fds_read)) {
1720 				int client_sock;
1721 
1722 				debug ("accept()ing connection...");
1723 				client_sock = accept (list_sock,
1724 					(struct sockaddr *)&client_name,
1725 					&name_len);
1726 
1727 				if (client_sock == -1)
1728 					fatal ("accept() failed: %s", strerror(errno));
1729 				logit ("Incoming connection");
1730 				if (!add_client(client_sock))
1731 					busy (client_sock);
1732 			}
1733 
1734 			if (FD_ISSET(wake_up_pipe[0], &fds_read)) {
1735 				int w;
1736 
1737 				logit ("Got 'wake up'");
1738 
1739 				if (read(wake_up_pipe[0], &w, sizeof(w)) < 0)
1740 					fatal ("Can't read wake up signal: %s", strerror(errno));
1741 			}
1742 
1743 			send_events (&fds_write);
1744 			handle_clients (&fds_read);
1745 		}
1746 
1747 		if (server_quit)
1748 			logit ("Exiting...");
1749 
1750 	} while (!end && !server_quit);
1751 
1752 	close_clients ();
1753 	clients_cleanup ();
1754 	close (list_sock);
1755 	server_shutdown ();
1756 }
1757 
set_info_bitrate(const int bitrate)1758 void set_info_bitrate (const int bitrate)
1759 {
1760 	sound_info.bitrate = bitrate;
1761 	add_event_all (EV_BITRATE, NULL);
1762 }
1763 
set_info_channels(const int channels)1764 void set_info_channels (const int channels)
1765 {
1766 	sound_info.channels = channels;
1767 	add_event_all (EV_CHANNELS, NULL);
1768 }
1769 
set_info_rate(const int rate)1770 void set_info_rate (const int rate)
1771 {
1772 	sound_info.rate = rate;
1773 	add_event_all (EV_RATE, NULL);
1774 }
1775 
set_info_avg_bitrate(const int avg_bitrate)1776 void set_info_avg_bitrate (const int avg_bitrate)
1777 {
1778 	sound_info.avg_bitrate = avg_bitrate;
1779 	add_event_all (EV_AVG_BITRATE, NULL);
1780 }
1781 
1782 /* Notify the client about change of the player state. */
state_change()1783 void state_change ()
1784 {
1785 	add_event_all (EV_STATE, NULL);
1786 }
1787 
ctime_change()1788 void ctime_change ()
1789 {
1790 	add_event_all (EV_CTIME, NULL);
1791 }
1792 
tags_change()1793 void tags_change ()
1794 {
1795 	add_event_all (EV_TAGS, NULL);
1796 }
1797 
status_msg(const char * msg)1798 void status_msg (const char *msg)
1799 {
1800 	add_event_all (EV_STATUS_MSG, msg);
1801 }
1802 
tags_response(const int client_id,const char * file,const struct file_tags * tags)1803 void tags_response (const int client_id, const char *file,
1804 		const struct file_tags *tags)
1805 {
1806 	assert (file != NULL);
1807 	assert (tags != NULL);
1808 	assert (LIMIT(client_id, CLIENTS_MAX));
1809 
1810 	if (clients[client_id].socket != -1) {
1811 		struct tag_ev_response *data
1812 			= (struct tag_ev_response *)xmalloc (
1813 					sizeof(struct tag_ev_response));
1814 
1815 		data->file = xstrdup (file);
1816 		data->tags = tags_dup (tags);
1817 
1818 		add_event (&clients[client_id], EV_FILE_TAGS, data);
1819 		wake_up_server ();
1820 	}
1821 }
1822 
ev_audio_start()1823 void ev_audio_start ()
1824 {
1825 	add_event_all (EV_AUDIO_START, NULL);
1826 }
1827 
ev_audio_stop()1828 void ev_audio_stop ()
1829 {
1830 	add_event_all (EV_AUDIO_STOP, NULL);
1831 }
1832 
1833 /* Announce to clients that first file from the queue is being played
1834  * and therefore needs to be removed from it */
1835 /* XXX: this function is called from player thread and add_event_all
1836  *      imho doesn't properly lock all shared variables -- possible
1837  *      race condition??? */
server_queue_pop(const char * filename)1838 void server_queue_pop (const char *filename)
1839 {
1840 	debug ("Queue pop -- broadcasting EV_QUEUE_DEL");
1841 	add_event_all (EV_QUEUE_DEL, filename);
1842 }
1843