Merge branch 'refs/heads/t/rm_source_browser'
authorAndre Noll <maan@tuebingen.mpg.de>
Mon, 19 Dec 2016 17:06:52 +0000 (18:06 +0100)
committerAndre Noll <maan@tuebingen.mpg.de>
Mon, 19 Dec 2016 17:13:01 +0000 (18:13 +0100)
Cooking for five months.

A single patch which gets rid of the source browser generated with
global, reducing the size of the web pages considerably.

* refs/heads/t/rm_source_browser:
  web: Remove extra source browser.

25 files changed:
Makefile.real
NEWS.md
afh.c
afh_common.c
afs.c
audiod.c
audiod.h
audiod_command.c
client_common.c
command.c
daemon.c
daemon.h
error.h
filter.c
filter.h
filter_common.c
gcrypt.c
mood.c
mp3_afh.c
net.c
play.c
server.c
string.c
t/test-lib.sh
version.c

index 1385bb9..ce4881d 100644 (file)
@@ -19,6 +19,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 := 2016
 
 ifeq ("$(origin O)", "command line")
        build_dir := $(O)
@@ -64,9 +65,8 @@ tarball_pfx := $(PACKAGE_TARNAME)-$(GIT_VERSION)
 tarball_delete := $(addprefix $(tarball_pfx)/, web .gitignore)
 tarball := $(tarball_pfx).tar.bz2
 
-.PHONY: dep all clean clean2 distclean maintainer-clean install man tarball
-all: dep $(prefixed_executables) $(man_pages)
-dep: $(deps)
+.PHONY: all clean clean2 distclean maintainer-clean install man tarball
+all: $(prefixed_executables) $(man_pages)
 man: $(man_pages)
 tarball: $(tarball)
 
@@ -91,6 +91,7 @@ $(subst u,U,$(subst v,V,$(subst w,W,$(subst x,X,$(subst y,Y,\
 $(subst z,Z,$1))))))))))))))))))))))))))
 
 CPPFLAGS += -DBINDIR='"$(bindir)"'
+CPPFLAGS += -DCOPYRIGHT_YEAR='"$(COPYRIGHT_YEAR)"'
 CPPFLAGS += -DBUILD_DATE='"$(build_date)"'
 CPPFLAGS += -DUNAME_RS='"$(uname_rs)"'
 CPPFLAGS += -DCC_VERSION='"$(cc_version)"'
diff --git a/NEWS.md b/NEWS.md
index 71eb6cb..afc7f10 100644 (file)
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,6 +1,16 @@
 NEWS
 ====
 
+------------------------------------------
+0.5.7 (to be announced) "semantic density"
+------------------------------------------
+
+- One of the two source browsers has been removed from the web pages.
+  The doxygen API reference still contains an HTML version of each
+  source file.
+
+Download: [tarball](./releases/paraslash-git.tar.bz2)
+
 ---------------------------------------
 0.5.6 (2016-07-10) "cascading gradient"
 ---------------------------------------
diff --git a/afh.c b/afh.c
index 195b378..8975777 100644 (file)
--- a/afh.c
+++ b/afh.c
@@ -169,7 +169,7 @@ __noreturn static void print_help_and_die(void)
  */
 int main(int argc, char **argv)
 {
-       int i, ret, audio_format_num, fd;
+       int i, ret = 0, audio_format_num, fd;
        void *audio_file_data;
        size_t audio_file_size;
        struct afh_info afhi;
@@ -177,12 +177,9 @@ int main(int argc, char **argv)
        afh_cmdline_parser(argc, argv, &conf);
        loglevel = get_loglevel_by_name(conf.loglevel_arg);
        version_handle_flag("afh", conf.version_given);
-       if (conf.help_given || conf.detailed_help_given)
+       if (conf.help_given || conf.detailed_help_given || conf.inputs_num == 0)
                print_help_and_die();
        afh_init();
-       ret = -E_AFH_SYNTAX;
-       if (conf.inputs_num == 0)
-               goto out;
        for (i = 0; i < conf.inputs_num; i++) {
                int ret2;
                ret = mmap_full_file(conf.inputs[i], O_RDONLY, &audio_file_data,
index 063ae8f..f36c32e 100644 (file)
@@ -139,6 +139,38 @@ int guess_audio_format(const char *name)
        return -E_AUDIO_FORMAT;
 }
 
+/**
+ * Get the name of the given audio format.
+ *
+ * \param i The audio format number.
+ *
+ * \return This returns a pointer to statically allocated memory so it
+ * must not be freed by the caller.
+ */
+const char *audio_format_name(int i)
+{
+       if (i < 0 || i >= ARRAY_SIZE(afl) - 1)
+               return "???";
+       return afl[i].name;
+}
+
+static int get_file_info(int format, const char *path, char *data,
+               size_t size, int fd, struct afh_info *afhi)
+{
+       int ret;
+       const char *fmt = audio_format_name(format);
+
+       memset(afhi, 0, sizeof(*afhi));
+       ret = afl[format].get_file_info(data, size, fd, afhi);
+       if (ret < 0) {
+               PARA_WARNING_LOG("%s: %s format not detected: %s\n",
+                       path, fmt, para_strerror(-ret));
+               return ret;
+       }
+       PARA_NOTICE_LOG("%s: detected %s format\n", path, fmt);
+       return format;
+}
+
 /**
  * Call get_file_info() to obtain an afhi structure.
  *
@@ -163,31 +195,18 @@ int compute_afhi(const char *path, char *data, size_t size, int fd,
 {
        int ret, i, format;
 
-       afhi->header_len = 0;
-       afhi->techinfo = NULL;
-       afhi->tags.artist = NULL;
-       afhi->tags.title = NULL;
-       afhi->tags.year = NULL;
-       afhi->tags.album = NULL;
-       afhi->tags.comment = NULL;
        format = guess_audio_format(path);
-
        if (format >= 0) {
-               ret = afl[format].get_file_info(data, size, fd, afhi);
-               if (ret >= 0) {
-                       ret = format;
+               ret = get_file_info(format, path, data, size, fd, afhi);
+               if (ret >= 0)
                        goto success;
-               }
        }
        FOR_EACH_AUDIO_FORMAT(i) {
                if (i == format) /* we already tried this one to no avail */
                        continue;
-               ret = afl[i].get_file_info(data, size, fd, afhi);
-               if (ret >= 0) {
-                       ret = i;
+               ret = get_file_info(i, path, data, size, fd, afhi);
+               if (ret >= 0)
                        goto success;
-               }
-               PARA_WARNING_LOG("%s\n", para_strerror(-ret));
        }
        return -E_AUDIO_FORMAT;
 success:
@@ -233,21 +252,6 @@ void clear_afhi(struct afh_info *afhi)
        free(afhi->tags.comment);
 }
 
-/**
- * Get the name of the given audio format.
- *
- * \param i The audio format number.
- *
- * \return This returns a pointer to statically allocated memory so it
- * must not be freed by the caller.
- */
-const char *audio_format_name(int i)
-{
-       if (i < 0 || i >= ARRAY_SIZE(afl) - 1)
-               return "???";
-       return afl[i].name;
-}
-
 static inline size_t get_chunk_len(long unsigned chunk_num,
                const struct afh_info *afhi)
 {
diff --git a/afs.c b/afs.c
index 0163298..0accc45 100644 (file)
--- a/afs.c
+++ b/afs.c
@@ -607,14 +607,17 @@ static int com_select_callback(struct afs_callback_arg *aca)
        if (ret >= 0)
                goto out;
        /* ignore subsequent errors (but log them) */
-       para_printf(&aca->pbout, "could not activate %s: %s\n"
-               "switching back to %s\n",
-               arg, para_strerror(-ret), current_mop? current_mop : "dummy");
-       ret = activate_mood_or_playlist(current_mop, &num_admissible);
-       if (ret >= 0)
-               goto out;
-       para_printf(&aca->pbout, "could not activate %s: %s\nswitching to dummy\n",
-               current_mop, para_strerror(-ret));
+       para_printf(&aca->pbout, "could not activate %s\n", arg);
+       if (current_mop) {
+               int ret2;
+               para_printf(&aca->pbout, "switching back to %s\n", current_mop);
+               ret2 = activate_mood_or_playlist(current_mop, &num_admissible);
+               if (ret2 >= 0)
+                       goto out;
+               para_printf(&aca->pbout, "could not reactivate %s: %s\n",
+                       current_mop, para_strerror(-ret2));
+       }
+       para_printf(&aca->pbout, "activating dummy mood\n");
        activate_mood_or_playlist(NULL, &num_admissible);
 out:
        para_printf(&aca->pbout, "activated %s (%d admissible files)\n",
index 2f9d5da..285d276 100644 (file)
--- a/audiod.c
+++ b/audiod.c
@@ -164,7 +164,7 @@ int audiod_status = AUDIOD_ON;
  * the gengetopt args_info struct that holds information on all command line
  * arguments
  */
-struct audiod_args_info conf;
+static struct audiod_args_info conf;
 
 static char *socket_name;
 static struct audio_format_info afi[NUM_AUDIO_FORMATS];
@@ -596,7 +596,8 @@ static void open_filters(struct slot_info *s)
                        EMBRACE(.name = f->name, .parent = parent,
                                .handler = f->execute, .context = fn));
 
-               f->open(fn);
+               if (f->open)
+                       f->open(fn);
                sprintf(buf, "%s (slot %d)", f->name, (int)(s - slot));
                fn->task = task_register(&(struct task_info) {
                        .name = buf,
@@ -1123,7 +1124,7 @@ static int command_post_select(struct sched *s, void *context)
        for (i = 0; i < 2; i++) {
                if (ct->fd[i] < 0)
                        continue;
-               ret = handle_connect(ct->fd[i], &s->rfds, uid_whitelist);
+               ret = handle_connect(ct->fd[i], &s->rfds);
                if (ret < 0) {
                        PARA_ERROR_LOG("%s\n", para_strerror(-ret));
                        if (ret == -E_AUDIOD_TERM) {
@@ -1448,6 +1449,29 @@ __noreturn static void print_help_and_die(void)
        exit(0);
 }
 
+/**
+ * Lookup the given UID in the whitelist.
+ *
+ * The whitelist is the array of arguments to the --user-allow opion. If the
+ * option was not given, the array is empty, in which case the check succeeds.
+ *
+ * \param uid User ID to look up.
+ *
+ * \return True if --user-allow was not given, or if uid matches an element of
+ * the whitelist.
+ */
+bool uid_is_whitelisted(uid_t uid)
+{
+       int i;
+
+       if (!conf.user_allow_given)
+               return true;
+       for (i = 0; i < conf.user_allow_given; i++)
+               if (uid == uid_whitelist[i])
+                       return true;
+       return false;
+}
+
 /**
  * the main function of para_audiod
  *
@@ -1483,8 +1507,11 @@ int main(int argc, char *argv[])
        daemon_set_priority(conf.priority_arg);
        daemon_drop_privileges_or_die(conf.user_arg, conf.group_arg);
        parse_config_or_die();
-       daemon_init_colors_or_die(conf.color_arg, color_arg_auto, color_arg_no,
-               conf.logfile_given, conf.log_color_arg, conf.log_color_given);
+       if (daemon_init_colors_or_die(conf.color_arg, color_arg_auto, color_arg_no,
+               conf.logfile_given)) {
+                       for (i = 0; i < conf.log_color_given; i++)
+                               daemon_set_log_color_or_die(conf.log_color_arg[i]);
+       }
        init_random_seed_or_die();
        daemon_set_flag(DF_LOG_TIME);
        daemon_set_flag(DF_LOG_HOSTNAME);
index b9cfb25..7073c6d 100644 (file)
--- a/audiod.h
+++ b/audiod.h
@@ -22,15 +22,17 @@ extern const char *audio_formats[];
  */
 enum audiod_status_info {AUDIOD_OFF, AUDIOD_ON, AUDIOD_STANDBY};
 
-extern struct audiod_args_info conf;
 extern int audiod_status;
 
-int handle_connect(int accept_fd, fd_set *rfds, uid_t *uid_whitelist);
-void audiod_status_dump(bool force);
+/* defined in audiod.c */
+struct btr_node *audiod_get_btr_root(void);
 __malloc char *audiod_get_decoder_flags(void);
+void clear_and_dump_items(void);
 char *get_time_string(void);
-struct btr_node *audiod_get_btr_root(void);
+bool uid_is_whitelisted(uid_t uid);
 
-void stat_client_write_item(int item_num);
-void clear_and_dump_items(void);
+/* defined in audiod_command.c */
+void audiod_status_dump(bool force);
 void close_stat_clients(void);
+int handle_connect(int accept_fd, fd_set *rfds);
+void stat_client_write_item(int item_num);
index 278e6ef..3a39027 100644 (file)
@@ -404,24 +404,11 @@ static int com_version(int fd, int argc, char **argv)
        return ret < 0? ret : 0;
 }
 
-static int check_perms(uid_t uid, uid_t *whitelist)
-{
-       int i;
-
-       if (!conf.user_allow_given)
-               return 1;
-       for (i = 0; i < conf.user_allow_given; i++)
-               if (uid == whitelist[i])
-                       return 1;
-       return -E_UCRED_PERM;
-}
-
 /**
  * Handle arriving connections on the local socket.
  *
  * \param accept_fd The fd to accept connections on.
  * \param rfds If \a accept_fd is not set in \a rfds, do nothing.
- * \param uid_whitelist Array of UIDs which are allowed to connect.
  *
  * This is called in each iteration of the select loop. If there is an incoming
  * connection on \a accept_fd, this function reads the command sent by the peer,
@@ -434,7 +421,7 @@ static int check_perms(uid_t uid, uid_t *whitelist)
  *
  * \sa para_accept(), recv_cred_buffer()
  * */
-int handle_connect(int accept_fd, fd_set *rfds, uid_t *uid_whitelist)
+int handle_connect(int accept_fd, fd_set *rfds)
 {
        int i, argc, ret, clifd;
        char buf[MAXLINE], **argv = NULL;
@@ -448,9 +435,9 @@ int handle_connect(int accept_fd, fd_set *rfds, uid_t *uid_whitelist)
        if (ret < 0)
                goto out;
        uid = ret;
-       PARA_INFO_LOG("connection from user %i, buf: %s\n", ret, buf);
-       ret = check_perms(uid, uid_whitelist);
-       if (ret < 0)
+       PARA_INFO_LOG("connection from UID %d, buf: %s\n", ret, buf);
+       ret = -E_UCRED_PERM;
+       if (!uid_is_whitelisted(uid))
                goto out;
        ret = create_argv(buf, "\n", &argv);
        if (ret <= 0)
index cd1ccc6..eea7510 100644 (file)
@@ -292,11 +292,6 @@ static int client_post_select(struct sched *s, void *context)
                if (ret < 0 || n == 0)
                        goto out;
                ct->features = parse_features(buf);
-               if (!has_feature("sideband", ct)) {
-                       PARA_ERROR_LOG("server has no sideband support\n");
-                       ret = -E_INCOMPAT_FEAT;
-                       goto out;
-               }
                ct->status = CL_RECEIVED_WELCOME;
                return 0;
        case CL_RECEIVED_WELCOME: /* send auth command */
index 93de2d2..0eb4efc 100644 (file)
--- a/command.c
+++ b/command.c
@@ -807,7 +807,6 @@ static void reset_signals(void)
 }
 
 struct connection_features {
-       bool sideband_requested;
        bool aes_ctr128_requested;
 };
 
@@ -835,8 +834,8 @@ static int parse_auth_request(char *buf, int len, struct user **u,
                create_argv(p, ",", &features);
                for (i = 0; features[i]; i++) {
                        if (strcmp(features[i], "sideband") == 0)
-                               cf->sideband_requested = true;
-                       else if (strcmp(features[i], "aes_ctr128") == 0)
+                               continue;
+                       if (strcmp(features[i], "aes_ctr128") == 0)
                                cf->aes_ctr128_requested = true;
                        else {
                                ret = -E_BAD_FEATURE;
@@ -949,11 +948,6 @@ __noreturn void handle_connect(int fd, const char *peername)
        ret = parse_auth_request(buf, ret, &cc->u, &cf);
        if (ret < 0)
                goto net_err;
-       if (!cf.sideband_requested) { /* sideband is mandatory */
-               PARA_ERROR_LOG("client did not request sideband\n");
-               ret = -E_BAD_FEATURE;
-               goto net_err;
-       }
        if (cc->u) {
                get_random_bytes_or_die(rand_buf, sizeof(rand_buf));
                ret = pub_encrypt(cc->u->pubkey, rand_buf, sizeof(rand_buf),
index 945c5a3..7c625bb 100644 (file)
--- a/daemon.c
+++ b/daemon.c
@@ -54,12 +54,12 @@ static void daemon_set_default_log_colors(void)
                color_parse_or_die(default_log_colors[i], me->log_colors[i]);
 }
 
-/*
+/**
  * Set the color for one loglevel.
  *
- * arg must be of the form "ll:[fg [bg]] [attr]".
+ * \param arg Must be of the form "ll:[fg [bg]] [attr]".
  */
-static void daemon_set_log_color_or_die(char const *arg)
+void daemon_set_log_color_or_die(const char *arg)
 {
        char *p = strchr(arg, ':');
        int ret, ll;
@@ -85,36 +85,31 @@ err:
  * \param color_arg_auto The value for automatic color detection.
  * \param color_arg_no The value to disable colored log messages.
  * \param logfile_given In auto mode colors are disabled if this value is true.
- * \param log_color_argv Color specifiers given to --log-color.
- * \param argc Number of color specifiers in \a log_color_argv.
  *
- * If \a color_arg equals \a color_arg_no, color mode is disabled, i.e., calls
- * to \a para_log() will not produce colored output. If \a color_arg == \a
- * color_arg_auto, the function autodetects whether to activate colors.
- * Otherwise color mode is enabled.
+ * If color_arg equals color_arg_no, color mode is disabled. That is, calls to
+ * para_log() will not produce colored output. If color_arg equals
+ * color_arg_auto, the function detects automatically whether to activate
+ * colors. Otherwise color mode is enabled.
+ *
+ * If color mode is to be enabled, the default colors are set for each
+ * loglevel. They can be overwritten by calling daemon_set_log_color_or_die().
  *
- * If color mode is to be enabled, the strings in \a log_color_argv are parsed
- * and the color scheme is updated accordingly. For each loglevel, the default
- * colors apply if there is no log_color_argv for this loglevel.
+ * \return Whether colors have been enabled by the function.
  */
-void daemon_init_colors_or_die(int color_arg, int color_arg_auto,
-               int color_arg_no, bool logfile_given, char **log_color_argv,
-               int argc)
+bool daemon_init_colors_or_die(int color_arg, int color_arg_auto,
+               int color_arg_no, bool logfile_given)
 {
-       int i;
-
        if (color_arg == color_arg_no)
-               return;
+               return false;
        if (color_arg == color_arg_auto) {
                if (logfile_given)
-                       return;
+                       return false;
                if (!isatty(STDERR_FILENO))
-                       return;
+                       return false;
        }
        daemon_set_flag(DF_COLOR_LOG);
        daemon_set_default_log_colors();
-       for (i = 0; i < argc; i++)
-               daemon_set_log_color_or_die(log_color_argv[i]);
+       return true;
 }
 
 /**
index e97678d..c715360 100644 (file)
--- a/daemon.h
+++ b/daemon.h
@@ -13,9 +13,9 @@ __malloc char *daemon_get_uptime_str(const struct timeval *current_time);
 void daemon_set_logfile(const char *logfile_name);
 void daemon_set_flag(unsigned flag);
 void daemon_set_loglevel(const char *loglevel);
-void daemon_init_colors_or_die(int color_arg, int color_arg_auto,
-               int color_arg_no, bool logfile_given, char **log_color_argv,
-               int argc);
+bool daemon_init_colors_or_die(int color_arg, int color_arg_auto,
+               int color_arg_no, bool logfile_given);
+void daemon_set_log_color_or_die(const char *arg);
 __printf_2_3 void daemon_log(int ll, const char* fmt,...);
 
 /** Daemon log configuration flags. */
diff --git a/error.h b/error.h
index 3d58e63..3fda578 100644 (file)
--- a/error.h
+++ b/error.h
@@ -103,7 +103,7 @@ extern const char **para_errlist[];
 
 
 #define AFH_RECV_ERRORS \
-       PARA_ERROR(AFH_RECV_BAD_FILENAME, "invalid file name"), \
+       PARA_ERROR(AFH_RECV_BAD_FILENAME, "no file name given"), \
 
 
 #define OGG_AFH_COMMON_ERRORS \
@@ -306,7 +306,6 @@ extern const char **para_errlist[];
        PARA_ERROR(SERVER_EOF, "connection closed by para_server"), \
        PARA_ERROR(SERVER_CMD_SUCCESS, "command terminated successfully"), \
        PARA_ERROR(SERVER_CMD_FAILURE, "command failed"), \
-       PARA_ERROR(INCOMPAT_FEAT, "client/server incompatibility"), \
 
 
 #define NET_ERRORS \
index 9378e46..804b5e1 100644 (file)
--- a/filter.c
+++ b/filter.c
@@ -142,7 +142,8 @@ int main(int argc, char *argv[])
                ti.pre_select = f->pre_select;
                ti.post_select = f->post_select;
                ti.context = fn;
-               f->open(fn);
+               if (f->open)
+                       f->open(fn);
                fn->task = task_register(&ti, &s);
                parent = fn->btrn;
        }
index 686776a..0bd5469 100644 (file)
--- a/filter.h
+++ b/filter.h
@@ -58,17 +58,18 @@ struct filter {
        /**
         * Open one instance of this filter.
         *
-        * This should allocate the output buffer of the given filter node and do any
-        * other filter-specific preparations like initializing the private_data member
-        * of \a fn suitably. The open function is assumed to succeed.
+        * This should allocate the output buffer of the given filter node and
+        * do any other filter-specific preparations like initializing the
+        * private_data member of \a fn suitably. The open function is
+        * optional, If it is provided, it is assumed to succeed.
         */
        void (*open)(struct filter_node *fn);
        /**
         * Close one instance of this filter.
         *
-        * Free all resources of associated with \a fn that were previously allocated
-        * by the open() function. It's OK to leave this alone if the filter does not
-        * need any cleanups.
+        * Free all resources associated with \a fn that were previously
+        * allocated by the open() function. It's OK to set this to NULL if the
+        * filter does not need to perform any cleanup operation.
         */
        void (*close)(struct filter_node *fn);
        /**
@@ -121,7 +122,7 @@ struct filter {
 };
 
 void filter_init(void);
-int check_filter_arg(char *filter_arg, void **conf);
+int check_filter_arg(const char *fa, void **conf);
 void print_filter_helps(unsigned flags);
 void generic_filter_pre_select(struct sched *s, void *context);
 int decoder_execute(const char *cmd, unsigned sample_rate, unsigned channels,
index 6fb9bd9..84863b3 100644 (file)
@@ -58,7 +58,7 @@ void filter_init(void)
  * If the filter has a command line parser and options is not NULL, run it.
  * Returns filter_num on success, negative on errors
  */
-static int parse_filter_args(int filter_num, char *options, void **conf)
+static int parse_filter_args(int filter_num, const char *options, void **conf)
 {
        const struct filter *f = filter_get(filter_num);
        int ret, argc;
@@ -78,11 +78,12 @@ static int parse_filter_args(int filter_num, char *options, void **conf)
 /**
  * Check the filter command line options.
  *
- * \param fa The command line options.
+ * \param fa The filter argument.
  * \param conf Points to the filter configuration upon successful return.
  *
- * Check if \a fa starts with a the name of a supported filter, followed by
- * a colon. If yes, call the command line parser of that filter.
+ * Check if the given filter argument starts with the name of a supported
+ * filter, optionally followed by options for this filter. If yes, call the
+ * command line parser of that filter.
  *
  * \return On success, the number of the filter is returned and \a conf
  * is initialized to point to the filter configuration determined by \a fa.
@@ -93,7 +94,7 @@ static int parse_filter_args(int filter_num, char *options, void **conf)
  *
  * \sa filter::parse_config
  */
-int check_filter_arg(char *fa, void **conf)
+int check_filter_arg(const char *fa, void **conf)
 {
        int j;
 
index 45a1c67..3c6c1ad 100644 (file)
--- a/gcrypt.c
+++ b/gcrypt.c
@@ -212,7 +212,7 @@ static int decode_key(const char *key_file, const char *header_str,
 
        ret = mmap_full_file(key_file, O_RDONLY, &map, &map_size, NULL);
        if (ret < 0)
-               return ret;
+               goto out;
        ret = -E_KEY_MARKER;
        if (strncmp(map, header_str, strlen(header_str)))
                goto unmap;
@@ -257,6 +257,7 @@ unmap:
                free(blob);
                blob = NULL;
        }
+out:
        *result = blob;
        return ret;
 }
@@ -781,6 +782,9 @@ int priv_decrypt(const char *key_file, unsigned char *outbuf,
        gcry_sexp_t in, out, priv_key;
        size_t nbytes;
 
+       ret = check_key_file(key_file, true);
+       if (ret < 0)
+               return ret;
        PARA_INFO_LOG("decrypting %d byte input\n", inlen);
        /* key_file -> asymmetric key priv */
        ret = get_private_key(key_file, &priv);
diff --git a/mood.c b/mood.c
index 83c3a57..940d72a 100644 (file)
--- a/mood.c
+++ b/mood.c
@@ -19,6 +19,7 @@
 #include "mm.h"
 #include "sideband.h"
 #include "mood.h"
+#include "sched.h"
 
 /**
  * Contains statistical data of the currently admissible audio files.
@@ -753,16 +754,27 @@ static int mood_update_audio_file(const struct osl_row *aft_row,
 static void log_statistics(void)
 {
        unsigned n = statistics.num;
+       int mean_days, sigma_days;
+       /*
+        * We can not use the "now" pointer from sched.c here because we are
+        * called before schedule(), which initializes "now".
+        */
+       struct timeval rnow;
 
+       assert(current_mood);
+       PARA_NOTICE_LOG("loaded mood %s\n", current_mood->name?
+               current_mood->name : "(dummy)");
        if (!n) {
-               PARA_NOTICE_LOG("no admissible files\n");
+               PARA_WARNING_LOG("no admissible files\n");
                return;
        }
-       PARA_INFO_LOG("last_played mean: %lli, last_played sigma: %llu\n",
-               (long long int)(statistics.last_played_sum / n),
-               (long long unsigned)int_sqrt(statistics.last_played_qd / n));
-       PARA_INFO_LOG("num_played mean: %lli, num_played sigma: %llu\n",
-               (long long int)statistics.num_played_sum / n,
+       PARA_NOTICE_LOG("%u admissible files\n", statistics.num);
+       clock_get_realtime(&rnow);
+       mean_days = (rnow.tv_sec - statistics.last_played_sum / n) / 3600 / 24;
+       sigma_days = int_sqrt(statistics.last_played_qd / n) / 3600 / 24;
+       PARA_NOTICE_LOG("last_played mean/sigma: %d/%d days\n", mean_days, sigma_days);
+       PARA_NOTICE_LOG("num_played mean/sigma: %llu/%llu\n",
+               (long long unsigned)statistics.num_played_sum / n,
                (long long unsigned)int_sqrt(statistics.num_played_qd / n));
 }
 
@@ -829,15 +841,13 @@ int change_current_mood(const char *mood_name)
        ret = audio_file_loop(&aa, add_if_admissible);
        if (ret < 0)
                return ret;
-       log_statistics();
-       PARA_INFO_LOG("%d admissible files\n", statistics.num);
        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)
                        goto out;
        }
-       PARA_NOTICE_LOG("loaded mood %s\n", mood_name? mood_name : "(dummy)");
+       log_statistics();
        ret = statistics.num;
 out:
        free(aa.array);
index 382b0e9..70f2ec9 100644 (file)
--- a/mp3_afh.c
+++ b/mp3_afh.c
@@ -662,7 +662,6 @@ static int mp3_read_info(unsigned char *map, size_t numbytes, int fd,
                header_mode(&header), tag_versions[ret]);
        return 1;
 err_out:
-       PARA_ERROR_LOG("%s\n", para_strerror(-ret));
        free(afhi->chunk_table);
        return ret;
 }
diff --git a/net.c b/net.c
index 1b142a3..1369498 100644 (file)
--- a/net.c
+++ b/net.c
@@ -175,8 +175,7 @@ char *parse_url(const char *url,
        }
 
        if (*o == ':')
-               if (para_atoi32(++o, port) < 0 ||
-                   *port < 0 || *port > 0xffff)
+               if (para_atoi32(++o, port) < 0 || *port < 0 || *port > 0xffff)
                        goto failed;
        if (host_string_ok(host))
                return host;
@@ -187,6 +186,7 @@ failed:
 
 /**
  * Stringify port number, resolve into service name where defined.
+ *
  * \param port 2-byte port number, in host-byte-order.
  * \param transport Transport protocol name (e.g. "udp", "tcp"), or NULL.
  * \return Pointer to static result buffer.
diff --git a/play.c b/play.c
index a7ce563..d2539ee 100644 (file)
--- a/play.c
+++ b/play.c
@@ -397,7 +397,8 @@ static int load_file(struct play_task *pt)
        pt->fn.btrn = btr_new_node(&(struct btr_node_description)
                EMBRACE(.name = decoder->name, .parent = pt->rn.btrn,
                        .handler = decoder->execute, .context = &pt->fn));
-       decoder->open(&pt->fn);
+       if (decoder->open)
+               decoder->open(&pt->fn);
 
        /* setup default writer */
        pt->wn.conf = check_writer_arg_or_die(NULL, &pt->wn.writer_num);
index 71a9ec5..088cc8b 100644 (file)
--- a/server.c
+++ b/server.c
@@ -207,8 +207,12 @@ void parse_config_or_die(int override)
                daemon_open_log_or_die();
        }
 
-       daemon_init_colors_or_die(conf.color_arg, color_arg_auto, color_arg_no,
-               conf.logfile_given, conf.log_color_arg, conf.log_color_given);
+       if (daemon_init_colors_or_die(conf.color_arg, color_arg_auto, color_arg_no,
+                       conf.logfile_given)) {
+               int i;
+               for (i = 0; i < conf.log_color_given; i++)
+                       daemon_set_log_color_or_die(conf.log_color_arg[i]);
+       }
        daemon_set_flag(DF_LOG_PID);
        daemon_set_flag(DF_LOG_LL);
        daemon_set_flag(DF_LOG_TIME);
index 86e7753..6033a00 100644 (file)
--- a/string.c
+++ b/string.c
@@ -803,15 +803,18 @@ err:
  * Split a buffer into words.
  *
  * This parser honors single and double quotes, backslash-escaped characters
- * and special characters like \p \\n. The result contains pointers to copies
- * of the words contained in \a buf and has to be freed by using \ref
- * free_argv().
+ * and special characters like \\n. The result contains pointers to copies of
+ * the words contained in buf and has to be freed by using \ref free_argv().
  *
  * \param buf The buffer to be split.
  * \param delim Each character in this string is treated as a separator.
  * \param result The array of words is returned here.
  *
- * \return Number of words in \a buf, negative on errors.
+ * It's OK to pass NULL as the buffer argument. This is equivalent to passing
+ * the empty string.
+ *
+ * \return Number of words in buf, negative on errors. The array returned
+ * through the result pointer is NULL terminated.
  */
 int create_argv(const char *buf, const char *delim, char ***result)
 {
index 99e575d..1f9913e 100644 (file)
@@ -156,7 +156,7 @@ test_require_executables()
 test_duration()
 {
        local t=$(exec 2>&1 1>/dev/null; time -p "$@")
-       result=$(awk '{print $2 * 1000}' <<< $t)
+       result=$(awk '{print $2 * 1000; exit 0}' <<< "$t")
 }
 
 test_expect_success()
index 6cbb053..bc61f54 100644 (file)
--- a/version.c
+++ b/version.c
@@ -43,7 +43,7 @@ const char *version_text(const char *pfx)
        static char buf[512];
 
        snprintf(buf, sizeof(buf) - 1, "%s\n"
-               "Copyright (C) 2002-2016 Andre Noll\n"
+               "Copyright (C) " COPYRIGHT_YEAR " Andre Noll\n"
                "This is free software with ABSOLUTELY NO WARRANTY."
                " See COPYING for details.\n"
                "Report bugs to <maan@tuebingen.mpg.de>.\n"