Merge branch 't/sound_device_lock'
authorAndre Noll <maan@tuebingen.mpg.de>
Sun, 23 Nov 2014 16:06:04 +0000 (17:06 +0100)
committerAndre Noll <maan@tuebingen.mpg.de>
Sun, 23 Nov 2014 16:07:21 +0000 (17:07 +0100)
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.

16 files changed:
NEWS
afh.h
afs.cmd
afs.h
audiod.c
audiod_command.c
command.c
dccp_send.c
error.h
http_send.c
play.c
send.h
send_common.c
server.cmd
udp_send.c
web/manual.m4

diff --git a/NEWS b/NEWS
index f7158c4..82e0f0d 100644 (file)
--- 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 ec1d670..4204108 100644 (file)
--- 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 91da48c..7bb0054 100644 (file)
--- 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 9669b26..0b44335 100644 (file)
--- 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.
  *
index 6dfef3a..f8eecce 100644 (file)
--- 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;
 }
index d5c53bf..2aae0d8 100644 (file)
@@ -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)
index c832bee..db28b39 100644 (file)
--- 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);
 }
 
index ed03b61..4eda3b9 100644 (file)
@@ -15,7 +15,6 @@
 #include <sys/socket.h>
 #include <regex.h>
 #include <sys/types.h>
-#include <osl.h>
 #include <arpa/inet.h>
 #include <sys/un.h>
 #include <netdb.h>
@@ -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 05e7e57..c28a25a 100644 (file)
--- 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 \
index ce2dddf..65fec69 100644 (file)
@@ -10,7 +10,6 @@
 #include <sys/socket.h>
 #include <regex.h>
 #include <sys/types.h>
-#include <osl.h>
 #include <arpa/inet.h>
 #include <sys/un.h>
 #include <netdb.h>
@@ -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 9fc49e3..ed1c6fe 100644 (file)
--- 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 e3f76ca..cb35e25 100644 (file)
--- 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);
index 3f29fe8..144a48e 100644 (file)
@@ -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,
index 83097f1..ebe372b 100644 (file)
@@ -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.
index 96f12ff..465b3ca 100644 (file)
@@ -15,7 +15,6 @@
 #include <net/if.h>
 #include <arpa/inet.h>
 #include <sys/un.h>
-#include <osl.h>
 #include <netdb.h>
 
 #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;
index 218769b..42021c4 100644 (file)
@@ -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.