Fix use of uninitialized afhi->header_len.
[paraslash.git] / audiod.c
index f83943a682f5c86496f1bd6efe1cd6b265443268..6fd8eef15a5b3c5f0c07c16795155daa63691ddc 100644 (file)
--- a/audiod.c
+++ b/audiod.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005-2007 Andre Noll <maan@systemlinux.org>
+ * Copyright (C) 2005-2008 Andre Noll <maan@systemlinux.org>
  *
  * Licensed under the GPL v2. For licencing details see COPYING.
  */
@@ -144,6 +144,8 @@ void para_log(int ll, const char* fmt,...)
 
        if (ll < conf.loglevel_arg)
                return;
+       if (!logfile && conf.daemon_given)
+               return;
        if (!hostname)
                hostname = para_hostname();
        outfd = logfile? logfile : stderr;
@@ -264,7 +266,7 @@ int num_filters(int audio_format_num)
 
 static void filter_event_handler(struct task *t)
 {
-       PARA_NOTICE_LOG("%s\n", PARA_STRERROR(-t->ret));
+       PARA_NOTICE_LOG("%s\n", para_strerror(-t->ret));
        struct filter_chain *fc = t->private_data;
        fc->error = t->ret;
        unregister_task(t);
@@ -314,7 +316,7 @@ static void wng_event_handler(struct task *t)
 {
        struct writer_node_group *wng = t->private_data;
 
-       PARA_INFO_LOG("%s\n", PARA_STRERROR(-t->ret));
+       PARA_INFO_LOG("%s\n", para_strerror(-t->ret));
        wng->error = t->ret;
        wng_unregister(wng);
 }
@@ -350,7 +352,7 @@ static void open_writers(int slot_num)
        }
        ret = wng_open(s->wng);
        if (ret < 0) {
-               PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
+               PARA_ERROR_LOG("%s\n", para_strerror(-ret));
                return;
        }
        s->wstime = *now;
@@ -362,7 +364,7 @@ static void rn_event_handler(struct task *t)
        struct receiver_node *rn = t->private_data;
        int i;
 
-       PARA_NOTICE_LOG("%s\n", PARA_STRERROR(-t->ret));
+       PARA_NOTICE_LOG("%s\n", para_strerror(-t->ret));
        unregister_task(t);
        rn->error = t->ret;
        /* set restart barrier */
@@ -411,7 +413,7 @@ static int open_receiver(int format)
        register_task(&rn->task);
        return 1;
 err:
-       PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
+       PARA_ERROR_LOG("%s\n", para_strerror(-ret));
        tv_add(now, &restart_delay, &afi[format].restart_barrier);
        return ret;
 }
@@ -431,23 +433,18 @@ static int receiver_running(int format)
 
 static int open_current_receiver(struct sched *s)
 {
-       int i;
        struct timeval diff;
-       char *audio_format = stat_task->stat_item_values[SI_FORMAT];
+       int cafn = stat_task->current_audio_format_num;
 
-       if (!audio_format || !stat_task->pcd)
-               return 0;
-       i = get_audio_format_num(audio_format + strlen(
-               status_item_list[SI_FORMAT]) + 1);
-       if (i < 0)
+       if (cafn < 0 || !stat_task->pcd)
                return 0;
-       if (receiver_running(i))
+       if (receiver_running(cafn))
                return 0;
-       if (tv_diff(now, &afi[i].restart_barrier, &diff) < 0) {
+       if (tv_diff(now, &afi[cafn].restart_barrier, &diff) < 0) {
                s->timeout = diff;
                return 0;
        }
-       return open_receiver(i) < 0? 0 : 1;
+       return open_receiver(cafn) < 0? 0 : 1;
 }
 
 static unsigned compute_time_diff(const struct timeval *status_time)
@@ -551,6 +548,9 @@ static int check_stat_line(char *line, __a_unused void *data)
                if (stat_task->clock_diff_count)
                        stat_task->clock_diff_count--;
                break;
+       case SI_FORMAT:
+               stat_task->current_audio_format_num = get_audio_format_num(
+                       line + ilen + 1);
        }
        return 1;
 }
@@ -601,6 +601,8 @@ static void audiod_pre_select(struct sched *s, __a_unused struct task *t)
                a = &afi[sl->format];
                if (!sl->receiver_node)
                        continue;
+               if ((!a->num_filters || sl->fc) && sl->wng)
+                       continue; /* everything already started */
                if (!a->num_filters) {
                        if (sl->receiver_node->loaded && !sl->wng) {
                                open_writers(i);
@@ -613,7 +615,7 @@ static void audiod_pre_select(struct sched *s, __a_unused struct task *t)
                        s->timeout = min_delay;
                        continue;
                }
-               if (!sl->fc || !*sl->fc->out_loaded || sl->wng)
+               if (sl->wng || !sl->fc || !*sl->fc->out_loaded)
                        continue;
                if (tv_diff(now, &initial_delay_barrier, &diff) > 0) {
                        open_writers(i);
@@ -846,10 +848,11 @@ static int init_stream_io(void)
        return 1;
 }
 
+/* does not unlink socket on errors */
 static int audiod_get_socket(void)
 {
        struct sockaddr_un unix_addr;
-       int fd;
+       int ret, fd;
 
        if (conf.socket_given)
                socket_name = para_strdup(conf.socket_arg);
@@ -862,18 +865,22 @@ static int audiod_get_socket(void)
        PARA_NOTICE_LOG("local socket: %s\n", socket_name);
        if (conf.force_given)
                unlink(socket_name);
-       fd = create_local_socket(socket_name, &unix_addr,
-                       S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IWOTH);
-       if (fd < 0) {
-               PARA_EMERG_LOG("can not connect to socket\n");
-               exit(EXIT_FAILURE); /* do not unlink socket */
-       }
+       ret = create_local_socket(socket_name, &unix_addr,
+               S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IWOTH);
+       if (ret < 0)
+               goto err;
+       fd = ret;
        if (listen(fd , 5) < 0) {
-               PARA_EMERG_LOG("can not listen on socket\n");
-               exit(EXIT_FAILURE); /* do not unlink socket */
+               ret = -ERRNO_TO_PARA_ERROR(errno);
+               goto err;
        }
-       mark_fd_nonblocking(fd);
+       ret = mark_fd_nonblocking(fd);
+       if (ret < 0)
+               goto err;
        return fd;
+err:
+       PARA_EMERG_LOG("%s\n", para_strerror(-ret));
+       exit(EXIT_FAILURE);
 }
 
 static void signal_event_handler(struct task *t)
@@ -933,7 +940,7 @@ static void command_post_select(struct sched *s, struct task *t)
                return;
        ret = handle_connect(ct->fd);
        if (ret < 0)
-               PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
+               PARA_ERROR_LOG("%s\n", para_strerror(-ret));
 }
 
 static void init_command_task(struct command_task *ct)
@@ -1084,6 +1091,7 @@ static void init_status_task(struct status_task *st)
        st->task.private_data = st;
        st->sa_time_diff_sign = 1;
        st->clock_diff_count = conf.clock_diff_count_arg;
+       st->current_audio_format_num = -1;
        sprintf(st->task.status, "status task");
 }
 
@@ -1101,7 +1109,7 @@ static void set_initial_status(void)
                return;
        }
        if (strcmp(conf.mode_arg, "on"))
-               PARA_WARNING_LOG("%s", "invalid mode\n");
+               PARA_WARNING_LOG("invalid mode\n");
 }
 
 /**
@@ -1136,7 +1144,7 @@ int main(int argc, char *argv[])
 
                };
                if (audiod_cmdline_parser_config_file(config_file, &conf, &params)) {
-                       PARA_EMERG_LOG("%s", "parse error in config file\n");
+                       PARA_EMERG_LOG("parse error in config file\n");
                        exit(EXIT_FAILURE);
                }
                free(config_file);
@@ -1146,7 +1154,7 @@ int main(int argc, char *argv[])
        log_welcome("para_audiod", conf.loglevel_arg);
        i = init_stream_io();
        if (i < 0) {
-               PARA_EMERG_LOG("init stream io error: %s\n", PARA_STRERROR(-i));
+               PARA_EMERG_LOG("init stream io error: %s\n", para_strerror(-i));
                exit(EXIT_FAILURE);
        }
        server_uptime(UPTIME_SET);
@@ -1173,6 +1181,6 @@ int main(int argc, char *argv[])
        s.default_timeout.tv_usec = 99 * 1000;
        ret = schedule(&s);
 
-       PARA_EMERG_LOG("%s\n", PARA_STRERROR(-ret));
+       PARA_EMERG_LOG("%s\n", para_strerror(-ret));
        return EXIT_FAILURE;
 }