X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=audiod_command.c;h=3467dbe1a1990c566b353c7450a828828996bdbc;hp=349480ff1f34f5a9bfebe57f26ddad6f0aef93ce;hb=1583369f6defebc7f44249b9ce4cc01f717db3b9;hpb=101e1fd3252d838458a6ad4015f497818c54c897 diff --git a/audiod_command.c b/audiod_command.c index 349480ff..3467dbe1 100644 --- a/audiod_command.c +++ b/audiod_command.c @@ -1,29 +1,20 @@ /* - * Copyright (C) 2005-2007 Andre Noll + * Copyright (C) 2005-2009 Andre Noll * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + * Licensed under the GPL v2. For licencing details see COPYING. */ /** \file audiod_command.c commands for para_audiod */ -#include "para.h" +#include +#include +#include "para.h" #include "audiod.cmdline.h" #include "list.h" #include "close_on_fork.h" #include "sched.h" +#include "ggo.h" #include "filter.h" #include "grab_client.cmdline.h" #include "grab_client.h" @@ -36,6 +27,9 @@ #include "fd.h" #include "audiod_command_list.h" +extern char *stat_item_values[NUM_STAT_ITEMS]; + + /** iterate over the array of all audiod commands */ #define FOR_EACH_COMMAND(c) for (c = 0; audiod_cmds[c].name; c++) @@ -45,76 +39,29 @@ static int client_write(int fd, const char *buf) return write(fd, buf, len) != len? -E_CLIENT_WRITE: 1; } -static char *get_time_string(struct timeval *newest_stime) -{ - struct timeval diff, adj_stream_start, tmp; - int total = 0, use_server_time = 1, - length_seconds = stat_task->length_seconds; - - if (!stat_task->playing) { - if (length_seconds) - return NULL; - return make_message("%s:\n", status_item_list[SI_PLAY_TIME]); - } - if (audiod_status == AUDIOD_OFF) - goto out; - if (stat_task->sa_time_diff_sign > 0) - tv_diff(&stat_task->server_stream_start, &stat_task->sa_time_diff, - &adj_stream_start); - else - tv_add(&stat_task->server_stream_start, &stat_task->sa_time_diff, - &adj_stream_start); - tmp = adj_stream_start; - if (newest_stime && audiod_status == AUDIOD_ON) { - tv_diff(newest_stime, &adj_stream_start, &diff); - if (tv2ms(&diff) < 5000) { - tmp = *newest_stime; - use_server_time = 0; - } - } - tv_diff(now, &tmp, &diff); - total = diff.tv_sec + stat_task->offset_seconds; - if (total > length_seconds) - total = length_seconds; - if (total < 0) - total = 0; -out: - return make_message( - "%s:%s%d:%02d [%d:%02d] (%d%%/%d:%02d)\n", - status_item_list[SI_PLAY_TIME], - use_server_time? "~" : "", - total / 60, - total % 60, - (length_seconds - total) / 60, - (length_seconds - total) % 60, - length_seconds? (total * 100 + length_seconds / 2) / - length_seconds : 0, - length_seconds / 60, - length_seconds % 60 - ); -} - __malloc static char *audiod_status_string(void) { const char *status = (audiod_status == AUDIOD_ON)? "on" : (audiod_status == AUDIOD_OFF)? "off": "sb"; - return make_message("%s:%s\n", status_item_list[SI_AUDIOD_STATUS], status); + return make_message("%s: %s\n", status_item_list[SI_AUDIOD_STATUS], status); } -static struct timeval *wstime(void) +static int get_play_time_slot_num(void) { - int i; - struct timeval *max = NULL; + int i, oldest = -1; + FOR_EACH_SLOT(i) { struct slot_info *s = &slot[i]; if (!s->wng) continue; - if (max && tv_diff(&s->wstime, max, NULL) <= 0) + if (oldest >= 0 && tv_diff(&s->wstime, &slot[oldest].wstime, + NULL) > 0) continue; - max = &s->wstime; + oldest = i; } - return max; + return oldest; } + __malloc static char *decoder_flags(void) { int i; @@ -130,7 +77,7 @@ __malloc static char *decoder_flags(void) flags[i] = flag; } flags[MAX_STREAM_SLOTS] = '\0'; - return make_message("%s:%s\n", status_item_list[SI_DECODER_FLAGS], + return make_message("%s: %s\n", status_item_list[SI_DECODER_FLAGS], flags); } @@ -236,8 +183,8 @@ int com_stat(int fd, __a_unused int argc, __a_unused char **argv) } PARA_INFO_LOG("mask: 0x%lx\n", mask); if (mask & (1 << SI_PLAY_TIME)) { - struct timeval *t = wstime(); - char *ts = get_time_string(t); + int slot_num = get_play_time_slot_num(); + char *ts = get_time_string(slot_num); if (ts) { ret = client_write(fd, ts); if (ret < 0) @@ -247,7 +194,7 @@ int com_stat(int fd, __a_unused int argc, __a_unused char **argv) } if (mask & (1 << SI_AUDIOD_UPTIME)) { char *tmp, *us = uptime_str(); - tmp = make_message("%s:%s\n", + tmp = make_message("%s: %s\n", status_item_list[SI_AUDIOD_UPTIME], us); free(us); ret = client_write(fd, tmp); @@ -263,18 +210,17 @@ int com_stat(int fd, __a_unused int argc, __a_unused char **argv) free(s); } if (mask & (1 << SI_DECODER_FLAGS)) { - char *df =decoder_flags(); + char *df = decoder_flags(); ret = client_write(fd, df); if (ret < 0) goto out; free(df); } - - for (i = 0; i < NUM_STAT_ITEMS; i++) { + FOR_EACH_STATUS_ITEM(i) { char *tmp, *v; if (!((1 << i) & mask)) continue; - v = stat_task->stat_item_values[i]; + v = stat_item_values[i]; tmp = make_message("%s%s%s", buf? buf: "", v? v : "", v? "\n" : ""); free(buf); @@ -290,8 +236,7 @@ out: static struct filter_node *find_filter_node(int slot_num, int format, int filternum) { - struct filter_node *fn; - int i, j; + int i; FOR_EACH_SLOT(i) { struct slot_info *s = &slot[i]; @@ -301,14 +246,10 @@ static struct filter_node *find_filter_node(int slot_num, int format, int filter continue; if (format >= 0 && s->format != format) continue; - if (num_filters(i) < filternum) + if (num_filters(i) <= filternum) continue; /* success */ - j = 1; - list_for_each_entry(fn, &s->fc->filters, node) - if (filternum <= 0 || j++ == filternum) - break; - return fn; + return s->fc->filter_nodes + filternum; } return NULL; } @@ -350,7 +291,7 @@ err_out: return 1; } -int __noreturn com_term(int fd, __a_unused int argc, __a_unused char **argv) +__noreturn int com_term(int fd, __a_unused int argc, __a_unused char **argv) { close(fd); clean_exit(EXIT_SUCCESS, "terminating on user request"); @@ -426,6 +367,7 @@ int handle_connect(int accept_fd) int i, argc, ret, clifd = -1; char *cmd = NULL, *p, *buf = para_calloc(MAXLINE), **argv = NULL; struct sockaddr_un unix_addr; + uid_t uid; ret = para_accept(accept_fd, &unix_addr, sizeof(struct sockaddr_un)); if (ret < 0) @@ -434,11 +376,11 @@ int handle_connect(int accept_fd) ret = recv_cred_buffer(clifd, buf, MAXLINE - 1); if (ret < 0) goto out; + uid = ret; PARA_INFO_LOG("connection from user %i, buf: %s\n", ret, buf); - ret = check_perms(ret); + ret = check_perms(uid); if (ret < 0) goto out; - ret = -E_INVALID_AUDIOD_CMD; cmd = para_strdup(buf); p = strchr(cmd, '\n'); if (!p) @@ -470,56 +412,59 @@ out: free(buf); free(argv); if (clifd > 0 && ret < 0 && ret != -E_CLIENT_WRITE) { - char *tmp = make_message("%s\n", PARA_STRERROR(-ret)); + char *tmp = make_message("%s\n", para_strerror(-ret)); client_write(clifd, tmp); free(tmp); close(clifd); } return ret; } - +/** + * send the current audiod status to all connected stat clients + */ void audiod_status_dump(void) { - struct timeval *t = wstime(); + int slot_num = get_play_time_slot_num(); char *old, *new, *tmp; - old = stat_task->stat_item_values[SI_PLAY_TIME]; - new = get_time_string(t); + old = stat_item_values[SI_PLAY_TIME]; + new = get_time_string(slot_num); if (new) { if (!old || strcmp(old, new)) { free(old); stat_client_write(new, SI_PLAY_TIME); - stat_task->stat_item_values[SI_PLAY_TIME] = new; + stat_item_values[SI_PLAY_TIME] = new; } else free(new); } new = uptime_str(); - old = stat_task->stat_item_values[SI_AUDIOD_UPTIME]; + old = stat_item_values[SI_AUDIOD_UPTIME]; if (!old || strcmp(old, new)) { free(old); - tmp = make_message("%s:%s\n", + tmp = make_message("%s: %s\n", status_item_list[SI_AUDIOD_UPTIME], new); stat_client_write(tmp, SI_AUDIOD_UPTIME); free(tmp); - stat_task->stat_item_values[SI_AUDIOD_UPTIME] = new; + stat_item_values[SI_AUDIOD_UPTIME] = new; } else free(new); - old = stat_task->stat_item_values[SI_AUDIOD_STATUS]; + old = stat_item_values[SI_AUDIOD_STATUS]; new = audiod_status_string(); if (!old || strcmp(old, new)) { free(old); stat_client_write(new, SI_AUDIOD_STATUS); - stat_task->stat_item_values[SI_AUDIOD_STATUS] = new; + stat_item_values[SI_AUDIOD_STATUS] = new; } else free(new); - old = stat_task->stat_item_values[SI_DECODER_FLAGS]; + old = stat_item_values[SI_DECODER_FLAGS]; new = decoder_flags(); if (!old || strcmp(old, new)) { + free(old); stat_client_write(new, SI_DECODER_FLAGS); - stat_task->stat_item_values[SI_DECODER_FLAGS] = new; + stat_item_values[SI_DECODER_FLAGS] = new; } else free(new); } @@ -534,11 +479,11 @@ void dump_empty_status(void) { int i; - FOR_EACH_STAT_ITEM(i) { + FOR_EACH_STATUS_ITEM(i) { char *tmp = make_message("%s:\n", status_item_list[i]); stat_client_write(tmp, i); free(tmp); - free(stat_task->stat_item_values[i]); - stat_task->stat_item_values[i] = NULL; + free(stat_item_values[i]); + stat_item_values[i] = NULL; } }