* the gengetopt args_info struct that holds information on all command line
* arguments
*/
-struct audiod_args_info conf;
+static struct audiod_args_info conf;
static char *socket_name;
static struct audio_format_info afi[NUM_AUDIO_FORMATS];
*/
char *get_time_string(void)
{
- int ret, seconds = 0, length;
+ int ret, seconds = 0, length = stat_task->length_seconds;
struct timeval *tmp, sum, sss, /* server stream start */
rstime, /* receiver start time */
wstime, /* writer start time */
if (audiod_status == AUDIOD_OFF)
goto empty;
- if (!(stat_task->vss_status & VSS_STATUS_FLAG_PLAYING)) {
- if (stat_task->length_seconds) /* paused */
+ if (stat_task->server_stream_start.tv_sec == 0) {
+ if (stat_task->vss_status & VSS_STATUS_FLAG_PLAYING)
+ goto out; /* server is about to change file */
+ if (length > 0) /* paused */
return NULL;
goto empty; /* stopped */
}
- if (audiod_status == AUDIOD_ON && !s)
- goto empty;
/*
* Valid status items and playing, set length and tmp to the stream
* start. We use the slot info and fall back to the info from current
* status items if no slot info is available.
*/
- length = stat_task->length_seconds;
tmp = &stat_task->server_stream_start;
if (s && s->wns && s->wns[0].btrn) { /* writer active in this slot */
btr_get_node_start(s->wns[0].btrn, &wstime);
tv_diff(tmp, &stat_task->sa_time_diff, &sss);
else
tv_add(tmp, &stat_task->sa_time_diff, &sss);
- if (!s || !s->wns || !s->wns[0].btrn) {
+ if (!s || !s->wns || !s->wns[0].btrn || wstime.tv_sec == 0) {
struct timeval diff;
tv_diff(now, &sss, &diff);
seconds = diff.tv_sec + stat_task->offset_seconds;
if (s->receiver_node->btrn) {
btr_get_node_start(s->receiver_node->btrn, &rstime);
ret = tv_diff(&rstime, &sss, &rskip);
- if (ret > 0) { /* audiod was started in the middle of the stream */
+ if (ret > 0 && rskip.tv_sec > 2) {
+ /* audiod was started in the middle of the stream */
tv_add(&wtime, &rskip, &sum);
seconds += sum.tv_sec;
} else
EMBRACE(.name = f->name, .parent = parent,
.handler = f->execute, .context = fn));
- f->open(fn);
+ if (f->open)
+ f->open(fn);
sprintf(buf, "%s (slot %d)", f->name, (int)(s - slot));
fn->task = task_register(&(struct task_info) {
.name = buf,
unlink(socket_name);
ct->fd[0] = create_local_socket(socket_name, 0);
ct->fd[1] = create_local_socket(socket_name,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IWOTH);
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
if (ct->fd[0] >= 0 || ct->fd[1] >= 0)
return;
PARA_EMERG_LOG("%s\n", para_strerror(-ct->fd[1]));
for (i = 0; i < 2; i++) {
if (ct->fd[i] < 0)
continue;
- ret = handle_connect(ct->fd[i], &s->rfds, uid_whitelist);
+ ret = handle_connect(ct->fd[i], &s->rfds);
if (ret < 0) {
PARA_ERROR_LOG("%s\n", para_strerror(-ret));
if (ret == -E_AUDIOD_TERM) {
static void close_unused_slots(void)
{
int i;
+ bool dump = false;
FOR_EACH_SLOT(i)
- if (must_close_slot(i))
+ if (must_close_slot(i)) {
close_slot(i);
+ dump = true;
+ }
+ if (dump)
+ audiod_status_dump(true);
}
/*
open_writers(sl);
activate_grab_clients(&sched);
btr_log_tree(sl->receiver_node->btrn, LL_NOTICE);
+ audiod_status_dump(true);
}
static void status_pre_select(struct sched *s, void *context)
exit(0);
}
+/**
+ * Lookup the given UID in the whitelist.
+ *
+ * The whitelist is the array of arguments to the --user-allow opion. If the
+ * option was not given, the array is empty, in which case the check succeeds.
+ *
+ * \param uid User ID to look up.
+ *
+ * \return True if --user-allow was not given, or if uid matches an element of
+ * the whitelist.
+ */
+bool uid_is_whitelisted(uid_t uid)
+{
+ int i;
+
+ if (!conf.user_allow_given)
+ return true;
+ for (i = 0; i < conf.user_allow_given; i++)
+ if (uid == uid_whitelist[i])
+ return true;
+ return false;
+}
+
/**
* the main function of para_audiod
*
daemon_set_priority(conf.priority_arg);
daemon_drop_privileges_or_die(conf.user_arg, conf.group_arg);
parse_config_or_die();
- daemon_init_colors_or_die(conf.color_arg, color_arg_auto, color_arg_no,
- conf.logfile_given, conf.log_color_arg, conf.log_color_given);
+ if (daemon_init_colors_or_die(conf.color_arg, color_arg_auto, color_arg_no,
+ conf.logfile_given)) {
+ for (i = 0; i < conf.log_color_given; i++)
+ daemon_set_log_color_or_die(conf.log_color_arg[i]);
+ }
init_random_seed_or_die();
daemon_set_flag(DF_LOG_TIME);
daemon_set_flag(DF_LOG_HOSTNAME);