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