]> git.tuebingen.mpg.de Git - paraslash.git/blob - audiod.c
Revamp status item handling.
[paraslash.git] / audiod.c
1 /*
2  * Copyright (C) 2005-2009 Andre Noll <maan@systemlinux.org>
3  *
4  * Licensed under the GPL v2. For licencing details see COPYING.
5  */
6
7 /** \file audiod.c the paraslash's audio daemon */
8 #include <sys/types.h>
9 #include <dirent.h>
10 #include <signal.h>
11
12 #include "para.h"
13 #include "error.h"
14 #include "audiod.cmdline.h"
15 #include "list.h"
16 #include "sched.h"
17 #include "ggo.h"
18 #include "recv.h"
19 #include "filter.h"
20 #include "grab_client.cmdline.h"
21 #include "grab_client.h"
22 #include "client.cmdline.h"
23 #include "client.h"
24 #include "audiod.h"
25 #include "net.h"
26 #include "daemon.h"
27 #include "string.h"
28 #include "fd.h"
29 #include "write.h"
30 #include "write_common.h"
31 #include "signal.h"
32
33 /** define the array of error lists needed by para_audiod */
34 INIT_AUDIOD_ERRLISTS;
35 /** define the array containing all supported audio formats */
36 const char *audio_formats[] = {AUDIOD_AUDIO_FORMAT_ARRAY NULL};
37
38 /** Defines how audiod handles one supported audio format. */
39 struct audio_format_info {
40         /** pointer to the receiver for this audio format */
41         struct receiver *receiver;
42         /** the receiver configuration */
43         void *receiver_conf;
44         /** the number of filters that should be activated for this audio format */
45         unsigned int num_filters;
46         /** Array of filter numbers to be activated. */
47         unsigned *filter_nums;
48         /** Pointer to the array of filter configurations. */
49         void **filter_conf;
50         /** the number of filters that should be activated for this audio format */
51         unsigned int num_writers;
52         /** Array of writer numbers to be activated. */
53         int *writer_nums;
54         /** pointer to the array of writer configurations */
55         void **writer_conf;
56         /** do not start receiver/filters/writer before this time */
57         struct timeval restart_barrier;
58 };
59
60 /**
61  * para_audiod uses \p MAX_STREAM_SLOTS different slots, each of which may
62  * be associated with a receiver/filter/writer triple. This array holds all
63  * information on the status of these slots.
64  *
65  * \sa struct slot_info
66  * */
67 struct slot_info slot[MAX_STREAM_SLOTS];
68
69 /** The vss status flags audiod is interested in. */
70 enum vss_status_flags {
71         /** Whether the 'N' flag is set. */
72         VSS_STATUS_FLAG_NEXT = 1,
73         /** The 'P' flag is set. */
74         VSS_STATUS_FLAG_PLAYING = 2,
75 };
76
77 /**
78  * The task for obtaining para_server's status (para_client stat).
79  *
80  * \sa struct task, struct sched.
81  */
82 struct status_task {
83         /** The associated task structure of audiod. */
84         struct task task;
85         /** Client data associated with the stat task. */
86         struct client_task *ct;
87         /** Do not restart client command until this time. */
88         struct timeval restart_barrier;
89         /** Last time we received status data from para_server. */
90         struct timeval last_status_read;
91         /** The offset value announced by para_server. */
92         int offset_seconds;
93         /** The length of the current audio file as announced by para_server. */
94         int length_seconds;
95         /** The start of the current stream from the view of para_server. */
96         struct timeval server_stream_start;
97         /** The average time deviation between para_server and para_audiod. */
98         struct timeval sa_time_diff;
99         /** Whether client time is ahead of server time. */
100         int sa_time_diff_sign;
101         /** The 'P' and the 'N' flags as announced by para_server. */
102         enum vss_status_flags vss_status;
103         /** Number of times the clock difference is to be checked. */
104         unsigned clock_diff_count;
105         /** When to start the next check for clock difference. */
106         struct timeval clock_diff_barrier;
107         /** Number of the audio format as announced by para_server. */
108         int current_audio_format_num;
109 };
110
111 /** The array of status items sent by para_server. */
112 char *stat_item_values[NUM_STAT_ITEMS] = {NULL};
113
114 /**
115  * the current mode of operation of which can be changed by the on/off/cycle
116  * commands. It is either, AUDIOD_OFF, AUDIOD_ON or AUDIOD_STANDBY.
117  */
118 int audiod_status = AUDIOD_ON;
119
120 /**
121  * the gengetopt args_info struct that holds information on all command line
122  * arguments
123  */
124 struct audiod_args_info conf;
125
126 static char *socket_name;
127 static struct audio_format_info afi[NUM_AUDIO_FORMATS];
128
129 static struct signal_task signal_task_struct, *sig_task = &signal_task_struct;
130
131 static struct status_task status_task_struct;
132
133 /**
134  * the task that calls the status command of para_server
135  *
136  * \sa struct status_task
137  */
138 static struct status_task *stat_task = &status_task_struct;
139 static struct timeval initial_delay_barrier;
140
141 /**
142  * the task for handling audiod commands
143  *
144  * \sa struct task, struct sched
145  */
146 struct command_task {
147         /** the local listening socket */
148         int fd;
149         /** the associated task structure */
150         struct task task;
151 };
152
153 /** iterate over all supported audio formats */
154 #define FOR_EACH_AUDIO_FORMAT(af) for (af = 0; af < NUM_AUDIO_FORMATS; af++)
155
156 /**
157  * get the audio format number
158  * \param name the name of the audio format
159  *
160  * \return The audio format number on success, -E_UNSUPPORTED_AUDIO_FORMAT if
161  * \a name is not a supported audio format.
162  */
163 int get_audio_format_num(char *name)
164 {
165         int i;
166
167         while (para_isspace(*name))
168                 name++;
169         FOR_EACH_AUDIO_FORMAT(i)
170                 if (!strcmp(name, audio_formats[i]))
171                         return i;
172         return -E_UNSUPPORTED_AUDIO_FORMAT;
173 }
174
175 char *get_time_string(int slot_num)
176 {
177         int ret, seconds = 0, length;
178         struct timeval *tmp, sum, sss, /* server stream start */
179                 wtime, /* now - writer start */
180                 rskip; /* receiver start - sss */
181         struct slot_info *s = slot_num < 0? NULL : &slot[slot_num];
182
183         if (audiod_status == AUDIOD_OFF)
184                 goto empty;
185         if (!(stat_task->vss_status & VSS_STATUS_FLAG_PLAYING)) {
186                 if (stat_task->length_seconds) /* paused */
187                         return NULL;
188                 goto empty; /* stopped */
189         }
190         if (audiod_status == AUDIOD_ON && !s)
191                 goto empty;
192         /* valid status items and playing */
193         if (s) { /* writer active in this slot */
194                 length = s->seconds_total;
195                 tmp = &s->server_stream_start;
196         } else { /* standby mode, rely on status items */
197                 length = stat_task->length_seconds;
198                 tmp = &stat_task->server_stream_start;
199         }
200         if (stat_task->sa_time_diff_sign > 0)
201                 tv_diff(tmp, &stat_task->sa_time_diff, &sss);
202         else
203                 tv_add(tmp, &stat_task->sa_time_diff, &sss);
204         if (!s) {
205                 struct timeval diff;
206                 tv_diff(now, &sss, &diff);
207                 seconds = diff.tv_sec + stat_task->offset_seconds;
208                 goto out;
209         }
210         tv_diff(now, &s->wstime, &wtime);
211         seconds = s->offset_seconds;
212         ret = tv_diff(&s->rstime, &sss, &rskip);
213         if (ret > 0) { /* audiod was started in the middle of the stream */
214                 tv_add(&wtime, &rskip, &sum);
215                 seconds += sum.tv_sec;
216         } else
217                 seconds += wtime.tv_sec;
218 out:
219         seconds = PARA_MIN(seconds, length);
220         seconds = PARA_MAX(seconds, 0);
221         return make_message(
222                 "%s%d:%02d [%d:%02d] (%d%%/%d:%02d)",
223                 s? "" : "~",
224                 seconds / 60,
225                 seconds % 60,
226                 (length - seconds) / 60,
227                 (length - seconds) % 60,
228                 length? (seconds * 100 + length / 2) / length : 0,
229                 length / 60,
230                 length % 60
231         );
232 empty:
233         return para_strdup(NULL);
234 }
235
236 static int want_colors(void)
237 {
238         if (conf.color_arg == color_arg_no)
239                 return 0;
240         if (conf.color_arg == color_arg_yes)
241                 return 1;
242         if (conf.logfile_given)
243                 return 0;
244         return isatty(STDERR_FILENO);
245 }
246
247 static void parse_config_or_die(void)
248 {
249         int ret;
250         char *config_file;
251         struct audiod_cmdline_parser_params params = {
252                 .override = 0,
253                 .initialize = 0,
254                 .check_required = 1,
255                 .check_ambiguity = 0,
256                 .print_errors = 1
257         };
258
259         if (conf.config_file_given)
260                 config_file = para_strdup(conf.config_file_arg);
261         else {
262                 char *home = para_homedir();
263                 config_file = make_message("%s/.paraslash/audiod.conf", home);
264                 free(home);
265         }
266         ret = file_exists(config_file);
267         if (conf.config_file_given && !ret) {
268                 PARA_EMERG_LOG("can not read config file %s\n", config_file);
269                 goto err;
270         }
271         if (ret)
272                 audiod_cmdline_parser_config_file(config_file, &conf, &params);
273         free(config_file);
274         daemon_set_loglevel(conf.loglevel_arg);
275         return;
276 err:
277         free(config_file);
278         exit(EXIT_FAILURE);
279 }
280
281 static void setup_signal_handling(void)
282 {
283         sig_task->fd = para_signal_init();
284         PARA_INFO_LOG("signal pipe: fd %d\n", sig_task->fd);
285         para_install_sighandler(SIGINT);
286         para_install_sighandler(SIGTERM);
287         para_install_sighandler(SIGHUP);
288         para_sigaction(SIGPIPE, SIG_IGN);
289 }
290
291 static void clear_slot(int slot_num)
292 {
293         struct slot_info *s = &slot[slot_num];
294
295         PARA_INFO_LOG("clearing slot %d\n", slot_num);
296         memset(s, 0, sizeof(struct slot_info));
297         s->format = -1;
298 }
299
300 static void close_receiver(int slot_num)
301 {
302         struct slot_info *s = &slot[slot_num];
303         struct audio_format_info *a;
304
305         if (s->format < 0 || !s->receiver_node)
306                 return;
307         a = &afi[s->format];
308         PARA_NOTICE_LOG("closing %s receiver in slot %d\n",
309                 audio_formats[s->format], slot_num);
310         a->receiver->close(s->receiver_node);
311         free(s->receiver_node);
312         s->receiver_node = NULL;
313 }
314
315 static void kill_all_decoders(int error)
316 {
317         int i;
318
319         FOR_EACH_SLOT(i) {
320                 struct slot_info *s = &slot[i];
321                 if (s->wng && s->wng->task.error >= 0) {
322                         PARA_INFO_LOG("deactivating wng in slot %d\n",
323                                 i);
324                         s->wng->task.error = error;
325                 }
326                 if (s->fc && s->fc->task.error >= 0) {
327                         PARA_INFO_LOG("deactivatimg filter chain in slot %d\n", i);
328                         s->fc->task.error = error;
329                 }
330                 if (s->receiver_node && s->receiver_node->task.error >= 0) {
331                         PARA_INFO_LOG("deactivating receiver_node in slot %d\n", i);
332                         s->receiver_node->task.error = error;
333                 }
334         }
335 }
336
337 static int get_empty_slot(void)
338 {
339         int i;
340         struct slot_info *s;
341
342         FOR_EACH_SLOT(i) {
343                 s = &slot[i];
344                 if (s->format < 0) {
345                         clear_slot(i);
346                         return i;
347                 }
348                 if (s->wng || s->receiver_node || s->fc)
349                         continue;
350                 clear_slot(i);
351                 return i;
352         }
353         return -E_NO_MORE_SLOTS;
354 }
355
356 /**
357  * get the number of filters
358  *
359  * \param audio_format_num the number identifying the audio format
360  *
361  * \return the number of filters for the given audio format
362  *
363  * \sa struct filter;
364  */
365 int num_filters(int audio_format_num)
366 {
367         return afi[audio_format_num].num_filters;
368 }
369
370 static void open_filters(int slot_num)
371 {
372         struct slot_info *s = &slot[slot_num];
373         struct audio_format_info *a = &afi[s->format];
374         struct filter_node *fn;
375         int nf = a->num_filters;
376         int i;
377
378         s->fc = NULL;
379         if (!nf)
380                 return;
381         PARA_INFO_LOG("opening %s filters\n", audio_formats[s->format]);
382         s->fc = para_calloc(sizeof(struct filter_chain));
383         s->fc->filter_nodes = para_malloc(nf * sizeof(struct filter_node));
384         s->fc->inbufp = &s->receiver_node->buf;
385         s->fc->in_loaded = &s->receiver_node->loaded;
386         s->fc->input_error = &s->receiver_node->task.error;
387         s->fc->task.pre_select = filter_pre_select;
388         s->fc->task.post_select = NULL;
389         s->fc->task.error = 0;
390         s->fc->num_filters = nf;
391
392         s->receiver_node->output_error = &s->fc->task.error;
393         sprintf(s->fc->task.status, "filter chain");
394         FOR_EACH_FILTER_NODE(fn, s->fc, i) {
395                 struct filter *f = filters + a->filter_nums[i];
396                 fn->filter_num = a->filter_nums[i];
397                 fn->conf = a->filter_conf[i];
398                 fn->fc = s->fc;
399                 fn->loaded = 0;
400                 INIT_LIST_HEAD(&fn->callbacks);
401                 f->open(fn);
402                 PARA_NOTICE_LOG("%s filter %d/%d (%s) started in slot %d\n",
403                         audio_formats[s->format], i,  nf, f->name, slot_num);
404                 s->fc->outbufp = &fn->buf;
405                 s->fc->out_loaded = &fn->loaded;
406         }
407         register_task(&s->fc->task);
408 }
409
410 static void open_writers(int slot_num)
411 {
412         int ret, i;
413         struct slot_info *s = &slot[slot_num];
414         struct audio_format_info *a = &afi[s->format];
415
416         PARA_INFO_LOG("opening %s writers\n", audio_formats[s->format]);
417         if (!a->num_writers)
418                 s->wng = setup_default_wng();
419         else
420                 s->wng = wng_new(a->num_writers);
421         if (s->fc) {
422                 s->wng->bufp = s->fc->outbufp;
423                 s->wng->loaded = s->fc->out_loaded;
424                 s->wng->input_error = &s->fc->task.error;
425                 s->wng->channels = &s->fc->channels;
426                 s->wng->samplerate = &s->fc->samplerate;
427                 s->fc->output_error = &s->wng->task.error;
428                 PARA_INFO_LOG("samplerate: %d\n", *s->wng->samplerate);
429         } else {
430                 s->wng->bufp = &s->receiver_node->buf;
431                 s->wng->loaded = &s->receiver_node->loaded;
432                 s->wng->input_error = &s->receiver_node->task.error;
433         }
434         for (i = 0; i < a->num_writers; i++) {
435                 s->wng->writer_nodes[i].conf = a->writer_conf[i];
436                 s->wng->writer_nodes[i].writer_num = a->writer_nums[i];
437         }
438         ret = wng_open(s->wng);
439         if (ret < 0)
440                 return;
441         s->wstime = *now;
442         s->server_stream_start = stat_task->server_stream_start.tv_sec?
443                 stat_task->server_stream_start : *now;
444         s->offset_seconds = stat_task->offset_seconds;
445         s->seconds_total = stat_task->length_seconds;
446         activate_inactive_grab_clients(slot_num, s->format, s->fc);
447 }
448
449 static int open_receiver(int format)
450 {
451         struct audio_format_info *a = &afi[format];
452         struct slot_info *s;
453         int ret, slot_num;
454         struct receiver_node *rn;
455         const struct timeval restart_delay = {2, 0};
456
457         ret = get_empty_slot();
458         if (ret < 0)
459                 goto err;
460         slot_num = ret;
461         s = &slot[slot_num];
462         s->format = format;
463         s->receiver_node = para_calloc(sizeof(struct receiver_node));
464         rn = s->receiver_node;
465         rn->receiver = a->receiver;
466         rn->conf = a->receiver_conf;
467         ret = a->receiver->open(s->receiver_node);
468         if (ret < 0) {
469                 free(s->receiver_node);
470                 s->receiver_node = NULL;
471                 goto err;
472         }
473         PARA_NOTICE_LOG("started %s: %s receiver in slot %d\n",
474                 audio_formats[s->format], a->receiver->name, slot_num);
475         rn->task.pre_select = a->receiver->pre_select;
476         rn->task.post_select = a->receiver->post_select;
477         s->rstime = *now;
478         sprintf(rn->task.status, "%s receiver node", rn->receiver->name);
479         register_task(&rn->task);
480         ret = 1;
481 err:
482         if (ret < 0)
483                 PARA_ERROR_LOG("%s\n", para_strerror(-ret));
484         tv_add(now, &restart_delay, &afi[format].restart_barrier);
485         return ret;
486 }
487
488 /* return: 0: Not running, 1: Running, -1: Running but eof (or error) */
489 static int receiver_running(int format)
490 {
491         int i, ret = 0;
492
493         FOR_EACH_SLOT(i) {
494                 struct slot_info *s = &slot[i];
495                 if (s->format != format)
496                         continue;
497                 if (!s->receiver_node)
498                         continue;
499                 if (s->receiver_node->task.error >= 0)
500                         return 1;
501                 ret = -1;
502         }
503         return ret;
504 }
505
506 static void open_current_receiver(struct sched *s)
507 {
508         struct timeval diff;
509         int ret, cafn = stat_task->current_audio_format_num;
510
511         if (cafn < 0 || !stat_task->ct)
512                 return;
513         /* Do nothing if the 'N' flag is set or the 'P' flag is unset */
514         if (stat_task->vss_status != VSS_STATUS_FLAG_PLAYING)
515                 return;
516         ret = receiver_running(cafn);
517         if (ret > 0) /* already running and not eof */
518                 return;
519         if (ret < 0) { /* eof */
520                 /*
521                  * para_server uses a zero start time during the announcement
522                  * period, i.e. before it sends the first chunk. Wait until
523                  * this period begins to avoid restarting the receiver that
524                  * belongs to the file just completed.
525                  */
526                 if (stat_task->server_stream_start.tv_sec)
527                         return;
528         }
529         if (tv_diff(now, &afi[cafn].restart_barrier, &diff) < 0) {
530                 /* avoid busy loop */
531                 s->timeout = diff;
532                 return;
533         }
534         /* start a new receiver */
535         open_receiver(cafn);
536 }
537
538 static unsigned compute_time_diff(const struct timeval *status_time)
539 {
540         struct timeval tmp, diff;
541         static unsigned count;
542         int sign, sa_time_diff_sign = stat_task->sa_time_diff_sign;
543         const struct timeval max_deviation = {0, 500 * 1000};
544         const int time_smooth = 5;
545
546         if (!status_time)
547                 return count;
548         sign = tv_diff(status_time, now, &diff);
549 //              PARA_NOTICE_LOG("%s: sign = %i, sa_time_diff_sign = %i\n", __func__,
550 //                      sign, sa_time_diff_sign);
551         if (!count) {
552                 sa_time_diff_sign = sign;
553                 stat_task->sa_time_diff = diff;
554                 count++;
555                 goto out;
556         }
557         if (count > 5) {
558                 int s = tv_diff(&diff, &stat_task->sa_time_diff, &tmp);
559                 if (tv_diff(&max_deviation, &tmp, NULL) < 0)
560                         PARA_WARNING_LOG("time diff jump: %lims\n",
561                                 s * tv2ms(&tmp));
562         }
563         count++;
564         sa_time_diff_sign = tv_convex_combination(
565                 sa_time_diff_sign * time_smooth, &stat_task->sa_time_diff,
566                 count > 10? sign : sign * time_smooth, &diff,
567                 &tmp);
568         stat_task->sa_time_diff = tmp;
569         PARA_INFO_LOG("time diff (cur/avg): %s%lums/%s%lums\n",
570                 sign > 0? "+" : "-",
571                 tv2ms(&diff),
572                 sa_time_diff_sign ? "+" : "-",
573                 tv2ms(&stat_task->sa_time_diff)
574         );
575 out:
576         stat_task->sa_time_diff_sign = sa_time_diff_sign;
577         return count;
578 }
579
580 static int update_item(int itemnum, char *buf)
581 {
582         long unsigned sec, usec;
583
584         if (stat_task->clock_diff_count && itemnum != SI_CURRENT_TIME)
585                 return 1;
586         free(stat_item_values[itemnum]);
587         stat_item_values[itemnum] = para_strdup(buf);
588         stat_client_write_item(itemnum);
589         switch (itemnum) {
590         case SI_STATUS_FLAGS:
591                 stat_task->vss_status = 0;
592                 if (strchr(buf, 'N'))
593                         stat_task->vss_status |= VSS_STATUS_FLAG_NEXT;
594                 if (strchr(buf, 'P'))
595                         stat_task->vss_status |= VSS_STATUS_FLAG_PLAYING;
596                 break;
597         case SI_OFFSET:
598                 stat_task->offset_seconds = atoi(buf);
599                 break;
600         case SI_SECONDS_TOTAL:
601                 stat_task->length_seconds = atoi(buf);
602                 break;
603         case SI_STREAM_START:
604                 if (sscanf(buf, "%lu.%lu", &sec, &usec) == 2) {
605                         struct timeval a_start, delay;
606                         delay.tv_sec = conf.stream_delay_arg / 1000;
607                         delay.tv_usec = (conf.stream_delay_arg % 1000) * 1000;
608                         stat_task->server_stream_start.tv_sec = sec;
609                         stat_task->server_stream_start.tv_usec = usec;
610                         if (compute_time_diff(NULL) > 2) {
611                                 if (stat_task->sa_time_diff_sign < 0)
612                                         tv_add(&stat_task->server_stream_start,
613                                                 &stat_task->sa_time_diff, &a_start);
614                                 else
615                                         tv_diff(&stat_task->server_stream_start,
616                                                 &stat_task->sa_time_diff, &a_start);
617                                 tv_add(&a_start, &delay, &initial_delay_barrier);
618                         }
619                 }
620                 break;
621         case SI_CURRENT_TIME:
622                 if (sscanf(buf, "%lu.%lu", &sec, &usec) == 2) {
623                         struct timeval tv = {sec, usec};
624                         compute_time_diff(&tv);
625                 }
626                 break;
627         case SI_FORMAT:
628                 stat_task->current_audio_format_num
629                         = get_audio_format_num(buf);
630         }
631         return 1;
632 }
633
634 static int parse_stream_command(const char *txt, char **cmd)
635 {
636         char *p = strchr(txt, ':');
637         int i;
638
639         if (!p)
640                 return -E_MISSING_COLON;
641         p++;
642         FOR_EACH_AUDIO_FORMAT(i) {
643                 if (strncmp(txt, audio_formats[i], strlen(audio_formats[i])))
644                         continue;
645                 *cmd = p;
646                 return i;
647         }
648         return -E_UNSUPPORTED_AUDIO_FORMAT;
649 }
650
651 static int add_filter(int format, char *cmdline)
652 {
653         struct audio_format_info *a = &afi[format];
654         int filter_num, nf = a->num_filters;
655
656         filter_num = check_filter_arg(cmdline, &a->filter_conf[nf]);
657         if (filter_num < 0)
658                 return filter_num;
659         a->filter_nums[nf] = filter_num;
660         a->num_filters++;
661         PARA_INFO_LOG("%s filter %d: %s\n", audio_formats[format], nf,
662                 filters[filter_num].name);
663         return filter_num;
664 }
665
666 static int parse_writer_args(void)
667 {
668         int i, ret, nw;
669         char *cmd;
670         struct audio_format_info *a;
671
672         nw = PARA_MAX(1U, conf.writer_given);
673         PARA_INFO_LOG("maximal number of writers: %d\n", nw);
674         FOR_EACH_AUDIO_FORMAT(i) {
675                 a = &afi[i];
676                 a->writer_conf = para_malloc(nw * sizeof(void *));
677                 a->writer_nums = para_malloc(nw * sizeof(int));
678                 a->num_writers = 0;
679         }
680         for (i = 0; i < conf.writer_given; i++) {
681                 void *wconf;
682                 int writer_num;
683                 ret = parse_stream_command(conf.writer_arg[i], &cmd);
684                 if (ret < 0)
685                         goto out;
686                 a = &afi[ret];
687                 nw = a->num_writers;
688                 wconf = check_writer_arg(cmd, &writer_num);
689                 if (!wconf) {
690                         ret = writer_num;
691                         goto out;
692                 }
693                 a->writer_nums[nw] = writer_num;
694                 a->writer_conf[nw] = wconf;
695                 PARA_INFO_LOG("%s writer #%d: %s\n", audio_formats[ret],
696                         nw, writer_names[writer_num]);
697                 a->num_writers++;
698         }
699         ret = 1;
700 out:
701         return ret;
702 }
703
704 static int parse_receiver_args(void)
705 {
706         int i, ret, receiver_num;
707         char *cmd = NULL;
708         struct audio_format_info *a;
709
710         for (i = conf.receiver_given - 1; i >= 0; i--) {
711                 char *arg = conf.receiver_arg[i];
712                 char *recv_arg = strchr(arg, ':');
713                 ret = -E_MISSING_COLON;
714                 if (!recv_arg)
715                         goto out;
716                 *recv_arg = '\0';
717                 recv_arg++;
718                 ret = get_audio_format_num(arg);
719                 if (ret < 0)
720                         goto out;
721                 afi[ret].receiver_conf = check_receiver_arg(recv_arg, &receiver_num);
722                 if (!afi[ret].receiver_conf) {
723                         ret = -E_RECV_SYNTAX;
724                         goto out;
725                 }
726                 afi[ret].receiver = &receivers[receiver_num];
727         }
728         /* use the first available receiver with no arguments
729          * for those audio formats for which no receiver
730          * was specified
731          */
732         cmd = para_strdup(receivers[0].name);
733         FOR_EACH_AUDIO_FORMAT(i) {
734                 a = &afi[i];
735                 if (a->receiver_conf)
736                         continue;
737                 a->receiver_conf = check_receiver_arg(cmd, &receiver_num);
738                 if (!a->receiver_conf)
739                         return -E_RECV_SYNTAX;
740                 a->receiver = &receivers[receiver_num];
741         }
742         ret = 1;
743 out:
744         free(cmd);
745         return ret;
746 }
747
748 static int init_default_filters(void)
749 {
750         int i, ret = 1;
751
752         FOR_EACH_AUDIO_FORMAT(i) {
753                 struct audio_format_info *a = &afi[i];
754                 char *tmp;
755                 int j;
756
757                 if (a->num_filters)
758                         continue; /* no default -- nothing to to */
759                 /* add "dec" to audio format name */
760                 tmp = make_message("%sdec", audio_formats[i]);
761                 for (j = 0; filters[j].name; j++)
762                         if (!strcmp(tmp, filters[j].name))
763                                 break;
764                 free(tmp);
765                 ret = -E_UNSUPPORTED_FILTER;
766                 if (!filters[j].name)
767                         goto out;
768                 tmp = para_strdup(filters[j].name);
769                 ret = add_filter(i, tmp);
770                 free(tmp);
771                 if (ret < 0)
772                         goto out;
773                 PARA_INFO_LOG("%s -> default filter: %s\n", audio_formats[i],
774                         filters[j].name);
775         }
776 out:
777         return ret;
778 }
779
780 static int parse_filter_args(void)
781 {
782         int i, ret, nf;
783
784         nf = PARA_MAX(1U, conf.filter_given);
785         PARA_INFO_LOG("maximal number of filters: %d\n", nf);
786         FOR_EACH_AUDIO_FORMAT(i) {
787                 afi[i].filter_conf = para_malloc(nf * sizeof(void *));
788                 afi[i].filter_nums = para_malloc(nf * sizeof(unsigned));
789         }
790         if (!conf.no_default_filters_given)
791                 return init_default_filters();
792         for (i = 0; i < conf.filter_given; i++) {
793                 char *arg = conf.filter_arg[i];
794                 char *filter_name = strchr(arg, ':');
795                 ret = -E_MISSING_COLON;
796                 if (!filter_name)
797                         goto out;
798                 *filter_name = '\0';
799                 filter_name++;
800                 ret = get_audio_format_num(arg);
801                 if (ret < 0)
802                         goto out;
803                 ret = add_filter(ret, filter_name);
804                 if (ret < 0)
805                         goto out;
806         }
807         ret = init_default_filters(); /* use default values for the rest */
808 out:
809         return ret;
810 }
811
812 static int parse_stream_args(void)
813 {
814         int ret;
815
816         ret = parse_receiver_args();
817         if (ret < 0)
818                 return ret;
819         ret = parse_filter_args();
820         if (ret < 0)
821                 return ret;
822         ret = parse_writer_args();
823         if (ret < 0)
824                 return ret;
825         return 1;
826 }
827
828 /* does not unlink socket on errors */
829 static int audiod_get_socket(void)
830 {
831         struct sockaddr_un unix_addr;
832         int ret, fd;
833
834         if (conf.socket_given)
835                 socket_name = para_strdup(conf.socket_arg);
836         else {
837                 char *hn = para_hostname();
838                 socket_name = make_message("/var/paraslash/audiod_socket.%s",
839                         hn);
840                 free(hn);
841         }
842         PARA_NOTICE_LOG("local socket: %s\n", socket_name);
843         if (conf.force_given)
844                 unlink(socket_name);
845         ret = create_local_socket(socket_name, &unix_addr,
846                 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IWOTH);
847         if (ret < 0)
848                 goto err;
849         fd = ret;
850         if (listen(fd , 5) < 0) {
851                 ret = -ERRNO_TO_PARA_ERROR(errno);
852                 goto err;
853         }
854         ret = mark_fd_nonblocking(fd);
855         if (ret < 0)
856                 goto err;
857         return fd;
858 err:
859         PARA_EMERG_LOG("%s\n", para_strerror(-ret));
860         exit(EXIT_FAILURE);
861 }
862
863 static void signal_pre_select(struct sched *s, struct task *t)
864 {
865         struct signal_task *st = container_of(t, struct signal_task, task);
866         para_fd_set(st->fd, &s->rfds, &s->max_fileno);
867 }
868
869 static void signal_post_select(struct sched *s, struct task *t)
870 {
871         struct signal_task *st = container_of(t, struct signal_task, task);
872
873         if (!FD_ISSET(st->fd, &s->rfds))
874                 return;
875
876         st->signum = para_next_signal();
877         switch (st->signum) {
878         case SIGINT:
879         case SIGTERM:
880         case SIGHUP:
881                 PARA_EMERG_LOG("terminating on signal %d\n", st->signum);
882                 clean_exit(EXIT_FAILURE, "caught deadly signal");
883         }
884 }
885
886 static void signal_setup_default(struct signal_task *st)
887 {
888         st->task.pre_select = signal_pre_select;
889         st->task.post_select = signal_post_select;
890         sprintf(st->task.status, "signal task");
891 }
892
893 static void command_pre_select(struct sched *s, struct task *t)
894 {
895         struct command_task *ct = container_of(t, struct command_task, task);
896         para_fd_set(ct->fd, &s->rfds, &s->max_fileno);
897 }
898
899 static void command_post_select(struct sched *s, struct task *t)
900 {
901         int ret;
902         struct command_task *ct = container_of(t, struct command_task, task);
903
904         audiod_status_dump();
905         if (!FD_ISSET(ct->fd, &s->rfds))
906                 return;
907         ret = handle_connect(ct->fd);
908         if (ret < 0)
909                 PARA_ERROR_LOG("%s\n", para_strerror(-ret));
910 }
911
912 static void init_command_task(struct command_task *ct)
913 {
914         ct->task.pre_select = command_pre_select;
915         ct->task.post_select = command_post_select;
916         ct->task.error = 0;
917         ct->fd = audiod_get_socket(); /* doesn't return on errors */
918         sprintf(ct->task.status, "command task");
919 }
920
921 static void close_stat_pipe(void)
922 {
923         if (!stat_task->ct)
924                 return;
925         client_close(stat_task->ct);
926         stat_task->ct = NULL;
927         clear_and_dump_items();
928         stat_task->length_seconds = 0;
929         stat_task->offset_seconds = 0;
930         stat_task->vss_status = 0;
931         audiod_status_dump();
932 }
933
934 /**
935  * close the connection to para_server and exit
936  *
937  * \param status the exit status which is passed to exit(3)
938  * \param msg the log message
939  *
940  * Log \a msg with loglevel \p EMERG, close the connection to para_server if
941  * open, and call \p exit(status). \a status should be either EXIT_SUCCESS or
942  * EXIT_FAILURE.
943  *
944  * \sa exit(3)
945  */
946 void __noreturn clean_exit(int status, const char *msg)
947 {
948         PARA_EMERG_LOG("%s\n", msg);
949         if (socket_name)
950                 unlink(socket_name);
951         close_stat_pipe();
952         exit(status);
953 }
954
955 /* avoid busy loop if server is down */
956 static void set_stat_task_restart_barrier(unsigned seconds)
957 {
958         struct timeval delay = {seconds, 0};
959         tv_add(now, &delay, &stat_task->restart_barrier);
960 }
961
962 static void try_to_close_slot(int slot_num)
963 {
964         struct slot_info *s = &slot[slot_num];
965
966         if (s->format < 0)
967                 return;
968         if (s->receiver_node && s->receiver_node->task.error != -E_TASK_UNREGISTERED)
969                 return;
970         if (s->fc && s->fc->task.error != -E_TASK_UNREGISTERED)
971                 return;
972         if (s->wng && s->wng->task.error != -E_TASK_UNREGISTERED)
973                 return;
974         PARA_INFO_LOG("closing slot %d\n", slot_num);
975         wng_close(s->wng);
976         close_filters(s->fc);
977         free(s->fc);
978         close_receiver(slot_num);
979         clear_slot(slot_num);
980 }
981
982 /*
983  * Check if any receivers/filters/writers need to be started and do so if
984  * necessary.
985  */
986 static void start_stop_decoders(struct sched *s)
987 {
988         int i;
989
990         FOR_EACH_SLOT(i)
991                 try_to_close_slot(i);
992         if (audiod_status != AUDIOD_ON ||
993                         !(stat_task->vss_status & VSS_STATUS_FLAG_PLAYING))
994                 return kill_all_decoders(-E_NOT_PLAYING);
995         open_current_receiver(s);
996         FOR_EACH_SLOT(i) {
997                 struct slot_info *sl = &slot[i];
998                 struct audio_format_info *a;
999                 struct timeval diff;
1000
1001                 if (sl->format < 0)
1002                         continue;
1003                 a = &afi[sl->format];
1004                 if (!sl->receiver_node)
1005                         continue;
1006                 if ((!a->num_filters || sl->fc) && sl->wng)
1007                         continue; /* everything already started */
1008                 if (!a->num_filters) {
1009                         if (sl->receiver_node->loaded && !sl->wng) {
1010                                 open_writers(i);
1011                         }
1012                         continue;
1013                 }
1014                 if (sl->receiver_node->loaded && !sl->fc) {
1015                         open_filters(i);
1016                         continue;
1017                 }
1018                 if (sl->wng || !sl->fc || !*sl->fc->out_loaded)
1019                         continue;
1020                 if (tv_diff(now, &initial_delay_barrier, &diff) > 0) {
1021                         open_writers(i);
1022                         continue;
1023                 }
1024                 PARA_INFO_LOG("initial delay: %lu ms left\n", tv2ms(&diff));
1025                 if (tv_diff(&s->timeout, &diff, NULL) > 0) {
1026                         s->timeout = diff;
1027                 }
1028         }
1029 }
1030
1031
1032 /* restart the client task if necessary */
1033 static void status_pre_select(struct sched *s, struct task *t)
1034 {
1035         struct status_task *st = container_of(t, struct status_task, task);
1036
1037         if (audiod_status == AUDIOD_OFF) {
1038                 if (!st->ct)
1039                         goto out;
1040                 if (st->ct->task.error >= 0) {
1041                         st->ct->task.error = -E_AUDIOD_OFF;
1042                         goto out;
1043                 }
1044                 if (st->ct->task.error != -E_TASK_UNREGISTERED)
1045                         goto out;
1046                 close_stat_pipe();
1047                 st->clock_diff_count = conf.clock_diff_count_arg;
1048                 goto out;
1049         }
1050         if (st->ct) {
1051                 int ret;
1052                 if (st->ct->task.error < 0) {
1053                         if (st->ct->task.error != -E_TASK_UNREGISTERED)
1054                                 goto out;
1055                         close_stat_pipe();
1056                         goto out;
1057                 }
1058                 if (st->ct->status != CL_RECEIVING)
1059                         goto out;
1060                 ret = for_each_stat_item(st->ct->buf, st->ct->loaded,
1061                         update_item);
1062                 if (ret < 0) {
1063                         st->ct->task.error = ret;
1064                         goto out;
1065                 }
1066                 if (st->ct->loaded != ret) {
1067                         st->last_status_read = *now;
1068                         st->ct->loaded = ret;
1069                 } else {
1070                         struct timeval diff;
1071                         tv_diff(now, &st->last_status_read, &diff);
1072                         if (diff.tv_sec > 61)
1073                                 st->ct->task.error = -E_STATUS_TIMEOUT;
1074                 }
1075                 goto out;
1076         }
1077         if (tv_diff(now, &st->restart_barrier, NULL) < 0)
1078                 goto out;
1079         if (st->clock_diff_count) { /* get status only one time */
1080                 char *argv[] = {"audiod", "--", "stat", "-p", "1", NULL};
1081                 int argc = 5;
1082                 PARA_INFO_LOG("clock diff count: %d\n", st->clock_diff_count);
1083                 st->clock_diff_count--;
1084                 client_open(argc, argv, &st->ct, NULL);
1085                 set_stat_task_restart_barrier(2);
1086
1087         } else {
1088                 char *argv[] = {"audiod", "--", "stat", "-p", NULL};
1089                 int argc = 4;
1090                 client_open(argc, argv, &st->ct, NULL);
1091                 set_stat_task_restart_barrier(5);
1092         }
1093         free(stat_item_values[SI_BASENAME]);
1094         stat_item_values[SI_BASENAME] = para_strdup(
1095                 "no connection to para_server");
1096         stat_client_write_item(SI_BASENAME);
1097         st->last_status_read = *now;
1098 out:
1099         start_stop_decoders(s);
1100 }
1101
1102 static void init_status_task(struct status_task *st)
1103 {
1104         memset(st, 0, sizeof(struct status_task));
1105         st->task.pre_select = status_pre_select;
1106         st->sa_time_diff_sign = 1;
1107         st->clock_diff_count = conf.clock_diff_count_arg;
1108         st->current_audio_format_num = -1;
1109         sprintf(st->task.status, "status task");
1110 }
1111
1112 static void set_initial_status(void)
1113 {
1114         audiod_status = AUDIOD_ON;
1115         if (!conf.mode_given)
1116                 return;
1117         if (!strcmp(conf.mode_arg, "sb")) {
1118                 audiod_status = AUDIOD_STANDBY;
1119                 return;
1120         }
1121         if (!strcmp(conf.mode_arg, "off")) {
1122                 audiod_status = AUDIOD_OFF;
1123                 return;
1124         }
1125         if (strcmp(conf.mode_arg, "on"))
1126                 PARA_WARNING_LOG("invalid mode\n");
1127 }
1128
1129 __noreturn static void print_help_and_die(void)
1130 {
1131         int d = conf.detailed_help_given;
1132         const char **p = d? audiod_args_info_detailed_help
1133                 : audiod_args_info_help;
1134
1135         printf_or_die("%s\n\n", AUDIOD_CMDLINE_PARSER_PACKAGE "-"
1136                 AUDIOD_CMDLINE_PARSER_VERSION);
1137         printf_or_die("%s\n\n", audiod_args_info_usage);
1138         for (; *p; p++)
1139                 printf_or_die("%s\n", *p);
1140         print_receiver_helps(d);
1141         print_filter_helps(d);
1142         print_writer_helps(d);
1143         exit(0);
1144 }
1145
1146 static void init_colors_or_die(void)
1147 {
1148         int ret, i;
1149
1150         if (!want_colors())
1151                 return;
1152         daemon_set_default_log_colors();
1153         daemon_set_flag(DF_COLOR_LOG);
1154         for (i = 0; i < conf.log_color_given; i++) {
1155                 ret = daemon_set_log_color(conf.log_color_arg[i]);
1156                 if (ret < 0)
1157                         exit(EXIT_FAILURE);
1158         }
1159 }
1160
1161 /**
1162  * the main function of para_audiod
1163  *
1164  * \param argc usual argument count
1165  * \param argv usual argument vector
1166  *
1167  * \return EXIT_SUCCESS or EXIT_FAILURE
1168  *
1169  * \sa para_audiod(1)
1170  * */
1171 int main(int argc, char *argv[])
1172 {
1173         int ret, i;
1174         static struct sched s;
1175         struct command_task command_task_struct, *cmd_task = &command_task_struct;
1176         struct audiod_cmdline_parser_params params = {
1177                 .override = 0,
1178                 .initialize = 1,
1179                 .check_required = 0,
1180                 .check_ambiguity = 0,
1181                 .print_errors = 1
1182         };
1183
1184         valid_fd_012();
1185         if (audiod_cmdline_parser_ext(argc, argv, &conf, &params))
1186                 exit(EXIT_FAILURE);
1187         HANDLE_VERSION_FLAG("audiod", conf);
1188         /* init receivers/filters/writers early to make help work */
1189         recv_init();
1190         filter_init();
1191         writer_init();
1192         if (conf.help_given || conf.detailed_help_given)
1193                 print_help_and_die();
1194         drop_privileges_or_die(conf.user_arg, conf.group_arg);
1195         parse_config_or_die();
1196         init_colors_or_die();
1197         daemon_set_flag(DF_LOG_TIME);
1198         daemon_set_flag(DF_LOG_HOSTNAME);
1199         daemon_set_flag(DF_LOG_LL);
1200         if (conf.logfile_given) {
1201                 daemon_set_logfile(conf.logfile_arg);
1202                 daemon_open_log_or_die();
1203         }
1204         ret = parse_stream_args();
1205         if (ret < 0) {
1206                 PARA_EMERG_LOG("%s\n", para_strerror(-ret));
1207                 exit(EXIT_FAILURE);
1208         }
1209         log_welcome("para_audiod");
1210         server_uptime(UPTIME_SET);
1211         set_initial_status();
1212         FOR_EACH_SLOT(i)
1213                 clear_slot(i);
1214         init_grabbing();
1215         setup_signal_handling();
1216         signal_setup_default(sig_task);
1217
1218         init_status_task(stat_task);
1219         init_command_task(cmd_task);
1220
1221         if (conf.daemon_given)
1222                 daemonize();
1223
1224         register_task(&sig_task->task);
1225         register_task(&cmd_task->task);
1226         register_task(&stat_task->task);
1227         s.default_timeout.tv_sec = 0;
1228         s.default_timeout.tv_usec = 99 * 1000;
1229         ret = schedule(&s);
1230
1231         PARA_EMERG_LOG("%s\n", para_strerror(-ret));
1232         return EXIT_FAILURE;
1233 }