From: Andre Noll Date: Sun, 23 Nov 2014 16:06:04 +0000 (+0100) Subject: Merge branch 't/sound_device_lock' X-Git-Tag: v0.5.4~47 X-Git-Url: http://git.tuebingen.mpg.de/?a=commitdiff_plain;h=8b71176b792089c47acc788e1c1e068e9375fd18;hp=2ba45411ace62b419ce03a085491077deea38878;p=paraslash.git Merge branch 't/sound_device_lock' Cooking since 2014-09-22. * t/sound_device_lock: oss: Avoid sound artefacts on some setups. oss: Introduce sound device lock. audiod: Invalidate current audio format on close. --- diff --git a/NEWS b/NEWS index f7158c45..82e0f0d5 100644 --- a/NEWS +++ b/NEWS @@ -5,9 +5,13 @@ NEWS 0.5.4 (to be announced) "exponential alignment" ----------------------------------------------- - * Minor cleanups to daemon.c. - * New URLs for home page and git services. - * Improved error diagnostics for the mvblob commands. + - Minor cleanups to daemon.c. + - New URLs for home page and git services. + - Improved error diagnostics for the mvblob commands. + - New sender subcommand: status. + - Improved help text for server and afs commands. + - audiod memory leak fixes. + - oss_writer improvements. Download: ./releases/paraslash-git.tar.bz2 diff --git a/afh.h b/afh.h index ec1d6706..4204108a 100644 --- a/afh.h +++ b/afh.h @@ -58,6 +58,18 @@ struct afh_info { uint16_t bitrate; }; +/** Data about the current audio file, passed from afs to server. */ +struct audio_file_data { + /** The open file descriptor to the current audio file. */ + int fd; + /** Vss needs this for streaming. */ + struct afh_info afhi; + /** Size of the largest chunk. */ + uint32_t max_chunk_size; + /** Needed to get the audio file header. */ + uint8_t audio_format_id; +}; + /** * Structure for audio format handling. * diff --git a/afs.cmd b/afs.cmd index 91da48cb..7bb00545 100644 --- a/afs.cmd +++ b/afs.cmd @@ -5,12 +5,11 @@ TM: mood lyr img pl --- N: add P: AFS_READ | AFS_WRITE -D: Add new audio files to the database. -U: add [-l] [-f] [-v] path... -H: Each given path may be either the full path to an audio -H: file, or the full path of a directory. In case of a -H: directory, all audio files in that directory are added -H: recursively. Only absolute paths are accepted. +D: Add or update audio files. +U: add [-a] [-l] [-f] [-v] path... +H: Each path must be absolute and refer to either an audio file, or a +H: directory. In case of a directory, all audio files in that directory +H: are added recursively. Only absolute paths are accepted. H: H: Options: H: @@ -18,9 +17,9 @@ H: -a Add all files. The default is to add only files ending in a H: known suffix for a supported audio format. H: H: -l Add files lazily. If the path already exists in the -H: database, skip this file. This operation is really cheap. -H: Use it when adding large directories if only a few files -H: where added. +H: database, skip this file. This operation is really cheap. Useful +H: to update large directories after some files have been added or +H: deleted. H: H: -f Force adding/updating. Recompute the audio format handler data H: even if a file with the same path and the same hash value exists. @@ -51,7 +50,7 @@ H: -lp: parser-friendly mode H: -lm: mbox listing mode H: -lc: chunk-table listing mode H: -H: -p List full path of audio file. If not specified, only the basename +H: -p List full paths. If this option is not specified, only the basename H: of each file is printed. H: H: -a List only files that are admissible with respect to the current mood or @@ -79,9 +78,8 @@ N: lsatt P: AFS_READ D: List attributes. U: lsatt [-i] [-l] [-r] [pattern] -H: Print the list of all defined attributes which match the -H: given pattern. If no pattern is given, the full list is -H: printed. +H: Print the list of all defined attributes which match the given +H: pattern. If no pattern is given, the full list is printed. H: H: Options: H: @@ -99,9 +97,9 @@ U: setatt attribute{+|-}... pattern H: Set ('+') or unset ('-') the given attributes for all audio files matching H: pattern. Example: H: -H: setatt rock+ punk+ classic- '*foo.mp3' +H: setatt rock+ punk+ pop- '*foo.mp3' H: -H: sets the 'rock' and the 'punk' attribute but unsets the 'classic' +H: sets the 'rock' and the 'punk' attribute and unsets the 'pop' H: attribute of all files ending with 'foo.mp3'. --- N: addatt @@ -149,9 +147,10 @@ N: rm P: AFS_READ | AFS_WRITE D: Remove entries from the audio file table. U: rm [-v] [-f] [-p] pattern... -H: Delete all entries in the audio file table that match any given pattern. -H: Note that affects the table entries only; paraslash won't touch your -H: audio files in any way. +H: Delete all entries in the audio file table that match any given pattern. Note +H: that this affects the table entries only; the command won't touch your audio +H: files on disk. +H: H: Options: H: H: -v Verbose mode. Explain what is being done. @@ -166,28 +165,29 @@ H: a slash (see fnmatch(3)). --- N: touch P: AFS_READ | AFS_WRITE -D: Manipulate the afs data for all audio files matching a pattern. +D: Manipulate the afs entry of audio files. U: touch [-n=numplayed] [-l=lastplayed] [-y=lyrics_id] [-i=image_id] [-a=amp] [-v] [-p] pattern -H: If no option is given, lastplayed is set to the current time -H: and numplayed is increased by one. Otherwise, only the given -H: options are taken into account. +H: If no option is given, the lastplayed field is set to the current time +H: and the value of the numplayed field is increased by one. Otherwise, +H: only the given options are taken into account. H: H: Options: H: -H: -n Set numplayed count. The number of times afs has selected this -H: audio file for streaming. +H: -n Set the numplayed count, i.e. the number of times this audio +H: file was selected for streaming so far. H: -H: -l Set lastplayed time. The last time this audio file was selected. -H: Must be given as the number of seconds since the epoch. Example: +H: -l Set the lastplayed time, i.e. the last time this audio file was +H: selected for streaming. The argument must be a number of seconds +H: since the epoch. Example: H: H: touch -l=$(date +%s) file H: H: sets the lastplayed time of 'file' to the current time. H: -H: -y Set the lyrics id. Specify the lyrics data file associated with -H: this audio file. +H: -y Set the lyrics ID which specifies the lyrics data file associated +H: with the audio file. H: -H: -i Set the image id. Same as -y, but sets the image. +H: -i Like -y, but sets the image ID. H: H: -a Set the amplification value (0-255). This determines a scaling H: factor by which the amplitude should be multiplied in order to @@ -208,10 +208,9 @@ N: cpsi P: AFS_READ | AFS_WRITE D: Copy audio file selector info. U: cpsi [-a] [-y] [-i] [-l] [-n] [-v] source pattern... -H: If no option, or only the -v option is given, all fields of -H: the audio file selector info are copied to all files -H: matching pattern. Otherwise, only the given options are -H: taken into account. +H: If no option, or only the -v option is given, all fields of the +H: audio file selector info are copied to all files matching pattern. +H: Otherwise, only the given options are taken into account. H: H: Options: H: @@ -242,14 +241,11 @@ T: add N: add@member@ O: int com_add@member@(struct command_context *cc); P: AFS_READ | AFS_WRITE -D: Read data from stdin and add it as a blob to the @member@ table. +D: Add stdin as a blob to the @member@ table. U: add@member@ @member@_name -H: Read arbitrary binary data from stdin and send that data to -H: the audio file selector process which creates a new blob for -H: the data in the corresponding osl table. -H: -H: The names of the blobs of a table are unique. If an entry with the -H: given name already exists, its contents are replaced by the new data. +H: Read from stdin and ask the audio file selector to create a blob in the +H: corresponding osl table. If the named blob already exists, it gets replaced +H: with the new data. --- T: cat N: cat@member@ @@ -257,9 +253,7 @@ O: int com_cat@member@(struct command_context *cc); P: AFS_READ D: Dump the contents of a blob of type @member@ to stdout. U: cat@member@ @member@_name -H: This command may be used to retrieve the blob identified by -H: the given name from the corresponding osl table to which -H: they were previously added. +H: Retrieve the named blob and write it to stdout. --- T: ls N: ls@member@ @@ -267,9 +261,8 @@ O: int com_ls@member@(struct command_context *cc); P: AFS_READ D: List blobs of type @member@ matching a pattern. U: ls@member@ [-i] [-l] [-r] [pattern] -H: Print a list of the names of all blobs in the corresponding -H: osl table which match the given pattern. If no pattern is -H: given, the full list is printed. +H: Print the list of all blobs which match the given pattern. If no +H: pattern is given, the full list is printed. H: H: Options: H: @@ -287,8 +280,7 @@ O: int com_rm@member@(struct command_context *cc); P: AFS_READ | AFS_WRITE D: Remove blob(s) of type @member@ from the @member@ table. U: rm@member@ pattern... -H: Remove all blobs from the corresponding table which match -H: any given pattern. +H: Remove all blobs whose name matches any of the given patterns. --- T: mv N: mv@member@ @@ -296,4 +288,5 @@ O: int com_mv@member@(struct command_context *cc); P: AFS_READ | AFS_WRITE D: Rename a blob of type @member@. U: mv@member@ old_@member@_name new_@member@_name -H: Rename the blob identified by the first name as the second name. +H: Rename the blob identified by old_@member@_name to new_@member@_name. +H: This command fails if new_@member@_name already exists. diff --git a/afs.h b/afs.h index 9669b26d..0b443354 100644 --- a/afs.h +++ b/afs.h @@ -122,18 +122,6 @@ struct ls_data { unsigned char *hash; }; -/** Data about the current audio file, passed from afs to server. */ -struct audio_file_data { - /** The open file descriptor to the current audio file. */ - int fd; - /** Vss needs this for streaming. */ - struct afh_info afhi; - /** Size of the largest chunk. */ - uint32_t max_chunk_size; - /** Needed to get the audio file header. */ - uint8_t audio_format_id; -}; - /** * Codes used for communication between the server and the afs process. * diff --git a/audiod.c b/audiod.c index 6dfef3a2..f8eeccee 100644 --- a/audiod.c +++ b/audiod.c @@ -1007,16 +1007,22 @@ static void signal_pre_select(struct sched *s, void *context) para_fd_set(st->fd, &s->rfds, &s->max_fileno); } -static int signal_post_select(struct sched *s, __a_unused void *context) +static int signal_post_select(struct sched *s, void *context) { - int signum; + struct signal_task *st = context; + int ret, signum; + + ret = task_get_notification(st->task); + if (ret < 0) + return ret; signum = para_next_signal(&s->rfds); switch (signum) { case SIGINT: case SIGTERM: case SIGHUP: PARA_NOTICE_LOG("received signal %d\n", signum); - clean_exit(EXIT_FAILURE, "caught deadly signal"); + task_notify_all(s, E_AUDIOD_SIGNAL); + return -E_AUDIOD_SIGNAL; } return 0; } @@ -1035,10 +1041,17 @@ static int command_post_select(struct sched *s, void *context) struct timeval tmp, delay; bool force = true; - ret = handle_connect(ct->fd, &s->rfds); + ret = task_get_notification(ct->task); if (ret < 0) + return ret; + ret = handle_connect(ct->fd, &s->rfds); + if (ret < 0) { PARA_ERROR_LOG("%s\n", para_strerror(-ret)); - else if (ret > 0) + if (ret == -E_AUDIOD_TERM) { + task_notify_all(s, -ret); + return ret; + } + } else if (ret > 0) goto dump; /* if last status dump was less than 500ms ago, do nothing */ @@ -1141,19 +1154,13 @@ static void close_unused_slots(void) close_slot(i); } -/** - * Close the connection to para_server and exit. - * - * \param status The exit status which is passed to exit(3). - * \param msg The log message - * - * Log \a msg with loglevel \p EMERG, close the connection to para_server and - * all slots, and call \p exit(status). \a status should be either EXIT_SUCCESS - * or EXIT_FAILURE. +/* + * Cleanup all resources. * - * \sa exit(3). + * This performs various cleanups, removes the audiod socket and closes the + * connection to para_server. */ -void __noreturn clean_exit(int status, const char *msg) +static void audiod_cleanup(void) { if (socket_name) unlink(socket_name); @@ -1161,8 +1168,6 @@ void __noreturn clean_exit(int status, const char *msg) close_unused_slots(); audiod_cmdline_parser_free(&conf); close_stat_clients(); - PARA_EMERG_LOG("%s\n", msg); - exit(status); } /* @@ -1227,7 +1232,11 @@ min_delay: static int status_post_select(struct sched *s, void *context) { struct status_task *st = context; + int ret; + ret = task_get_notification(st->task); + if (ret < 0) + return ret; if (audiod_status == AUDIOD_OFF) { if (!st->ct) goto out; @@ -1242,7 +1251,6 @@ static int status_post_select(struct sched *s, void *context) if (st->ct) { char *buf; size_t sz; - int ret; ret = btr_node_status(st->btrn, st->min_iqs, BTR_NT_LEAF); if (ret < 0) { @@ -1436,8 +1444,10 @@ int main(int argc, char *argv[]) sched.default_timeout.tv_sec = 2; sched.default_timeout.tv_usec = 999 * 1000; ret = schedule(&sched); + audiod_cleanup(); sched_shutdown(&sched); - PARA_EMERG_LOG("%s\n", para_strerror(-ret)); - return EXIT_FAILURE; + if (ret < 0) + PARA_EMERG_LOG("%s\n", para_strerror(-ret)); + return ret < 0? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/audiod_command.c b/audiod_command.c index d5c53bf9..2aae0d80 100644 --- a/audiod_command.c +++ b/audiod_command.c @@ -376,10 +376,10 @@ static int com_grab(int fd, int argc, char **argv) return grab_client_new(fd, argc, argv, &sched); } -__noreturn static int com_term(int fd, __a_unused int argc, __a_unused char **argv) +static int com_term(int fd, __a_unused int argc, __a_unused char **argv) { close(fd); - clean_exit(EXIT_SUCCESS, "terminating on user request"); + return -E_AUDIOD_TERM; } static int com_on(int fd, __a_unused int argc, __a_unused char **argv) diff --git a/command.c b/command.c index c832beea..db28b39d 100644 --- a/command.c +++ b/command.c @@ -344,7 +344,10 @@ static int com_sender(struct command_context *cc) if (ret < 0) { if (scd.sender_num < 0) return ret; - msg = senders[scd.sender_num].help(); + if (strcmp(cc->argv[2], "status") == 0) + msg = senders[scd.sender_num].status(); + else + msg = senders[scd.sender_num].help(); return send_sb(&cc->scc, msg, strlen(msg), SBD_OUTPUT, false); } @@ -364,7 +367,7 @@ static int com_sender(struct command_context *cc) usleep(100 * 1000); continue; } - memcpy(&mmd->sender_cmd_data, &scd, sizeof(scd)); + mmd->sender_cmd_data = scd; mutex_unlock(mmd_mutex); break; } @@ -374,28 +377,20 @@ static int com_sender(struct command_context *cc) /* server info */ static int com_si(struct command_context *cc) { - int i, ret; - char *msg, *ut, *sender_info = NULL; + int ret; + char *msg, *ut; if (cc->argc != 1) return -E_COMMAND_SYNTAX; mutex_lock(mmd_mutex); - for (i = 0; senders[i].name; i++) { - char *info = senders[i].info(); - sender_info = para_strcat(sender_info, info); - free(info); - } ut = daemon_get_uptime_str(now); ret = xasprintf(&msg, - "version: %s\n" "up: %s\nplayed: %u\n" "server_pid: %d\n" "afs_pid: %d\n" "connections (active/accepted/total): %u/%u/%u\n" "current loglevel: %s\n" - "supported audio formats: %s\n" - "%s", - version_git(), + "supported audio formats: %s\n", ut, mmd->num_played, (int)getppid(), (int)mmd->afs_pid, @@ -403,12 +398,10 @@ static int com_si(struct command_context *cc) mmd->num_commands, mmd->num_connects, conf.loglevel_arg, - AUDIO_FORMAT_HANDLERS, - sender_info + AUDIO_FORMAT_HANDLERS ); mutex_unlock(mmd_mutex); free(ut); - free(sender_info); return send_sb(&cc->scc, msg, ret, SBD_OUTPUT, false); } diff --git a/dccp_send.c b/dccp_send.c index ed03b614..4eda3b94 100644 --- a/dccp_send.c +++ b/dccp_send.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -24,7 +23,6 @@ #include "error.h" #include "string.h" #include "afh.h" -#include "afs.h" #include "server.h" #include "net.h" #include "list.h" @@ -199,13 +197,13 @@ static const char *dccp_list_available_ccids(void) return list; } -static char *dccp_info(void) +static char *dccp_status(void) { - char *info = get_sender_info(dss, "dccp"); - char *ret = make_message("%s" "\tsupported ccids: %s\n", - info, dccp_list_available_ccids()); - free(info); - return ret; + char *status = generic_sender_status(dss, "dccp"); + char *result = make_message("%ssupported ccids: %s\n", status, + dccp_list_available_ccids()); + free(status); + return result; } /** @@ -220,7 +218,7 @@ void dccp_send_init(struct sender *s) { int ret, k, n; - s->info = dccp_info; + s->status = dccp_status; s->send = NULL; s->pre_select = dccp_pre_select; s->post_select = dccp_post_select; diff --git a/error.h b/error.h index 05e7e57e..c28a25a3 100644 --- a/error.h +++ b/error.h @@ -343,6 +343,8 @@ extern const char **para_errlist[]; PARA_ERROR(NOT_PLAYING, "not playing"), \ PARA_ERROR(AUDIOD_OFF, "audiod switched off"), \ PARA_ERROR(STATUS_TIMEOUT, "status item timeout"), \ + PARA_ERROR(AUDIOD_SIGNAL, "caught deadly signal"), \ + PARA_ERROR(AUDIOD_TERM, "terminating on user request"), \ #define AUDIOD_COMMAND_ERRORS \ diff --git a/http_send.c b/http_send.c index ce2dddfa..65fec69f 100644 --- a/http_send.c +++ b/http_send.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -20,7 +19,6 @@ #include "string.h" #include "server.cmdline.h" #include "afh.h" -#include "afs.h" #include "server.h" #include "http.h" #include "list.h" @@ -235,9 +233,9 @@ static int http_com_allow(struct sender_command_data *scd) return 1; } -static char *http_info(void) +static char *http_status(void) { - return get_sender_info(hss, "http"); + return generic_sender_status(hss, "http"); } /** @@ -251,7 +249,7 @@ static char *http_info(void) void http_send_init(struct sender *s) { int ret; - s->info = http_info; + s->status = http_status; s->send = http_send; s->pre_select = http_pre_select; s->post_select = http_post_select; diff --git a/play.c b/play.c index 9fc49e37..ed1c6fef 100644 --- a/play.c +++ b/play.c @@ -872,6 +872,7 @@ static int com_prev(struct play_task *pt, int argc, __a_unused char **argv) kill_stream(pt); pt->next_file = ret; pt->rq = CRT_FILE_CHANGE; + pt->start_chunk = 0; return 0; } @@ -887,6 +888,7 @@ static int com_next(struct play_task *pt, int argc, __a_unused char **argv) kill_stream(pt); pt->next_file = ret; pt->rq = CRT_FILE_CHANGE; + pt->start_chunk = 0; return 0; } diff --git a/send.h b/send.h index e3f76caf..cb35e255 100644 --- a/send.h +++ b/send.h @@ -7,7 +7,15 @@ /** \file send.h Sender-related defines and structures. */ /** The sender subcommands. */ -enum {SENDER_ADD, SENDER_DELETE, SENDER_ALLOW, SENDER_DENY, SENDER_ON, SENDER_OFF, NUM_SENDER_CMDS}; +enum sender_subcommand { + SENDER_ADD, /**< Add a target (udp only). */ + SENDER_DELETE, /**< Delete a target (udp only). */ + SENDER_ALLOW, /**< Allow connections from given IP address(es). */ + SENDER_DENY, /**< Deny connections from given IP address(es). */ + SENDER_ON, /**< Activate the sender. */ + SENDER_OFF, /**< Deactivate the sender. */ + NUM_SENDER_CMDS /**< Used as array size in struct \ref sender. */ +}; /** * Describes one supported sender of para_server. @@ -37,7 +45,7 @@ struct sender { * * The result must be dynamically allocated and is freed by the caller. */ - char* (*info)(void); + char* (*status)(void); /** * The send-hook. * @@ -171,7 +179,7 @@ void shutdown_client(struct sender_client *sc, struct sender_status *ss); void shutdown_clients(struct sender_status *ss); void init_sender_status(struct sender_status *ss, char **access_arg, int num_access_args, int port, int max_clients, int default_deny); -char *get_sender_info(struct sender_status *ss, const char *name); +char *generic_sender_status(struct sender_status *ss, const char *name); void generic_com_allow(struct sender_command_data *scd, struct sender_status *ss); diff --git a/send_common.c b/send_common.c index 3f29fe81..144a48e1 100644 --- a/send_common.c +++ b/send_common.c @@ -159,7 +159,7 @@ void init_sender_status(struct sender_status *ss, char **access_arg, * * \return The string printed in the "si" command. */ -char *get_sender_info(struct sender_status *ss, const char *name) +char *generic_sender_status(struct sender_status *ss, const char *name) { char *clnts = NULL, *ret; struct sender_client *sc, *tmp_sc; @@ -171,14 +171,12 @@ char *get_sender_info(struct sender_status *ss, const char *name) clnts = tmp; } ret = make_message( - "%s sender:\n" - "\tstatus: %s\n" - "\tport: %s\n" - "\tnumber of connected clients: %d\n" - "\tmaximal number of clients: %d%s\n" - "\tconnected clients: %s\n" - "\taccess %s list: %s\n", - name, + "status: %s\n" + "port: %s\n" + "number of connected clients: %d\n" + "maximal number of clients: %d%s\n" + "connected clients: %s\n" + "access %s list: %s\n", (ss->listen_fd >= 0)? "on" : "off", stringify_port(ss->port, strcmp(name, "http") ? "dccp" : "tcp"), ss->num_clients, diff --git a/server.cmd b/server.cmd index 83097f1f..ebe372b7 100644 --- a/server.cmd +++ b/server.cmd @@ -4,15 +4,14 @@ SN: list of server commands --- N: ff P: VSS_READ | VSS_WRITE -D: Jump amount of time forwards or backwards in current audio file. +D: Jump N seconds forward or backward. U: ff n[-] -H: Set the 'R' (reposition request) bit of the vss status flags -H: and enqueue a request to jump n seconds forwards or backwards -H: in the current audio file. +H: This sets the 'R' (reposition request) bit of the vss status flags +H: which enqueues a request to jump n seconds forwards or backwards. H: -H: EXAMPLE +H: Example: H: -H: ff 30- +H: para_client ff 30- H: H: jumps 30 seconds backwards. --- @@ -21,41 +20,41 @@ P: 0 D: Print online help. U: help [command] H: Without any arguments, help prints a list of available commands. When -H: issued with a command name as first argument, print out a description -H: for that command. +H: called with a command name as first argument, it prints the description +H: of that command. --- N: hup P: VSS_WRITE -D: Force reload of config file, log file and user list. +D: Reload config file, log file and user list. U: hup H: Reread the config file and the user list file, close and reopen the log -H: file, and tell all children to do the same. +H: file, and ask the afs process to do the same. Sending the HUP signal to +H: the server process has the same effect. --- N: jmp P: VSS_READ | VSS_WRITE -D: Jump to given position in current audio file. -U: jmp [n] -H: Set the 'R' (reposition request) bit of the vss status flags -H: and enqueue a request to jump to n% of the current audio file, -H: where 0 <= n <= 100. +D: Jump to the given position. +U: jmp n +H: Set the 'R' (reposition request) bit of the vss status flags and enqueue a +H: request to jump to n% of the current audio file, where 0 <= n <= 100. --- N: next P: VSS_READ | VSS_WRITE -D: Skip rest of the current audio file. +D: Close the current audio file. U: next -H: Set the 'N' (next audio file) bit of the vss status flags. When -H: playing, change audio file immediately. Equivalent to stop -H: if paused, NOP if stopped. +H: Set the 'N' (next audio file) bit of the vss status flags which instructs the +H: server to close its current audio file if necessary. If the 'P' bit (playing) +H: is on, playing continues with the next audio file. This command is equivalent +H: to stop if paused, and has no effect if stopped. --- N: nomore P: VSS_READ | VSS_WRITE D: Stop playing after current audio file. U: nomore -H: Set the 'O' (no more) bit of the vss status flags. This instructs -H: para_server to clear the 'P' (playing) bit as soon as it encounters -H: the 'N' (next audio file) bit being set. -H: Use this command instead of stop if you don't like -H: sudden endings. +H: Set the 'O' (no more) bit of the vss status flags which asks para_server to +H: clear the 'P' (playing) bit after the 'N' (next audio file) bit transitions +H: from off to on (because the end of the current audio file is reached). Use this +H: command instead of stop if you don't like sudden endings. --- N: pause P: VSS_READ | VSS_WRITE @@ -65,54 +64,60 @@ H: Clear the 'P' (playing) bit of the vss status flags. --- N: play P: VSS_READ | VSS_WRITE -D: Start playing or resume playing when paused. +D: Start or resume playing. U: play -H: Set the 'P' (playing) bit of the vss status flags. This -H: results in starting/continuing to stream. +H: Set the 'P' (playing) bit of the vss status flags. --- N: sender P: VSS_READ | VSS_WRITE -D: Control paraslash internal senders. +D: Control paraslash senders. U: sender [s cmd [arguments]] -H: send command cmd to sender s. cmd may be one of the following: -H: help, on, off, add, delete, allow, or deny. Note that not all senders -H: support each command. Try e.g. 'para_client sender http help' for -H: more information about the http sender. If no argument is given, -H: print out a list of all senders that are compiled in. +H: Send a command to a specific sender. The following commands are available, but +H: not all senders support every command. +H: +H: help, on, off, add, delete, allow, deny, status. +H: +H: The help command prints the help text of the given sender. If no command is +H: given the list of compiled in senders is shown. +H: +H: Example: +H: +H: para_client sender http help --- N: si P: 0 D: Print server info. U: si -H: Print server uptime and other information. +H: Show server and afs PID, number of connections, uptime and more. --- N: stat P: VSS_READ -D: Print status info for the current audio file. +D: Print information about the current audio file. U: stat [-n=num] [-p] -H: If -n is given, the command exits after having displayed the status n -H: times. Otherwise, the command runs in an endless loop. +H: If -n is given, exit after the status information has been shown n times. +H: Otherwise, the command runs in an endless loop. H: H: The -p option activates parser-friendly output: Each status item is -H: prefixed with its size in bytes and the status items identifiers are +H: prefixed with its size in bytes and the status item identifiers are H: printed as numerical values. --- N: stop P: VSS_READ | VSS_WRITE -D: Stop streaming. +D: Stop playing. U: stop -H: Clear the 'P' (play) bit and set the 'N' bit of the vss status -H: flags. +H: Clear the 'P' (playing) bit and set the 'N' (next audio file) bit of the vss +H: status flags, effectively stopping playback. --- N: term P: VSS_READ | VSS_WRITE -D: Terminate para_server. +D: Ask the server to terminate. U: term -H: Shuts down the server. Instead of this command, you can also send -H: SIGINT or SIGTERM. It should never be necessary to send SIGKILL. +H: Shut down the server. Instead of this command, you can also send SIGINT or +H: SIGTERM to the para_server process. It should never be necessary to send +H: SIGKILL. --- N: version P: 0 -D: Print server's version. +D: Print the git version string of para_server. U: version -H: Show version and other info +H: Show version and other info. diff --git a/udp_send.c b/udp_send.c index 96f12ff0..465b3ca6 100644 --- a/udp_send.c +++ b/udp_send.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include "server.cmdline.h" @@ -23,7 +22,6 @@ #include "error.h" #include "string.h" #include "afh.h" -#include "afs.h" #include "server.h" #include "list.h" #include "send.h" @@ -355,7 +353,7 @@ err: return ret; } -static char *udp_info(void) +static char *udp_status(void) { struct sender_client *sc; char *ret, *tgts = NULL; @@ -371,10 +369,9 @@ static char *udp_info(void) tgts = tmp; } ret = make_message( - "udp sender:\n" - "\tstatus: %s\n" - "\tport: %s\n" - "\ttargets: %s\n", + "status: %s\n" + "port: %s\n" + "targets: %s\n", (sender_status == SENDER_ON)? "on" : "off", stringify_port(conf.udp_default_port_arg, "udp"), tgts? tgts : "(none)" @@ -427,7 +424,7 @@ static char *udp_help(void) void udp_send_init(struct sender *s) { INIT_LIST_HEAD(&targets); - s->info = udp_info; + s->status = udp_status; s->help = udp_help; s->send = NULL; s->pre_select = NULL; diff --git a/web/manual.m4 b/web/manual.m4 index 218769ba..42021c42 100644 --- a/web/manual.m4 +++ b/web/manual.m4 @@ -1452,15 +1452,21 @@ the stream. Examples ~~~~~~~~ -The sender command of para_server allows to (de-)activate senders -and to change the access permissions senders at runtime. The "si" -(server info) command is used to list the streaming options of the -currently running server as well as the various sender access lists. +The "si" (server info) command lists some information about the +currently running server process. --> Show client/target/access lists: +-> Show PIDs, number of connected clients, uptime, and more: para_client si +The sender command of para_server prints information about senders, +like the various access control lists, and it allows to (de-)activate +senders and to change the access permissions at runtime. + +-> List all senders + + para_client sender + -> Obtain general help for the sender command: para_client help sender @@ -1470,6 +1476,10 @@ currently running server as well as the various sender access lists. s=http # or dccp or udp para_client sender $s help +-> Show status of the http sender + + para_client sender http status + By default para_server activates both the HTTP and th DCCP sender on startup. This can be changed via command line options or para_server's config file.