Move struct status_task from audiod.h to audiod.c.
[paraslash.git] / audiod.c
index a92c4e3b1ebca665a3804bc168472673fd733037..3194501bfc7e6e0a5e687842be70a57cb84e76b2 100644 (file)
--- a/audiod.c
+++ b/audiod.c
@@ -66,6 +66,39 @@ struct audio_format_info {
  * */
 struct slot_info slot[MAX_STREAM_SLOTS];
 
+/**
+ * The task for obtaining para_server's status (para_client stat).
+ *
+ * \sa struct task, struct sched.
+ */
+struct status_task {
+       /** The associated task structure of audiod. */
+       struct task task;
+       /** Client data associated with the stat task. */
+       struct client_task *ct;
+       /** Do not restart client command until this time. */
+       struct timeval restart_barrier;
+       /** Last time we received status data from para_server. */
+       struct timeval last_status_read;
+       /** The offset value announced by para_server. */
+       int offset_seconds;
+       /** The length of the current audio file as announced by para_server. */
+       int length_seconds;
+       /** The start of the current stream from the view of para_server. */
+       struct timeval server_stream_start;
+       /** The average time deviation between para_server and para_audiod. */
+       struct timeval sa_time_diff;
+       /** Whether client time is ahead of server time. */
+       int sa_time_diff_sign;
+       /** Non-zero if para_server's status is "playing". */
+       int playing;
+       /** Number of times the clock difference is to be checked. */
+       unsigned clock_diff_count;
+       /** When to start the next check for clock difference. */
+       struct timeval clock_diff_barrier;
+       /** Number of the audio format as announced by para_server. */
+       int current_audio_format_num;
+};
 
 /** The array of status items sent by para_server. */
 char *stat_item_values[NUM_STAT_ITEMS] = {NULL};
@@ -193,6 +226,7 @@ static int want_colors(void)
 
 static void parse_config_or_die(void)
 {
+       int ret;
        char *config_file;
        struct audiod_cmdline_parser_params params = {
                .override = 0,
@@ -209,14 +243,13 @@ static void parse_config_or_die(void)
                config_file = make_message("%s/.paraslash/audiod.conf", home);
                free(home);
        }
-       if (conf.config_file_given && !file_exists(config_file)) {
+       ret = file_exists(config_file);
+       if (conf.config_file_given && !ret) {
                PARA_EMERG_LOG("can not read config file %s\n", config_file);
                goto err;
        }
-       if (audiod_cmdline_parser_config_file(config_file, &conf, &params)) {
-               PARA_EMERG_LOG("parse error in config file\n");
-               goto err;
-       }
+       if (ret)
+               audiod_cmdline_parser_config_file(config_file, &conf, &params);
        free(config_file);
        daemon_set_loglevel(conf.loglevel_arg);
        return;
@@ -596,13 +629,12 @@ static int add_filter(int format, char *cmdline)
        return filter_num;
 }
 
-static int init_writers(void)
+static int parse_writer_args(void)
 {
        int i, ret, nw;
        char *cmd;
        struct audio_format_info *a;
 
-       init_supported_writers();
        nw = PARA_MAX(1U, conf.writer_given);
        PARA_INFO_LOG("maximal number of writers: %d\n", nw);
        FOR_EACH_AUDIO_FORMAT(i) {
@@ -635,16 +667,12 @@ out:
        return ret;
 }
 
-static int init_receivers(void)
+static int parse_receiver_args(void)
 {
        int i, ret, receiver_num;
        char *cmd = NULL;
        struct audio_format_info *a;
 
-       for (i = 0; receivers[i].name; i++) {
-               PARA_INFO_LOG("initializing %s receiver\n", receivers[i].name);
-               receivers[i].init(&receivers[i]);
-       }
        for (i = conf.receiver_given - 1; i >= 0; i--) {
                char *arg = conf.receiver_arg[i];
                char *recv_arg = strchr(arg, ':');
@@ -715,11 +743,10 @@ out:
        return ret;
 }
 
-static int init_filters(void)
+static int parse_filter_args(void)
 {
        int i, ret, nf;
 
-       filter_init(filters);
        nf = PARA_MAX(1U, conf.filter_given);
        PARA_INFO_LOG("maximal number of filters: %d\n", nf);
        FOR_EACH_AUDIO_FORMAT(i) {
@@ -748,17 +775,17 @@ out:
        return ret;
 }
 
-static int init_stream_io(void)
+static int parse_stream_args(void)
 {
        int ret;
 
-       ret = init_writers();
+       ret = parse_receiver_args();
        if (ret < 0)
                return ret;
-       ret = init_receivers();
+       ret = parse_filter_args();
        if (ret < 0)
                return ret;
-       ret = init_filters();
+       ret = parse_writer_args();
        if (ret < 0)
                return ret;
        return 1;
@@ -1021,13 +1048,13 @@ static void status_pre_select(struct sched *s, struct task *t)
                int argc = 3;
                PARA_INFO_LOG("clock diff count: %d\n", st->clock_diff_count);
                st->clock_diff_count--;
-               client_open(argc, argv, &st->ct);
+               client_open(argc, argv, &st->ct, NULL);
                set_stat_task_restart_barrier(2);
 
        } else {
                char *argv[] = {"audiod", "stat", NULL};
                int argc = 2;
-               client_open(argc, argv, &st->ct);
+               client_open(argc, argv, &st->ct, NULL);
                set_stat_task_restart_barrier(5);
        }
        free(stat_item_values[SI_BASENAME]);
@@ -1124,12 +1151,18 @@ int main(int argc, char *argv[])
        };
 
        valid_fd_012();
-       audiod_cmdline_parser_ext(argc, argv, &conf, &params);
+       if (audiod_cmdline_parser_ext(argc, argv, &conf, &params))
+               exit(EXIT_FAILURE);
        HANDLE_VERSION_FLAG("audiod", conf);
-       drop_privileges_or_die(conf.user_arg, conf.group_arg);
-       parse_config_or_die();
+       /* init receivers/filters/writers early to make help work */
+       recv_init();
+       filter_init();
+       writer_init();
        if (conf.help_given || conf.detailed_help_given)
                print_help_and_die();
+       drop_privileges_or_die(conf.user_arg, conf.group_arg);
+       parse_config_or_die();
+       init_colors_or_die();
        daemon_set_flag(DF_LOG_TIME);
        daemon_set_flag(DF_LOG_HOSTNAME);
        daemon_set_flag(DF_LOG_LL);
@@ -1137,10 +1170,9 @@ int main(int argc, char *argv[])
                daemon_set_logfile(conf.logfile_arg);
                daemon_open_log_or_die();
        }
-       init_colors_or_die();
-       i = init_stream_io();
-       if (i < 0) {
-               PARA_EMERG_LOG("init stream io error: %s\n", para_strerror(-i));
+       ret = parse_stream_args();
+       if (ret < 0) {
+               PARA_EMERG_LOG("%s\n", para_strerror(-ret));
                exit(EXIT_FAILURE);
        }
        log_welcome("para_audiod");