Merge branch 'refs/heads/t/gui-sigwinch'
authorAndre Noll <maan@tuebingen.mpg.de>
Tue, 1 May 2018 16:17:32 +0000 (18:17 +0200)
committerAndre Noll <maan@tuebingen.mpg.de>
Tue, 1 May 2018 16:25:59 +0000 (18:25 +0200)
A single patch which removes a long standing issue of para_gui.

Cooking for half a year.

* refs/heads/t/gui-sigwinch:
  gui: Catch SIGWINCH.

38 files changed:
Doxyfile
Makefile.real
NEWS.md
afh_recv.c
afs.c
afs.h
aft.c
base64.h
bash_completion
client.h
client_common.c
command.c
configure.ac
crypt.c
daemon.c
dccp_send.c
fd.c
fd.h
gcrypt.c
http_recv.c
http_send.c
m4/lls/mixer.suite.m4
m4/lls/recv.suite.m4
m4/lls/recv_cmd.suite.m4
mixer.c
mood.c
mp.c
net.c
net.h
ogg_afh_common.c
play.c
resample_filter.c
send.h
send_common.c
server.c
server.h
udp_send.c
vss.c

index d8960dded71cd867917c0a7589df413cd2321aa1..b11683e424443baef8754b34097ad3cb8dbed4fe 100644 (file)
--- a/Doxyfile
+++ b/Doxyfile
@@ -812,7 +812,7 @@ RECURSIVE              = NO
 # Note that relative paths are relative to the directory from which doxygen is
 # run.
 
-EXCLUDE                =
+EXCLUDE                = config.h
 
 # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
 # directories that are symbolic links (a Unix file system feature) are excluded
index b60c56984e4fd707378a3f462d2d522825de5f45..7648767732470d0bc0e10adb2a69e981f709fceb 100644 (file)
@@ -18,7 +18,7 @@ uname_s := $(shell uname -s 2>/dev/null || echo "UNKNOWN_OS")
 uname_rs := $(shell uname -rs)
 cc_version := $(shell $(CC) --version | head -n 1)
 GIT_VERSION := $(shell ./GIT-VERSION-GEN git-version.h)
-COPYRIGHT_YEAR := 2017
+COPYRIGHT_YEAR := 2018
 
 ifeq ("$(origin O)", "command line")
        build_dir := $(O)
diff --git a/NEWS.md b/NEWS.md
index d0bd6585a3a2f04be5ec262d580bfb8800733498..4fd9dcb495e7f42cf89468ae18d485338820ec9b 100644 (file)
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,6 +1,13 @@
 NEWS
 ====
 
+-------------------------------------------
+0.6.2 (to be accounced) "elastic diversity"
+-------------------------------------------
+
+- para_gui no longer waits up to one second to update the screen when
+the geometry of the terminal changes.
+
 ----------------------------------------
 0.6.1 (2017-09-23) "segmented iteration"
 ----------------------------------------
index c3e6ddbd0ecf85e320484c0e1ca4298f5c480d9a..6525209bff4119a177eb443f154b4f1f5224845b 100644 (file)
@@ -68,7 +68,7 @@ static int afh_recv_open(struct receiver_node *rn)
        struct lls_parse_result *lpr = rn->lpr;
        struct private_afh_recv_data *pard;
        struct afh_info *afhi;
-       const char *fn = RECV_CMD_OPT_STRING_VAL(AFH, FILENAME, lpr);
+       const char *fn = RECV_CMD_OPT_STRING_VAL(AFH, FILENAME, lpr), *msg;
        int32_t bc = RECV_CMD_OPT_INT32_VAL(AFH, BEGIN_CHUNK, lpr);
        const struct lls_opt_result *r_e = RECV_CMD_OPT_RESULT(AFH, END_CHUNK, lpr);
        int ret;
@@ -87,8 +87,10 @@ static int afh_recv_open(struct receiver_node *rn)
                goto out_unmap;
        pard->audio_format_num = ret;
        ret = -ERRNO_TO_PARA_ERROR(EINVAL);
+       msg = "no data chunks";
        if (afhi->chunks_total == 0)
                goto out_clear_afhi;
+       msg = "invalid begin chunk";
        if (PARA_ABS(bc) >= afhi->chunks_total)
                goto out_clear_afhi;
        if (bc >= 0)
@@ -100,6 +102,7 @@ static int afh_recv_open(struct receiver_node *rn)
        if (lls_opt_given(r_e)) {
                int32_t ec = lls_int32_val(0, r_e);
                ret = -ERRNO_TO_PARA_ERROR(EINVAL);
+               msg = "invalid end chunk";
                if (PARA_ABS(ec) > afhi->chunks_total)
                        goto out_clear_afhi;
                if (ec >= 0)
@@ -109,12 +112,14 @@ static int afh_recv_open(struct receiver_node *rn)
        } else
                pard->last_chunk = afhi->chunks_total - 1;
        ret = -ERRNO_TO_PARA_ERROR(EINVAL);
+       msg = "begin chunk >= end chunk!?";
        if (pard->first_chunk >= pard->last_chunk)
                goto out_clear_afhi;
        pard->current_chunk = pard->first_chunk;
        return pard->audio_format_num;
 out_clear_afhi:
        clear_afhi(afhi);
+       PARA_ERROR_LOG("%s: %s\n", fn, msg);
 out_unmap:
        para_munmap(pard->map, pard->map_size);
        close(pard->fd);
diff --git a/afs.c b/afs.c
index a8c504f460d4f10a67422fcca2adc2ba25478a80..538606add432aef4710c09d5b2826df3d123c933 100644 (file)
--- a/afs.c
+++ b/afs.c
@@ -22,8 +22,8 @@
 #include "string.h"
 #include "afh.h"
 #include "afs.h"
-#include "server.h"
 #include "net.h"
+#include "server.h"
 #include "ipc.h"
 #include "list.h"
 #include "sched.h"
@@ -74,11 +74,6 @@ static struct afs_table afs_tables[NUM_AFS_TABLES] = {
 struct command_task {
        /** The file descriptor for the local socket. */
        int fd;
-       /**
-        * Value sent by the command handlers to identify themselves as
-        * children of the running para_server.
-        */
-       uint32_t cookie;
        /** The associated task structure. */
        struct task *task;
 };
@@ -93,15 +88,6 @@ static struct signal_task *signal_task;
 static enum play_mode current_play_mode;
 static char *current_mop; /* mode or playlist specifier. NULL means dummy mood */
 
-/**
- * A random number used to "authenticate" the connection.
- *
- * para_server picks this number by random before it forks the afs process. The
- * command handlers know this number as well and write it to the afs socket,
- * together with the id of the shared memory area which contains the payload of
- * the afs command. A local process has to know this number to abuse the afs
- * service provided by the local socket.
- */
 extern uint32_t afs_socket_cookie;
 
 /**
@@ -699,8 +685,7 @@ static int open_afs_tables(void)
                ret = afs_tables[i].open(database_dir);
                if (ret >= 0)
                        continue;
-               PARA_ERROR_LOG("%s init: %s\n", afs_tables[i].name,
-                       para_strerror(-ret));
+               PARA_ERROR_LOG("could not open %s\n", afs_tables[i].name);
                break;
        }
        if (ret >= 0)
@@ -880,7 +865,7 @@ static int execute_server_command(fd_set *rfds)
 }
 
 /* returns 0 if no data available, 1 else */
-static int execute_afs_command(int fd, fd_set *rfds, uint32_t expected_cookie)
+static int execute_afs_command(int fd, fd_set *rfds)
 {
        uint32_t cookie;
        int query_shmid;
@@ -898,9 +883,9 @@ static int execute_afs_command(int fd, fd_set *rfds, uint32_t expected_cookie)
                return 1;
        }
        cookie = *(uint32_t *)buf;
-       if (cookie != expected_cookie) {
+       if (cookie != afs_socket_cookie) {
                PARA_NOTICE_LOG("received invalid cookie (got %u, expected %u)\n",
-                       (unsigned)cookie, (unsigned)expected_cookie);
+                       (unsigned)cookie, (unsigned)afs_socket_cookie);
                return 1;
        }
        query_shmid = *(int *)(buf + sizeof(cookie));
@@ -938,7 +923,7 @@ static int command_post_select(struct sched *s, void *context)
        }
        /* Check the list of connected clients. */
        list_for_each_entry_safe(client, tmp, &afs_client_list, node) {
-               ret = execute_afs_command(client->fd, &s->rfds, ct->cookie);
+               ret = execute_afs_command(client->fd, &s->rfds);
                if (ret == 0) { /* prevent bogus connection flooding */
                        struct timeval diff;
                        tv_diff(now, &client->connect_time, &diff);
@@ -969,11 +954,10 @@ static int command_post_select(struct sched *s, void *context)
        return 0;
 }
 
-static void register_command_task(uint32_t cookie, struct sched *s)
+static void register_command_task(struct sched *s)
 {
        struct command_task *ct = &command_task_struct;
        ct->fd = setup_command_socket_or_die();
-       ct->cookie = cookie;
 
        ct->task = task_register(&(struct task_info) {
                .name = "afs command",
@@ -986,10 +970,9 @@ static void register_command_task(uint32_t cookie, struct sched *s)
 /**
  * Initialize the audio file selector process.
  *
- * \param cookie The value used for "authentication".
  * \param socket_fd File descriptor used for communication with the server.
  */
-__noreturn void afs_init(uint32_t cookie, int socket_fd)
+__noreturn void afs_init(int socket_fd)
 {
        static struct sched s;
        int i, ret;
@@ -1005,10 +988,9 @@ __noreturn void afs_init(uint32_t cookie, int socket_fd)
        ret = mark_fd_nonblocking(server_socket);
        if (ret < 0)
                goto out_close;
-       PARA_INFO_LOG("server_socket: %d, afs_socket_cookie: %u\n",
-               server_socket, (unsigned) cookie);
+       PARA_INFO_LOG("server_socket: %d\n", server_socket);
        init_admissible_files(OPT_STRING_VAL(AFS_INITIAL_MODE));
-       register_command_task(cookie, &s);
+       register_command_task(&s);
        s.default_timeout.tv_sec = 0;
        s.default_timeout.tv_usec = 999 * 1000;
        ret = write(socket_fd, "\0", 1);
diff --git a/afs.h b/afs.h
index 544a498dee9811912b2e58732dd0c1c0690571e5..8beca5aefcd0b9d06aed05e915877a2c5104a1a8 100644 (file)
--- a/afs.h
+++ b/afs.h
@@ -161,6 +161,14 @@ struct afs_callback_arg {
        struct osl_object query;
        /** Will be written on band SBD_OUTPUT, fully buffered. */
        struct para_buffer pbout;
+       /**
+        * Convenience pointer for the deserialized parse result.
+        *
+        * Most afs command handlers call \ref send_lls_callback_request() to
+        * serialize the parse result of the subcommand and pass it to the
+        * callback. In afs context a pointer to the deserialized parse result
+        * is stored here.
+        */
        struct lls_parse_result *lpr;
 };
 
@@ -212,7 +220,7 @@ _static_inline_ int afs_max_size_handler(char *buf, size_t size, void *private)
        return pass_buffer_as_shm(amshd->fd, amshd->band, buf, size);
 }
 
-__noreturn void afs_init(uint32_t cookie, int socket_fd);
+__noreturn void afs_init(int socket_fd);
 __must_check int afs_event(enum afs_events event, struct para_buffer *pb,
        void *data);
 int send_callback_request(afs_callback *f, struct osl_object *query,
diff --git a/aft.c b/aft.c
index 4433730647f1e95452fdfbd1853b563abf5e43fe..8969e7ac207ac935a83e4a212ee07d09e7317bc1 100644 (file)
--- a/aft.c
+++ b/aft.c
 #include "sideband.h"
 #include "command.h"
 
-static struct osl_table *audio_file_table;
+/* Data about one audio file. Needed for ls and stat output. */
+struct ls_data {
+       /* Usual audio format handler information. */
+       struct afh_info afhi;
+       /* Audio file selector information. */
+       struct afs_info afsi;
+       /* The full path of the audio file. */
+       char *path;
+       /* The score value (if -a was given). */
+       long score;
+       /* The hash value of the audio file data. */
+       unsigned char *hash;
+};
+
+/*
+ * The internal state of the audio file table is described by the following
+ * variables which are private to aft.c.
+ */
+static struct osl_table *audio_file_table; /* NULL if table not open */
+static struct osl_row *current_aft_row; /* NULL if no audio file open */
+
 static char *status_items;
 static char *parser_friendly_status_items;
+static struct ls_data status_item_ls_data;
 
 /** The different sorting methods of the ls command. */
 enum ls_sorting_method {
@@ -70,20 +91,6 @@ enum ls_listing_mode {
        LS_MODE_PARSER,
 };
 
-/* Data about one audio file. Needed for ls and stat output. */
-struct ls_data {
-       /* Usual audio format handler information. */
-       struct afh_info afhi;
-       /* Audio file selector information. */
-       struct afs_info afsi;
-       /* The full path of the audio file. */
-       char *path;
-       /* The score value (if -a was given). */
-       long score;
-       /* The hash value of the audio file data. */
-       unsigned char *hash;
-};
-
 /**
  * The size of the individual output fields of the ls command.
  *
@@ -954,9 +961,6 @@ out:
        return ret;
 }
 
-static struct ls_data status_item_ls_data;
-static struct osl_row *current_aft_row;
-
 static void make_inode_status_items(struct para_buffer *pb)
 {
        struct stat statbuf = {.st_size = 0};
@@ -1590,7 +1594,7 @@ ACTION:   Table modifications to be done by the callback.
 +----+----+---+------+---------------------------------------------------+
 | N  |  N | Y |  Y   | (new file) create new entry (force has no effect)
 +----+----+---+------+---------------------------------------------------+
-|  N |  N | N |  Y   | (new file) create new entry
+|  |  N | N |  Y   | (new file) create new entry
 +----+----+---+------+---------------------------------------------------+
 
 Notes:
@@ -2577,6 +2581,7 @@ static int aft_event_handler(enum afs_events event, struct para_buffer *pb,
                 * every time.
                 */
                make_status_items();
+               return 0;
        } default:
                return 0;
        }
index 4bfaa99d05eb6d3631d978f1fac2827823f8ec57..ea62d98fd92759eefae19492909bcc6a054fd097 100644 (file)
--- a/base64.h
+++ b/base64.h
@@ -1,3 +1,7 @@
+/* Copyright (C) 2016 Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */
+
+/** \file base64.h uudecode/base64 API. */
+
 int uudecode(char const *src, size_t encoded_size, char **result,
                size_t *decoded_size);
 int base64_decode(char const *src, size_t encoded_size, char **result,
index 4b1a4be55508d70f4f34a170327967d067ba24ef..88b37dc28fb0dc175f48ac9fa364f26a434bedde 100644 (file)
@@ -6,10 +6,6 @@ _para_complete()
        local line="$COMP_LINE" OLD_IFS="$IFS"
        local opts n
 
-       if [[ "$COMP_WORDBREAKS" != ' '  ]]; then
-               COMP_WORDBREAKS=' '
-               return 124 # try again with proper value
-       fi
        # This extracts short and long options from the help output
        local script='{
                if ($1 ~ "-[a-zA-Z]," && $2 ~ "--[a-zA-Z]") {
index f8cc5d649bb682ba497212b87a7417d911c44472..7ba56b9168c500bd4f596c5ba9db82ccef3347c5 100644 (file)
--- a/client.h
+++ b/client.h
@@ -36,8 +36,6 @@ struct client_task {
        unsigned char *challenge_hash;
        /** The parsed command line (including the command). */
        struct lls_parse_result *lpr;
-       /** The config file for client options. */
-       char *config_file;
        /** The RSA private key. */
        char *key_file;
        /** Paraslash user name. */
index 97d29f8fd09948b1e97972431df1f62ec30a4989..a8d480555708f77331cf4eb89b4b6d0df43d02c5 100644 (file)
@@ -40,7 +40,6 @@ void client_close(struct client_task *ct)
        if (!ct)
                return;
        free(ct->user);
-       free(ct->config_file);
        free(ct->key_file);
        lls_free_parse_result(ct->lpr, CLIENT_CMD_PTR);
        free(ct->challenge_hash);
@@ -536,7 +535,6 @@ int client_parse_config(int argc, char *argv[], struct client_task **ct_ptr,
        ret = lls(lls_parse(argc, argv, cmd, &lpr, &errctx));
        if (ret < 0)
                goto out;
-       ll = CLIENT_OPT_UINT32_VAL(LOGLEVEL, lpr);
        version_handle_flag("client", CLIENT_OPT_GIVEN(VERSION, lpr));
        handle_help_flag(lpr);
 
@@ -573,6 +571,9 @@ int client_parse_config(int argc, char *argv[], struct client_task **ct_ptr,
                lpr = merged_lpr;
        }
        /* success */
+       ll = CLIENT_OPT_UINT32_VAL(LOGLEVEL, lpr);
+       if (loglevel)
+               *loglevel = ll;
        user = CLIENT_OPT_GIVEN(USER, lpr)?
                para_strdup(CLIENT_OPT_STRING_VAL(USER, lpr)) : para_logname();
 
@@ -593,21 +594,17 @@ int client_parse_config(int argc, char *argv[], struct client_task **ct_ptr,
        ct->scc.fd = -1;
        ct->lpr = lpr;
        ct->key_file = kf;
-       ct->config_file = cf;
        ct->user = user;
        *ct_ptr = ct;
-       if (loglevel)
-               *loglevel = ll;
        ret = lls_num_inputs(lpr);
 out:
        free(home);
+       free(cf);
        if (ret < 0) {
                if (errctx)
                        PARA_ERROR_LOG("%s\n", errctx);
                free(errctx);
-               PARA_ERROR_LOG("%s\n", para_strerror(-ret));
                lls_free_parse_result(lpr, cmd);
-               free(cf);
                free(kf);
                *ct_ptr = NULL;
        }
index 837c49cf3976b6bb7d8a1c5b7284e53d4ba51257..6568b789339b25125fd54fad90d03abeceb515a2 100644 (file)
--- a/command.c
+++ b/command.c
 #include "string.h"
 #include "afh.h"
 #include "afs.h"
+#include "net.h"
 #include "server.h"
 #include "list.h"
 #include "send.h"
 #include "sched.h"
 #include "vss.h"
-#include "net.h"
 #include "daemon.h"
 #include "fd.h"
 #include "ipc.h"
@@ -872,7 +872,7 @@ static int run_command(struct command_context *cc, struct iovec *iov)
  * permissions to execute that command, the function calls the corresponding
  * command handler which does argument checking and further processing.
  *
- * In order to cope with DOS attacks, a timeout is set up which terminates
+ * In order to cope with DOS attacks, a timeout is set up which terminates
  * the function if the connection was not authenticated when the timeout
  * expires.
  *
index 1a375e9f57b0c9d589b24caf7faf2fe4b02a861e..499571a70318f2d3bfe753e8a9be95307e7fc378 100644 (file)
@@ -46,20 +46,21 @@ AC_DEFUN([LIB_SUBST_FLAGS], [
        AC_SUBST($1_cppflags)
        AC_SUBST($1_ldflags)
 ])
+AC_DEFUN([REQUIRE_EXECUTABLE], [
+        AC_PATH_PROG(m4_toupper([$1]), [$1])
+        test -z "$m4_toupper([$1])" && AC_MSG_ERROR(
+               [$1 is required to build this package])
+])
 
 AC_USE_SYSTEM_EXTENSIONS
 AC_C_BIGENDIAN()
-
-AC_PATH_PROG([BISON], [bison])
-AC_PATH_PROG([FLEX], [flex])
-
-AC_PATH_PROG([M4], [m4])
-test -z "$M4" && AC_MSG_ERROR(
-       [The m4 macro processor is required to build this package])
-
 AC_PROG_CC
 AC_PROG_CPP
 
+REQUIRE_EXECUTABLE([bison])
+REQUIRE_EXECUTABLE([flex])
+REQUIRE_EXECUTABLE([m4])
+
 executables="recv filter audioc write afh play"
 ########################################################################### osl
 STASH_FLAGS
diff --git a/crypt.c b/crypt.c
index 39fcd7edc136c6b81ef80b5132ea59ddbbeb74b1..b8a587cd0e55114f1ced030d5284adcd2d4a96b4 100644 (file)
--- a/crypt.c
+++ b/crypt.c
@@ -38,9 +38,9 @@ void get_random_bytes_or_die(unsigned char *buf, int num)
 }
 
 /*
- * Read 64 bytes from /dev/urandom and adds them to the SSL PRNG. Seed the PRNG
- * used by random() with a random seed obtained from SSL. If /dev/random is not
- * readable the function calls exit().
+ * Read 64 bytes from /dev/urandom and add them to the SSL PRNG. Seed the PRNG
+ * used by random(3) with a random seed obtained from SSL. If /dev/urandom is
+ * not readable, the function calls exit().
  *
  * \sa RAND_load_file(3), \ref get_random_bytes_or_die(), srandom(3),
  * random(3), \ref para_random().
@@ -154,8 +154,8 @@ int get_public_key(const char *key_file, struct asymmetric_key **result)
                goto out;
        ret = is_ssh_rsa_key(map, map_size);
        if (!ret) {
-               para_munmap(map, map_size);
-               return -E_SSH_PARSE;
+               ret = -E_SSH_PARSE;
+               goto out_unmap;
        }
        cp = map + ret;
        encoded_size = map_size - ret;
index e47639bc42864cc4881d5992bb567e902f4752ac..ddfe680cebc63dc1c7af89fde333c665873765eb 100644 (file)
--- a/daemon.c
+++ b/daemon.c
@@ -30,6 +30,7 @@ struct daemon {
        char *hostname;
        /** Used for colored log messages. */
        char log_colors[NUM_LOGLEVELS][COLOR_MAXLEN];
+       char *old_cwd;
 };
 
 static struct daemon the_daemon, *me = &the_daemon;
@@ -117,7 +118,12 @@ void daemon_set_logfile(const char *logfile_name)
 {
        free(me->logfile_name);
        me->logfile_name = NULL;
-       if (logfile_name)
+       if (!logfile_name)
+               return;
+       if (me->old_cwd && logfile_name[0] != '/')
+               me->logfile_name = make_message("%s/%s", me->old_cwd,
+                       logfile_name);
+       else
                me->logfile_name = para_strdup(logfile_name);
 }
 
@@ -197,6 +203,7 @@ int daemonize(bool parent_waits)
        /* become session leader */
        if (setsid() < 0)
                goto err;
+       me->old_cwd = getcwd(NULL, 0);
        if (chdir("/") < 0)
                goto err;
        null = open("/dev/null", O_RDWR);
@@ -234,15 +241,18 @@ void daemon_close_log(void)
  */
 void daemon_open_log_or_die(void)
 {
-       daemon_close_log();
+       FILE *new_log;
+
        if (!me->logfile_name)
                return;
-       me->logfile = fopen(me->logfile_name, "a");
-       if (!me->logfile) {
+       new_log = fopen(me->logfile_name, "a");
+       if (!new_log) {
                PARA_EMERG_LOG("can not open %s: %s\n", me->logfile_name,
                        strerror(errno));
                exit(EXIT_FAILURE);
        }
+       daemon_close_log();
+       me->logfile = new_log;
        /* equivalent to setlinebuf(), but portable */
        setvbuf(me->logfile, NULL, _IOLBF, 0);
 }
index 6f9895410161e47133d65a4f0893bac14a0743b4..69ba65f5ef864396e81a722d8e69817a0040166f 100644 (file)
@@ -21,8 +21,8 @@
 #include "error.h"
 #include "string.h"
 #include "afh.h"
-#include "server.h"
 #include "net.h"
+#include "server.h"
 #include "list.h"
 #include "send.h"
 #include "sched.h"
@@ -161,7 +161,8 @@ static void dccp_post_select(fd_set *rfds, __a_unused fd_set *wfds)
 
 static int dccp_com_on(__a_unused struct sender_command_data *scd)
 {
-       return generic_com_on(dss, IPPROTO_DCCP);
+       generic_com_on(dss, IPPROTO_DCCP);
+       return 1;
 }
 
 static int dccp_com_off(__a_unused struct sender_command_data *scd)
@@ -224,8 +225,6 @@ static char *dccp_status(void)
  */
 void dccp_send_init(struct sender *s)
 {
-       int ret;
-
        s->status = dccp_status;
        s->send = NULL;
        s->pre_select = dccp_pre_select;
@@ -243,7 +242,5 @@ void dccp_send_init(struct sender *s)
        init_sender_status(dss, OPT_RESULT(DCCP_ACCESS),
                OPT_UINT32_VAL(DCCP_PORT), OPT_UINT32_VAL(DCCP_MAX_CLIENTS),
                OPT_GIVEN(DCCP_DEFAULT_DENY));
-       ret = generic_com_on(dss, IPPROTO_DCCP);
-       if (ret < 0)
-               PARA_ERROR_LOG("%s\n", para_strerror(-ret));
+       generic_com_on(dss, IPPROTO_DCCP);
 }
diff --git a/fd.c b/fd.c
index 7079b51cc95c683af1187f0b4af1412b07e40950..0347fd83b7f4340019811b853e7eab5e9dccce36 100644 (file)
--- a/fd.c
+++ b/fd.c
@@ -179,15 +179,15 @@ __printf_2_3 int write_va_buffer(int fd, const char *fmt, ...)
  * \param rfds An optional fd set pointer.
  * \param num_bytes Result pointer. Contains the number of bytes read from \a fd.
  *
- * If \a rfds is not \p NULL and the (non-blocking) file descriptor \a fd is
- * not set in \a rfds, this function returns early without doing anything.
- * Otherwise The function tries to read up to \a sz bytes from \a fd, where \a
- * sz is the sum of the lengths of all vectors in \a iov. As for xwrite(),
- * \p EAGAIN is not considered an error condition. However, \p EOF is.
+ * If rfds is not NULL and the (non-blocking) file descriptor fd is not set in
+ * rfds, this function returns early without doing anything. Otherwise it tries
+ * to read up to sz bytes from fd, where sz is the sum of the lengths of all
+ * vectors in iov. Like \ref xwrite(), EAGAIN and EINTR are not considered
+ * error conditions. However, EOF is.
  *
  * \return Zero or a negative error code. If the underlying call to readv(2)
  * returned zero (indicating an end of file condition) or failed for some
- * reason other than \p EAGAIN, a negative error code is returned.
+ * reason other than EAGAIN or EINTR, a negative error code is returned.
  *
  * In any case, \a num_bytes contains the number of bytes that have been
  * successfully read from \a fd (zero if the first readv() call failed with
@@ -226,7 +226,7 @@ int readv_nonblock(int fd, struct iovec *iov, int iovcnt, fd_set *rfds,
                if (ret == 0)
                        return -E_EOF;
                if (ret < 0) {
-                       if (errno == EAGAIN)
+                       if (errno == EAGAIN || errno == EINTR)
                                return 0;
                        return -ERRNO_TO_PARA_ERROR(errno);
                }
@@ -455,22 +455,20 @@ again:
  * PROT_EXEC PROT_READ PROT_WRITE.
  * \param flags Exactly one of MAP_SHARED and MAP_PRIVATE.
  * \param fd The file to mmap from.
- * \param offset Mmap start.
  * \param map Result pointer.
  *
  * \return Standard.
  *
  * \sa mmap(2).
  */
-int para_mmap(size_t length, int prot, int flags, int fd, off_t offset,
-               void *map)
+int para_mmap(size_t length, int prot, int flags, int fd, void *map)
 {
        void **m = map;
 
        errno = EINVAL;
        if (!length)
                goto err;
-       *m = mmap(NULL, length, prot, flags, fd, offset);
+       *m = mmap(NULL, length, prot, flags, fd, (off_t)0);
        if (*m != MAP_FAILED)
                return 1;
 err:
@@ -639,7 +637,7 @@ int mmap_full_file(const char *path, int open_mode, void **map,
        if (S_ISDIR(file_status.st_mode))
                goto out;
 
-       ret = para_mmap(*size, mmap_prot, mmap_flags, fd, 0, map);
+       ret = para_mmap(*size, mmap_prot, mmap_flags, fd, map);
 out:
        if (ret < 0 || !fd_ptr)
                close(fd);
diff --git a/fd.h b/fd.h
index 106f5a4ceaaae81209385a23a73092a22a0035c0..25eea8a27ceaaec24ac24a8e3ab210d5ff798b05 100644 (file)
--- a/fd.h
+++ b/fd.h
@@ -12,8 +12,7 @@ __must_check int mark_fd_nonblocking(int fd);
 __must_check int mark_fd_blocking(int fd);
 void para_fd_set(int fd, fd_set *fds, int *max_fileno);
 __must_check int para_fgets(char *line, int size, FILE *f);
-int para_mmap(size_t length, int prot, int flags, int fd, off_t offset,
-               void *map);
+int para_mmap(size_t length, int prot, int flags, int fd, void *map);
 int para_open(const char *path, int flags, mode_t mode);
 int para_mkdir(const char *path, mode_t mode);
 int para_chdir(const char *path);
index d5cb49a45c2d6da4e6249b6810a298a0460c8b1f..052546dd60733d143e6c12bdcfcc92ce36ac5e50 100644 (file)
--- a/gcrypt.c
+++ b/gcrypt.c
@@ -52,21 +52,22 @@ void get_random_bytes_or_die(unsigned char *buf, int num)
 }
 
 /*
- * This is called at the beginning of every program that uses libgcrypt. We
- * don't have to initialize any random seed here, but we must initialize the
- * gcrypt library. This task is performed by gcry_check_version() which can
- * also check that the gcrypt library version is at least the minimal required
- * version.
+ * This is called at the beginning of every program that uses libgcrypt. The
+ * call to gcry_check_version() initializes the gcrypt library and checks that
+ * we have at least the minimal required version.
  */
 void init_random_seed_or_die(void)
 {
        const char *req_ver = "1.5.0";
+       int seed;
 
-       if (gcry_check_version(req_ver))
-               return;
-       PARA_EMERG_LOG("fatal: need at least libgcrypt-%s, have: %s\n",
-               req_ver, gcry_check_version(NULL));
-       exit(EXIT_FAILURE);
+       if (!gcry_check_version(req_ver)) {
+               PARA_EMERG_LOG("fatal: need at least libgcrypt-%s, have: %s\n",
+                       req_ver, gcry_check_version(NULL));
+               exit(EXIT_FAILURE);
+       }
+       get_random_bytes_or_die((unsigned char *)&seed, sizeof(seed));
+       srandom(seed);
 }
 
 /** S-expression for the public part of an RSA key. */
index c581ebdd093e09cda16b8a08bba3fd4d689a4998..3a723299e78b241a9ac4f44a13caf91651f36b6a 100644 (file)
@@ -106,8 +106,10 @@ static int http_recv_post_select(struct sched *s, void *context)
        }
        if (phd->status == HTTP_SENT_GET_REQUEST) {
                ret = read_pattern(rn->fd, HTTP_OK_MSG, strlen(HTTP_OK_MSG), &s->rfds);
-               if (ret < 0)
+               if (ret < 0) {
+                       PARA_ERROR_LOG("did not receive HTTP OK message\n");
                        goto out;
+               }
                if (ret == 0)
                        return 0;
                PARA_INFO_LOG("received ok msg, streaming\n");
@@ -128,8 +130,10 @@ static int http_recv_post_select(struct sched *s, void *context)
                btr_add_output_pool(rn->btrp, num_bytes - iov[0].iov_len, btrn);
        }
 out:
-       if (ret < 0)
+       if (ret < 0) {
+               PARA_NOTICE_LOG("%s\n", para_strerror(-ret));
                btr_remove_node(&rn->btrn);
+       }
        return ret;
 }
 
index dace5c23c6574527a6b8c26880eb63bd896b8aca..210f85ac63c9dd718a3f00e6a6e9790ffeeb5d96 100644 (file)
@@ -16,6 +16,7 @@
 #include "error.h"
 #include "string.h"
 #include "afh.h"
+#include "net.h"
 #include "server.h"
 #include "http.h"
 #include "list.h"
@@ -23,7 +24,6 @@
 #include "sched.h"
 #include "vss.h"
 #include "close_on_fork.h"
-#include "net.h"
 #include "fd.h"
 #include "chunk_queue.h"
 #include "acl.h"
@@ -209,7 +209,8 @@ static void http_pre_select(int *max_fileno, fd_set *rfds, fd_set *wfds)
 
 static int http_com_on(__a_unused struct sender_command_data *scd)
 {
-       return generic_com_on(hss, IPPROTO_TCP);
+       generic_com_on(hss, IPPROTO_TCP);
+       return 1;
 }
 
 static int http_com_off(__a_unused struct sender_command_data *scd)
@@ -245,7 +246,6 @@ static char *http_status(void)
  */
 void http_send_init(struct sender *s)
 {
-       int ret;
        s->status = http_status;
        s->send = http_send;
        s->pre_select = http_pre_select;
@@ -265,7 +265,5 @@ void http_send_init(struct sender *s)
                OPT_GIVEN(HTTP_DEFAULT_DENY));
        if (OPT_GIVEN(HTTP_NO_AUTOSTART))
                return;
-       ret = generic_com_on(hss, IPPROTO_TCP);
-       if (ret < 0)
-               PARA_ERROR_LOG("%s\n", para_strerror(-ret));
+       generic_com_on(hss, IPPROTO_TCP);
 }
index 37ecbd8172035d63c4b8a4f47d11eb9a914525ec..3019f7693a1d986f53cfcea45d13e572a4295a5f 100644 (file)
@@ -170,7 +170,6 @@ caption = List of subcommands
                arg_info = required_arg
                arg_type = string
                typestr = mood_spec
-               default_val = m/fade
                [help]
                        This mood (or playlist) is selected right after setting the initial
                        volume.
@@ -195,7 +194,6 @@ caption = List of subcommands
                arg_info = required_arg
                arg_type = string
                typestr = mood_spec
-               default_val = m/sleep
                [help]
                        Select the given mood or playlist after the fade-out. If unset,
                        playback is stopped until fade-in starts.
@@ -217,7 +215,6 @@ caption = List of subcommands
                arg_info = required_arg
                arg_type = string
                typestr = mood_spec
-               default_val = m/wake
                [help]
                        This mood or playlist is selected right before fade-in begins.
                [/help]
index 793a2f5f98127d9bf2891280722f678fd874b54c..993a4494f0ba90823f68b933a806b7cd267c1706 100644 (file)
@@ -2,7 +2,16 @@ m4_define(PROGRAM, para_recv)
 [suite recv]
 version-string = GIT_VERSION()
 [supercommand para_recv]
-       purpose = a command line HTTP/DCCP/UDP stream grabber
+       purpose = receive an audio stream
+       [description]
+               para_recv starts one paraslash receiver (http, dccp, udp or afh)
+               to produce an audio stream in the same way para_audiod would download
+               the stream from para_server (http, dccp or udp) or para_server makes a
+               stream out of an audio file (afh). This is mostly useful for debugging.
+
+               Regardless of which receiver was started, the audio stream is written
+               to stdout.
+       [/description]
        m4_include(common-option-section.m4)
        m4_include(help.m4)
        m4_include(detailed-help.m4)
@@ -19,4 +28,6 @@ version-string = GIT_VERSION()
                        Any options for the selected receiver must be quoted. Example:
 
                                -r 'http -i www.paraslash.org -p 8009'
+
+                       If no receiver is given, http is assumed.
                [/help]
index 674a4487cf8380ee6b3927cc6507ee70b1022d25..de6c5a6870b708be42222aaea55c275bbba4dc01 100644 (file)
@@ -79,7 +79,7 @@ caption = receivers
 
                        The request is reconciled with the CCIDs on the server through the
                        'server-priority' mechanism of RFC 4340 6.3.1/10. The server CCIDs
-                       can be listed by calling 'para_client si'.
+                       can be listed by calling 'para_client sender dccp status'.
                [/help]
 [subcommand udp]
        purpose = receive an audio stream over UDP
diff --git a/mixer.c b/mixer.c
index 00af08a4e428b637dcb24ebc68545edb478ff61d..52af25f9c22ae5397f03c5bf61daaae0f1bb67bd 100644 (file)
--- a/mixer.c
+++ b/mixer.c
@@ -192,9 +192,6 @@ static void change_afs_mode(const char *afs_mode)
 {
        char *cmd;
 
-       client_cmd("stop");
-       if (!afs_mode)
-               return;
        cmd = make_message("select %s", afs_mode);
        client_cmd(cmd);
        free(cmd);
@@ -290,7 +287,7 @@ static int com_sleep(const struct mixer *m, struct mixer_handle *h)
        PARA_INFO_LOG("waketime: %d:%02d\n", tm->tm_hour, tm->tm_min);
        client_cmd("stop");
        sleep(1);
-       if (fot) {
+       if (fot && fo_mood) {
                ret = set_initial_volume(m, h);
                if (ret < 0)
                        return ret;
@@ -307,12 +304,13 @@ static int com_sleep(const struct mixer *m, struct mixer_handle *h)
                if (ret < 0)
                        return ret;
        }
-       if (OPT_GIVEN(SLEEP, SLEEP_MOOD)) {
+       if (sleep_mood) {
                change_afs_mode(sleep_mood);
-               client_cmd("play");
-       } else
+               if (!fot || !fo_mood) /* currently stopped */
+                       client_cmd("play");
+       } else if (fot && fo_mood) /* currently playing */
                client_cmd("stop");
-       if (!fit)
+       if (!fit || !fi_mood) /* nothing to do */
                return 1;
        change_afs_mode(fi_mood);
        for (;;) {
diff --git a/mood.c b/mood.c
index ae8364a29ea7b4028ebbe2bfb812ef6592b402c0..a63d4d2af5d10d7b64c319d915e00b9b7ea62e89 100644 (file)
--- a/mood.c
+++ b/mood.c
@@ -418,10 +418,13 @@ static int load_mood(const struct osl_row *mood_row, struct mood **m,
 
        *m = NULL;
        ret = mood_get_name_and_def_by_row(mood_row, &mood_name, &mood_def);
-       if (ret < 0)
+       if (ret < 0) {
+               if (errmsg)
+                       *errmsg = make_message(
+                               "could not read mood definition");
                return ret;
-       if (!*mood_name)
-               return -E_DUMMY_ROW;
+       }
+       assert(*mood_name);
        mlpd.m = alloc_new_mood(mood_name);
        ret = for_each_line(FELF_READ_ONLY, mood_def.data, mood_def.size,
                parse_mood_line, &mlpd);
@@ -876,7 +879,9 @@ int change_current_mood(const char *mood_name, char **errmsg)
                };
                ret = osl(osl_get_row(moods_table, BLOBCOL_NAME, &obj, &row));
                if (ret < 0) {
-                       PARA_NOTICE_LOG("no such mood: %s\n", mood_name);
+                       if (errmsg)
+                               *errmsg = make_message("no such mood: %s",
+                                       mood_name);
                        return ret;
                }
                ret = load_mood(row, &m, errmsg);
@@ -891,13 +896,20 @@ int change_current_mood(const char *mood_name, char **errmsg)
        aa.m = current_mood;
        PARA_NOTICE_LOG("computing statistics of admissible files\n");
        ret = audio_file_loop(&aa, add_if_admissible);
-       if (ret < 0)
+       if (ret < 0) {
+               if (errmsg)
+                       *errmsg = make_message("audio file loop failed");
                return ret;
+       }
        for (i = 0; i < statistics.num; i++) {
                struct admissible_file_info *a = aa.array + i;
                ret = add_to_score_table(a->aft_row, a->score);
-               if (ret < 0)
+               if (ret < 0) {
+                       if (errmsg)
+                               *errmsg = make_message(
+                                       "could not add row to score table");
                        goto out;
+               }
        }
        log_statistics();
        ret = statistics.num;
diff --git a/mp.c b/mp.c
index 3c84a05484cb38c15ba681c14c41cc37bb7cd932..c5702c625bf2125afd10f3dab8ce1627053ddb07 100644 (file)
--- a/mp.c
+++ b/mp.c
@@ -9,7 +9,7 @@
  * The public API (at the bottom of the file) allows to parse the same mood
  * definition many times in an efficient manner.
  *
- * The first function to all is \ref mp_init(), which analyzes the given mood
+ * The first function to call is \ref mp_init(), which analyzes the given mood
  * definition syntactically. It returns the abstract syntax tree of the mood
  * definition and pre-compiles all regular expression patterns to make later
  * pattern matching efficient.
diff --git a/net.c b/net.c
index 3f76d21c6cc9abf60ff5a98d1ac804f4b067ffef..1fece043586cddc782791d0ec18af45881797c5f 100644 (file)
--- a/net.c
+++ b/net.c
@@ -425,15 +425,20 @@ int makesock_addrinfo(unsigned l4type, bool passive, struct addrinfo *ai,
        for (; ai; ai = ai->ai_next) {
                int fd;
                ret = socket(ai->ai_family, sock_type(l4type), l4type);
-               if (ret < 0)
+               if (ret < 0) {
+                       PARA_NOTICE_LOG("socket(): %s\n", strerror(errno));
                        continue;
+               }
                fd = ret;
                flowopt_setopts(fd, fo);
                if (!passive) {
-                       if (connect(fd, ai->ai_addr, ai->ai_addrlen) == 0)
-                               return fd;
-                       close(fd);
-                       continue;
+                       if (connect(fd, ai->ai_addr, ai->ai_addrlen) < 0) {
+                               PARA_NOTICE_LOG("connect(): %s\n",
+                                       strerror(errno));
+                               close(fd);
+                               continue;
+                       }
+                       return fd;
                }
                /*
                 * Reuse the address on passive sockets to avoid failure on
@@ -442,10 +447,12 @@ int makesock_addrinfo(unsigned l4type, bool passive, struct addrinfo *ai,
                 */
                if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on,
                                sizeof(on)) == -1) {
+                       PARA_NOTICE_LOG("setsockopt(): %s\n", strerror(errno));
                        close(fd);
                        continue;
                }
                if (bind(fd, ai->ai_addr, ai->ai_addrlen) < 0) {
+                       PARA_NOTICE_LOG("bind(): %s\n", strerror(errno));
                        close(fd);
                        continue;
                }
@@ -496,16 +503,15 @@ int makesock(unsigned l4type, bool passive, const char *host, uint16_t port_numb
  *
  * \param l4type The transport-layer type (\p IPPROTO_xxx).
  * \param port The decimal port number to listen on.
- * \param fo Flowopts (if any) to set before starting to listen.
  *
  * \return Positive integer (socket descriptor) on success, negative value
  * otherwise.
  *
  * \sa \ref makesock(), ip(7), ipv6(7), bind(2), listen(2).
  */
-int para_listen(unsigned l4type, uint16_t port, struct flowopts *fo)
+int para_listen_simple(unsigned l4type, uint16_t port)
 {
-       int ret, fd = makesock(l4type, 1, NULL, port, fo);
+       int ret, fd = makesock(l4type, 1, NULL, port, NULL);
 
        if (fd > 0) {
                ret = listen(fd, BACKLOG);
diff --git a/net.h b/net.h
index f172131ef05d45c8d05f82a91ea9e72cd0160a16..143fb812f4c1be20368b93cbb60be26eaeb826fe 100644 (file)
--- a/net.h
+++ b/net.h
@@ -48,6 +48,9 @@
 #define DCCP_SOCKOPT_TX_CCID 14 /**< Set/get the TX CCID. */
 #endif
 
+/** The maximum length of the host component in an URL. */
+#define MAX_HOSTLEN 256
+
 /**
  * Flowopts: Transport-layer independent encapsulation of socket options
  *           that need to be registered prior to setting up a connection.
@@ -124,12 +127,8 @@ bool sockaddr_equal(const struct sockaddr *sa1, const struct sockaddr *sa2);
  */
 /** How many pending connections queue of a listening server will hold. */
 #define BACKLOG        10
-extern int para_listen(unsigned l4type, uint16_t port, struct flowopts *fo);
 
-static inline int para_listen_simple(unsigned l4type, uint16_t port)
-{
-       return para_listen(l4type, port, NULL);
-}
+int para_listen_simple(unsigned l4type, uint16_t port);
 
 /** Pretty-printing of IPv4/6 socket addresses */
 extern char *remote_name(int sockfd);
index 46465de1208b3c8edbb09972550bf4277667c7db..62cde3d465ab7c86a23d6c539b8a2b447d465f78 100644 (file)
@@ -154,7 +154,7 @@ int oac_get_file_info(char *map, size_t numbytes, struct afh_info *afhi,
        afhi->seconds_total = num_frames / afhi->frequency;
        /* use roughly one page per chunk */
        frames_per_chunk = num_frames / i;
-       PARA_INFO_LOG("%" PRIu32 "seconds, %d frames/chunk\n",
+       PARA_INFO_LOG("%" PRIu32 " seconds, %d frames/chunk\n",
                afhi->seconds_total, frames_per_chunk);
        ct_size = 250;
        afhi->chunk_table = para_malloc(ct_size * sizeof(uint32_t));
diff --git a/play.c b/play.c
index b304e427183d264b09d38eabbc0ec6c77990dec3..78d53fa8c7659c55f375c1e15a30ca5ac7f88488 100644 (file)
--- a/play.c
+++ b/play.c
@@ -139,7 +139,7 @@ static void handle_help_flags(void)
 
        if (OPT_GIVEN(DETAILED_HELP))
                help = lls_long_help(CMD_PTR);
-       else if (OPT_GIVEN(HELP))
+       else if (OPT_GIVEN(HELP) || lls_num_inputs(play_lpr) == 0)
                help = lls_short_help(CMD_PTR);
        else
                return;
@@ -163,7 +163,7 @@ static void parse_config_or_die(int argc, char *argv[])
                goto fail;
        loglevel = OPT_UINT32_VAL(LOGLEVEL);
        version_handle_flag("play", OPT_GIVEN(VERSION));
-       handle_help_flags();
+       handle_help_flags(); /* also handles the zero-arg case */
        if (OPT_GIVEN(CONFIG_FILE))
                cf = para_strdup(OPT_STRING_VAL(CONFIG_FILE));
        else {
@@ -178,7 +178,7 @@ static void parse_config_or_die(int argc, char *argv[])
                if (ret == -ERRNO_TO_PARA_ERROR(ENOENT) && OPT_GIVEN(CONFIG_FILE))
                        goto free_cf;
                ret = 0;
-               goto free_cf;
+               goto setup_keymap;
        }
        ret = lls(lls_convert_config(map, sz, NULL, &cf_argv, &errctx));
        para_munmap(map, sz);
@@ -196,10 +196,7 @@ static void parse_config_or_die(int argc, char *argv[])
        lls_free_parse_result(play_lpr, cmd);
        play_lpr = merged_lpr;
        loglevel = OPT_UINT32_VAL(LOGLEVEL);
-
-       ret = lls(lls_check_arg_count(play_lpr, 1, INT_MAX, &errctx));
-       if (ret < 0)
-               goto free_cf;
+setup_keymap:
        num_kmas = OPT_GIVEN(KEY_MAP);
        for (i = 0; i < num_kmas; i++) {
                const char *kma = lls_string_val(i, OPT_RESULT(KEY_MAP));
index 8a87b1f33fb063ca8d105683ddd74b091e4ffe2b..bbdda51c525630c6d1411dfa547193f8ccdae9ce 100644 (file)
@@ -155,6 +155,7 @@ static int resample_frames(int16_t *in, size_t num_frames, bool have_more,
                size_t *result_frames)
 {
        int ret, num_samples, out_samples;
+       float *in_float;
        int16_t *out;
        SRC_DATA data;
 
@@ -166,11 +167,12 @@ static int resample_frames(int16_t *in, size_t num_frames, bool have_more,
        data.output_frames = num_frames * ctx->ratio + 1;
        out_samples = data.output_frames * ctx->channels;
 
-       data.data_in = para_malloc(num_samples * sizeof(float));
-       src_short_to_float_array(in, data.data_in, num_samples);
+       in_float = para_malloc(num_samples * sizeof(float));
+       src_short_to_float_array(in, in_float, num_samples);
+       data.data_in = in_float;
        data.data_out = para_malloc(out_samples * sizeof(float));
        ret = src_process(ctx->src_state, &data);
-       free(data.data_in);
+       free(in_float);
        if (ret != 0) {
                PARA_ERROR_LOG("%s\n", src_strerror(ret));
                free(data.data_out);
diff --git a/send.h b/send.h
index 9a6e5f745c406abe4a91f34da7a104946922c1d5..84f35f9228cd05c62f9430063123d3e49761a06c 100644 (file)
--- a/send.h
+++ b/send.h
@@ -186,7 +186,7 @@ void generic_com_allow(struct sender_command_data *scd,
                struct sender_status *ss);
 void generic_com_deny(struct sender_command_data *scd,
                struct sender_status *ss);
-int generic_com_on(struct sender_status *ss, unsigned protocol);
+void generic_com_on(struct sender_status *ss, unsigned protocol);
 void generic_com_off(struct sender_status *ss);
 char *generic_sender_help(void);
 struct sender_client *accept_sender_client(struct sender_status *ss, fd_set *rfds);
index acb7aa6d06777863cccffe8a317749618b11060b..16820a5380395fabd841287448108a346a2fb4ca 100644 (file)
 /** Clients will be kicked if there are more than that many bytes pending. */
 #define MAX_CQ_BYTES 40000
 
-/**
- * Open a passive socket of given layer4 type.
- *
- * Set the resulting file descriptor to nonblocking mode and add it to the list
- * of fds that are being closed in the child process when the server calls
- * fork().
- *
- * \param l4type The transport-layer protocol.
- * \param port The port number.
- *
- * \return The listening fd on success, negative on errors.
- */
-static int open_sender(unsigned l4type, int port)
-{
-       int fd, ret = para_listen_simple(l4type, port);
-
-       if (ret < 0)
-               return ret;
-       fd = ret;
-       ret = mark_fd_nonblocking(fd);
-       if (ret < 0) {
-               close(fd);
-               return ret;
-       }
-       add_close_on_fork_list(fd);
-       return fd;
-}
-
 /**
  * Shut down a client connected to a paraslash sender.
  *
@@ -234,21 +206,38 @@ void generic_com_deny(struct sender_command_data *scd,
  * Activate a paraslash sender.
  *
  * \param ss The sender to activate.
- * \param protocol The symbolic name of the transport-layer protocol.
+ * \param protocol layer4 type (IPPROTO_TCP or IPPROTO_DCCP).
  *
- * \return Standard.
+ * This opens a passive socket of given layer4 type, sets the resulting file
+ * descriptor to nonblocking mode and adds it to the close on fork list.
+ *
+ * Errors are logged but otherwise ignored.
  */
-int generic_com_on(struct sender_status *ss, unsigned protocol)
+void generic_com_on(struct sender_status *ss, unsigned protocol)
 {
-       int ret;
+       int fd, ret;
 
        if (ss->listen_fd >= 0)
-               return 1;
-       ret = open_sender(protocol, ss->port);
-       if (ret < 0)
-               return ret;
-       ss->listen_fd = ret;
-       return 1;
+               return;
+       ret = para_listen_simple(protocol, ss->port);
+       if (ret < 0) {
+               PARA_ERROR_LOG("could not listen on port %d: %s\n", ss->port,
+                       para_strerror(-ret));
+               return;
+       }
+       fd = ret;
+       ret = mark_fd_nonblocking(fd);
+       if (ret < 0) {
+               PARA_ERROR_LOG("could not set %s socket fd for port %d to "
+                       "nonblocking mode: %s\n",
+                       protocol == IPPROTO_TCP? "TCP" : "DCCP", ss->port,
+                       para_strerror(-ret));
+               close(fd);
+               return;
+       }
+       add_close_on_fork_list(fd);
+       ss->listen_fd = fd;
+       return;
 }
 
 /**
@@ -277,9 +266,8 @@ void generic_com_off(struct sender_status *ss)
  * \param ss The sender whose listening fd is ready for reading.
  * \param rfds Passed to para_accept(),
  *
- * This must be called only if the socket fd of \a ss is ready for reading.  It
- * calls para_accept() to accept the connection and performs the following
- * actions on the resulting file descriptor \a fd:
+ * This calls para_accept() and performs the following actions on the resulting
+ * file descriptor fd:
  *
  *     - Checks whether the maximal number of connections are exceeded.
  *     - Sets \a fd to nonblocking mode.
index 2018b8eece1988206e2992f560b65fa73059ff5e..66c93ab259d1c26e26a904c312cd45916407cb2a 100644 (file)
--- a/server.c
+++ b/server.c
@@ -45,6 +45,7 @@
 #include "afh.h"
 #include "string.h"
 #include "afs.h"
+#include "net.h"
 #include "server.h"
 #include "list.h"
 #include "send.h"
@@ -52,7 +53,6 @@
 #include "vss.h"
 #include "config.h"
 #include "close_on_fork.h"
-#include "net.h"
 #include "daemon.h"
 #include "ipc.h"
 #include "fd.h"
@@ -86,7 +86,15 @@ struct lls_parse_result *server_lpr = NULL;
 /* Command line options (no config file options). Used in handle_sighup(). */
 static struct lls_parse_result *cmdline_lpr;
 
-/** A random value used in child context for authentication. */
+/**
+ * A random number used to "authenticate" the afs connection.
+ *
+ * para_server picks this number by random before it forks the afs process. The
+ * command handlers know this number as well and write it to the afs socket,
+ * together with the id of the shared memory area which contains the payload of
+ * the afs command. A local process has to know this number to abuse the afs
+ * service provided by the local socket.
+ */
 uint32_t afs_socket_cookie;
 
 /** The mutex protecting the shared memory area containing the mmd struct. */
@@ -177,7 +185,6 @@ void parse_config_or_die(bool reload)
        struct lls_parse_result *cf_lpr, *merged_lpr;
        char *home = para_homedir();
 
-       daemon_close_log();
        if (OPT_GIVEN(CONFIG_FILE))
                cf = para_strdup(OPT_STRING_VAL(CONFIG_FILE));
        else
@@ -454,7 +461,7 @@ static int init_afs(int argc, char **argv)
                i = argc - lls_num_inputs(cmdline_lpr) - 1;
                sprintf(argv[i], "para_server (afs)");
                close(afs_server_socket[0]);
-               afs_init(afs_socket_cookie, afs_server_socket[1]);
+               afs_init(afs_server_socket[1]);
        }
        close(afs_server_socket[1]);
        if (read(afs_server_socket[0], &c, 1) <= 0) {
index 1852dd50962b78a72d270bb1d20e61eb0d9911c4..988a98d8e17723817907787016cf9b58e771f545 100644 (file)
--- a/server.h
+++ b/server.h
@@ -5,10 +5,6 @@
 /** Size of the selector_info and audio_file info strings of struct misc_meta_data. */
 #define MMD_INFO_SIZE 16384
 
-/** The maximum length of the host component in an URL */
-#define MAX_HOSTLEN 256
-
-
 /** Arguments for the sender command. */
 struct sender_command_data {
        /** Greater than zero indicates that a sender cmd is already queued. */
index 49c17631487db2cabedb4acd5444bb589d602762..38d49e3e70e42bc72d9316a21a5ca5e5441106f3 100644 (file)
 #include "error.h"
 #include "string.h"
 #include "afh.h"
+#include "net.h"
 #include "server.h"
 #include "list.h"
 #include "send.h"
 #include "sched.h"
 #include "vss.h"
 #include "portable_io.h"
-#include "net.h"
 #include "fd.h"
 #include "close_on_fork.h"
 
diff --git a/vss.c b/vss.c
index 00c632c70674a034044f6c73c7f2c6b87bf63bd1..13a8e25fd0febc7aeeb56e8e37099f7ec4747a0f 100644 (file)
--- a/vss.c
+++ b/vss.c
@@ -25,8 +25,8 @@
 #include "string.h"
 #include "afh.h"
 #include "afs.h"
-#include "server.h"
 #include "net.h"
+#include "server.h"
 #include "list.h"
 #include "send.h"
 #include "sched.h"
@@ -997,7 +997,7 @@ static void recv_afs_result(struct vss_task *vsst, fd_set *rfds)
                goto err;
        }
        ret = para_mmap(statbuf.st_size, PROT_READ, MAP_PRIVATE | MAP_POPULATE,
-               passed_fd, 0, &vsst->map);
+               passed_fd, &vsst->map);
        if (ret < 0)
                goto err;
        vsst->mapsize = statbuf.st_size;