Merge branch 't/map_populate'
authorAndre Noll <maan@systemlinux.org>
Mon, 24 Oct 2011 13:31:31 +0000 (15:31 +0200)
committerAndre Noll <maan@systemlinux.org>
Mon, 24 Oct 2011 13:34:25 +0000 (15:34 +0200)
35 files changed:
NEWS
aac_afh.c
afs.c
aft.c
attribute.c
audiod.c
audiod_command.c
autogen.sh
blob.c
command.c
crypt.c
crypt.h
daemon.c
daemon.h
dccp_recv.c
error.h
imdct.c
ipc.c
ipc.h
mood.c
mp3_afh.c
net.c
net.h
ogg_afh.c
oggdec_filter.c
para.h
playlist.c
recv.h
sched.c
server.c
string.c
time.c
vss.c
wma_common.c
wmadec_filter.c

diff --git a/NEWS b/NEWS
index 50f9b69..3a70272 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,16 @@
 0.4.9 (to be announced) "hybrid causality"
 ------------------------------------------
 
+       - Fix for an endless loop in the mp3 decoder for certain
+         (corrupt) mp3 files.
+       - autogen.sh now detects a distcc setup and adjusts the
+         parameter for the -j option of make accordingly.
+       - Shared memory areas are no longer restricted to 64K. We now
+         detect the maximal size of a shared memory area at runtime.
+       - cleanup of the internal uptime API.
+       - para_server prefaults the mmapped audio file to avoid
+         delays on slow media.
+
 --------------------------------------
 0.4.8 (2011-08-19) "nested assignment"
 --------------------------------------
index a53a757..7acb011 100644 (file)
--- a/aac_afh.c
+++ b/aac_afh.c
@@ -191,8 +191,7 @@ static int aac_set_chunk_tv(struct afh_info *afhi,
 {
        float tmp = mp4ASC->sbr_present_flag == 1? 2047 : 1023;
        struct timeval total;
-       long unsigned ms = 1000.0 * afhi->chunks_total * tmp
-               / mp4ASC->samplingFrequency;
+       long unsigned ms;
 
        if (!mp4ASC->samplingFrequency)
                return -E_MP4ASC;
diff --git a/afs.c b/afs.c
index 755537d..3f37805 100644 (file)
--- a/afs.c
+++ b/afs.c
@@ -286,6 +286,9 @@ out:
  * command. This function allows to pass such a structure together with a list
  * of further arguments (often a list of audio files) to the parent process.
  *
+ * \return The return value of the underlying call to \ref
+ * send_callback_request().
+ *
  * \sa send_standard_callback_request(), send_callback_request().
  */
 int send_option_arg_callback_request(struct osl_object *options,
@@ -537,7 +540,7 @@ static int activate_mood_or_playlist(char *arg, int *num_admissible)
 static void com_select_callback(int fd, const struct osl_object *query)
 {
        struct para_buffer pb = {
-               .max_size = SHMMAX,
+               .max_size = shm_get_shmmax(),
                .private_data = &fd,
                .max_size_handler = pass_buffer_as_shm
        };
@@ -1146,7 +1149,8 @@ void afs_event(enum afs_events event, struct para_buffer *pb,
  * \param pb Unused.
  * \param data Unused.
  *
- * This table does not honor events.
+ * \return The images table does not honor events, so this handler always
+ * returns success.
  */
 __a_const int images_event_handler(__a_unused enum afs_events event,
        __a_unused  struct para_buffer *pb, __a_unused void *data)
@@ -1161,7 +1165,8 @@ __a_const int images_event_handler(__a_unused enum afs_events event,
  * \param pb Unused.
  * \param data Unused.
  *
- * This table does not honor events.
+ * \return The lyrics table does not honor events, so this handler always
+ * returns success.
  */
 __a_const int lyrics_event_handler(__a_unused enum afs_events event,
        __a_unused struct para_buffer *pb, __a_unused void *data)
diff --git a/aft.c b/aft.c
index f408023..3d22e24 100644 (file)
--- a/aft.c
+++ b/aft.c
@@ -1037,7 +1037,7 @@ static int make_status_items(struct audio_file_data *afd,
                .flags = LS_FLAG_FULL_PATH | LS_FLAG_ADMISSIBLE_ONLY,
                .mode = LS_MODE_VERBOSE,
        };
-       struct para_buffer pb = {.max_size = SHMMAX - 1};
+       struct para_buffer pb = {.max_size = shm_get_shmmax() - 1};
        time_t current_time;
        int ret;
 
@@ -1048,7 +1048,7 @@ static int make_status_items(struct audio_file_data *afd,
        free(status_items);
        status_items = pb.buf;
        memset(&pb, 0, sizeof(pb));
-       pb.max_size = SHMMAX - 1;
+       pb.max_size = shm_get_shmmax() - 1;
        pb.flags = PBF_SIZE_PREFIX;
        ret = print_list_item(&d, &opts, &pb, current_time);
        if (ret < 0) {
@@ -1343,7 +1343,7 @@ static void com_ls_callback(int fd, const struct osl_object *query)
 {
        struct ls_options *opts = query->data;
        char *p, *pattern_start = (char *)query->data + sizeof(*opts);
-       struct para_buffer b = {.max_size = SHMMAX,
+       struct para_buffer b = {.max_size = shm_get_shmmax(),
                .flags = (opts->mode == LS_MODE_PARSER)? PBF_SIZE_PREFIX : 0,
                .max_size_handler = pass_buffer_as_shm, .private_data = &fd};
        int i = 0, ret;
@@ -1665,7 +1665,7 @@ static void com_add_callback(int fd, const struct osl_object *query)
        char afsi_buf[AFSI_SIZE];
        uint32_t flags = read_u32(buf + CAB_FLAGS_OFFSET);
        struct afs_info default_afsi = {.last_played = 0};
-       struct para_buffer msg = {.max_size = SHMMAX,
+       struct para_buffer msg = {.max_size = shm_get_shmmax(),
                .max_size_handler = pass_buffer_as_shm, .private_data = &fd};
        uint16_t afhi_offset, chunks_offset;
 
@@ -2080,7 +2080,7 @@ static void com_touch_callback(int fd, const struct osl_object *query)
 {
        struct touch_action_data tad = {.cto = query->data,
                .pb = {
-                       .max_size = SHMMAX,
+                       .max_size = shm_get_shmmax(),
                        .private_data = &fd,
                        .max_size_handler = pass_buffer_as_shm
                }
@@ -2226,7 +2226,7 @@ static void com_rm_callback(int fd, const struct osl_object *query)
 {
        struct com_rm_action_data crd = {.flags = *(uint32_t *)query->data,
                .pb = {
-                       .max_size = SHMMAX,
+                       .max_size = shm_get_shmmax(),
                        .private_data = &fd,
                        .max_size_handler = pass_buffer_as_shm
                }
@@ -2371,7 +2371,7 @@ static void com_cpsi_callback(int fd, const struct osl_object *query)
        struct cpsi_action_data cad = {
                .flags = *(unsigned *)query->data,
                .pb = {
-                       .max_size = SHMMAX,
+                       .max_size = shm_get_shmmax(),
                        .private_data = &fd,
                        .max_size_handler = pass_buffer_as_shm
                }
@@ -2481,6 +2481,8 @@ static void afs_stat_callback(int fd, const struct osl_object *query)
  * up-to-date afs status items directly. Therefore the usual callback mechanism
  * is used to pass the status items from the afs process to the command handler
  * via a shared memory area and a pipe.
+ *
+ * \return The return value of the underyling call to \ref send_callback_request().
  */
 int send_afs_status(struct stream_cipher_context *scc, int parser_friendly)
 {
@@ -2543,7 +2545,7 @@ static int check_audio_file(struct osl_row *row, void *data)
 void aft_check_callback(int fd, __a_unused const struct osl_object *query)
 {
        struct para_buffer pb = {
-               .max_size = SHMMAX,
+               .max_size = shm_get_shmmax(),
                .private_data = &fd,
                .max_size_handler = pass_buffer_as_shm
        };
index 42fa421..f36f4e7 100644 (file)
@@ -149,7 +149,7 @@ static void com_lsatt_callback(int fd, const struct osl_object *query)
        struct lsatt_action_data laad = {
                .flags = *(unsigned *) query->data,
                .pb = {
-                       .max_size = SHMMAX,
+                       .max_size = shm_get_shmmax(),
                        .private_data = &fd,
                        .max_size_handler = pass_buffer_as_shm
                }
@@ -295,7 +295,7 @@ static void com_addatt_callback(int fd, const struct osl_object *query)
        char *p;
        int ret = 1, ret2 = 0;
        struct para_buffer pb = {
-               .max_size = SHMMAX,
+               .max_size = shm_get_shmmax(),
                .private_data = &fd,
                .max_size_handler = pass_buffer_as_shm
        };
@@ -378,7 +378,7 @@ static void com_mvatt_callback(int fd, const struct osl_object *query)
        struct osl_object obj = {.data = old, .size = size};
        struct osl_row *row;
        struct para_buffer pb = {
-               .max_size = SHMMAX,
+               .max_size = shm_get_shmmax(),
                .private_data = &fd,
                .max_size_handler = pass_buffer_as_shm
        };
@@ -448,7 +448,7 @@ static void com_rmatt_callback(int fd, const struct osl_object *query)
        struct remove_attribute_action_data raad = {
                .num_removed = 0,
                .pb = {
-                       .max_size = SHMMAX,
+                       .max_size = shm_get_shmmax(),
                        .private_data = &fd,
                        .max_size_handler = pass_buffer_as_shm
                }
index c78df5b..4864c85 100644 (file)
--- a/audiod.c
+++ b/audiod.c
@@ -1370,7 +1370,7 @@ int main(int argc, char *argv[])
                exit(EXIT_FAILURE);
        }
        log_welcome("para_audiod");
-       server_uptime(UPTIME_SET);
+       set_server_start_time(NULL);
        set_initial_status();
        FOR_EACH_SLOT(i)
                clear_slot(i);
index 1c22f58..dfb014a 100644 (file)
@@ -480,7 +480,7 @@ void audiod_status_dump(void)
                        free(new);
        }
 
-       new = uptime_str();
+       new = get_server_uptime_str(now);
        old = stat_item_values[SI_AUDIOD_UPTIME];
        if (!old || strcmp(old, new)) {
                free(old);
index e5000a6..ea38dbf 100755 (executable)
@@ -5,6 +5,11 @@ if [ -z "$n" ]; then
        n=$(grep ^processor /proc/cpuinfo 2>/dev/null | wc -l)
        [ $n -eq 0 ] && n=1
 fi
+# If we are compiling with distcc, try to guess a reasonable number
+# based on (a) the number of cores on this machine and (b) the number
+# of words in the DISTCC_HOSTS variable.
+d="$(echo $DISTCC_HOSTS | wc -w)"
+n=$(($n + 2 * $n * $d))
 echo preparing, parallel=$n...
 if test -f Makefile; then
        make maintainer-clean > /dev/null 2>&1
diff --git a/blob.c b/blob.c
index 25aa2a6..707c6c6 100644 (file)
--- a/blob.c
+++ b/blob.c
@@ -80,12 +80,13 @@ static struct osl_column_description blob_cols[] = {
        DEFINE_BLOB_TABLE_DESC(table_name); \
        DEFINE_BLOB_TABLE_PTR(table_name);
 
-/** \cond doxygen isn't smart enough to recognize these */
+/* doxygen isn't smart enough to recognize these */
+/** \cond blob_table */
 INIT_BLOB_TABLE(lyrics);
 INIT_BLOB_TABLE(images);
 INIT_BLOB_TABLE(moods);
 INIT_BLOB_TABLE(playlists);
-/** \endcond */
+/** \endcond blob_table */
 
 /** Flags that may be passed to the \p ls functions of each blob  type. */
 enum blob_ls_flags {
@@ -130,7 +131,7 @@ static void com_lsblob_callback(struct osl_table *table,
        struct lsblob_action_data lbad = {
                .flags = *(uint32_t *)query->data,
                .pb = {
-                       .max_size = SHMMAX,
+                       .max_size = shm_get_shmmax(),
                        .private_data = &fd,
                        .max_size_handler = pass_buffer_as_shm
                }
@@ -261,7 +262,7 @@ static void com_rmblob_callback(struct osl_table *table, int fd,
        struct rmblob_data rmbd = {
                .num_removed = 0,
                .pb = {
-                       .max_size = SHMMAX,
+                       .max_size = shm_get_shmmax(),
                        .private_data = &fd,
                        .max_size_handler = pass_buffer_as_shm
                }
@@ -662,9 +663,10 @@ static int blob_open(struct osl_table **table,
        DEFINE_GET_DEF_BY_NAME(table_name, cmd_prefix); \
        DEFINE_GET_NAME_AND_DEF_BY_ROW(table_name, cmd_prefix); \
 
-/** \cond doxygen isn't smart enough to recognize these */
+/* doxygen isn't smart enough to recognize these */
+/** \cond blob_function */
 DEFINE_BLOB_FUNCTIONS(lyrics, lyr);
 DEFINE_BLOB_FUNCTIONS(images, img);
 DEFINE_BLOB_FUNCTIONS(moods, mood);
 DEFINE_BLOB_FUNCTIONS(playlists, pl);
-/** \endcond */
+/** \endcond blob_function */
index 69bbbb7..b6861b8 100644 (file)
--- a/command.c
+++ b/command.c
@@ -108,7 +108,8 @@ static char *get_status(struct misc_meta_data *nmmd, int parser_friendly)
 {
        char mtime[30] = "";
        char *status, *flags; /* vss status info */
-       char *ut = uptime_str();
+       /* nobody updates our version of "now" */
+       char *ut = get_server_uptime_str(NULL);
        long offset = (nmmd->offset + 500) / 1000;
        struct timeval current_time;
        struct tm mtime_tm;
@@ -258,7 +259,7 @@ int com_si(struct stream_cipher_context *scc, int argc, __a_unused char * const
                sender_info = para_strcat(sender_info, info);
                free(info);
        }
-       ut = uptime_str();
+       ut = get_server_uptime_str(now);
        ret = sc_send_va_buffer(scc, "version: " GIT_VERSION "\n"
                "up: %s\nplayed: %u\n"
                "server_pid: %d\n"
@@ -762,13 +763,11 @@ __noreturn void handle_connect(int fd, const char *peername)
                ret = -E_AUTH_REQUEST;
                goto net_err;
        }
-       numbytes = ret;
        ret = -E_AUTH_REQUEST;
        if (strncmp(buf, AUTH_REQUEST_MSG, strlen(AUTH_REQUEST_MSG)))
                goto net_err;
        p = buf + strlen(AUTH_REQUEST_MSG);
        PARA_DEBUG_LOG("received auth request for user %s\n", p);
-       ret = -E_BAD_USER;
        u = lookup_user(p);
        if (u) {
                get_random_bytes_or_die(rand_buf, sizeof(rand_buf));
diff --git a/crypt.c b/crypt.c
index 5b7029d..431de6f 100644 (file)
--- a/crypt.c
+++ b/crypt.c
@@ -184,24 +184,25 @@ int get_asymmetric_key(const char *key_file, int private,
        PARA_INFO_LOG("decoding public rsa-ssh key %s\n", key_file);
        ret = -ERRNO_TO_PARA_ERROR(EOVERFLOW);
        if (map_size > INT_MAX / 4)
-               goto out;
+               goto out_unmap;
        blob_size = 2 * map_size;
        blob = para_malloc(blob_size);
        ret = uudecode(cp, blob, blob_size);
        if (ret < 0)
-               goto out;
+               goto out_unmap;
        decoded_size = ret;
        ret = check_ssh_key_header(blob, decoded_size);
        if (ret < 0)
-               goto out;
+               goto out_unmap;
        ret = read_rsa_bignums(blob + ret, decoded_size - ret, &key->rsa);
        if (ret < 0)
-               goto out;
+               goto out_unmap;
        ret = RSA_size(key->rsa);
-out:
+out_unmap:
        ret2 = para_munmap(map, map_size);
        if (ret >= 0 && ret2 < 0)
                ret = ret2;
+out:
        if (ret < 0) {
                free(key);
                *result = NULL;
@@ -306,7 +307,7 @@ int sc_send_bin_buffer(struct stream_cipher_context *scc, char *buf,
 int sc_recv_bin_buffer(struct stream_cipher_context *scc, char *buf,
                size_t size)
 {
-       unsigned char *tmp = para_malloc(size);
+       unsigned char *tmp = para_malloc(ROUND_UP(size, RC4_ALIGN));
        ssize_t ret = recv(scc->fd, tmp, size, 0);
 
        if (ret > 0)
diff --git a/crypt.h b/crypt.h
index 4696ee4..833bbf1 100644 (file)
--- a/crypt.h
+++ b/crypt.h
@@ -7,13 +7,14 @@
 /** \file crypt.h Public crypto interface. */
 
 
-/** \cond used to distinguish between loading of private/public key */
+/* These are used to distinguish between loading of private/public key. */
+
+/** The key to load is a public key. */
 #define LOAD_PUBLIC_KEY 0
+/** The key to load is a private key. */
 #define LOAD_PRIVATE_KEY 1
+/** The size of the challenge sent to the client. */
 #define CHALLENGE_SIZE 64
-/** \endcond **/
-
-/* asymetric (public key) crypto */
 
 /** Opaque structure for public and private keys. */
 struct asymmetric_key;
index b7a0a32..ffdec4e 100644 (file)
--- a/daemon.c
+++ b/daemon.c
@@ -26,7 +26,6 @@ struct daemon {
        char *logfile_name;
        /** Current loglevel, see \ref daemon_set_loglevel(). */
        int loglevel;
-
        /** Used by \ref server_uptime() and \ref uptime_str(). */
        time_t startuptime;
        /** The file pointer if the logfile is open. */
@@ -277,43 +276,59 @@ void drop_privileges_or_die(const char *username, const char *groupname)
 }
 
 /**
- * Set/get the server uptime.
+ * Set the server startup time.
+ *
+ * \param startuptime The value to store as the server start time.
  *
- * \param set_or_get Chose one of the two modes.
+ * This should be called once on startup with \a startuptime either NULL or a
+ * pointer to a struct timeval which contains the current time. If \a
+ * startuptime is NULL, the server start time is set to the current time.
  *
- * This should be called at startup time with \a set_or_get equal to \p
- * UPTIME_SET which sets the uptime to zero.  Subsequent calls with \a
- * set_or_get equal to \p UPTIME_GET return the uptime.
+ * \sa time(2), difftime(3) \ref get_server_uptime(), \ref
+ * get_server_uptime_str().
+ */
+void set_server_start_time(const struct timeval *startuptime)
+{
+       if (startuptime)
+               me->startuptime = startuptime->tv_sec;
+       else
+               time(&me->startuptime);
+}
 
- * \return Zero if called with \a set_or_get equal to \p UPTIME_SET, the number
- * of seconds elapsed since the last reset otherwise.
+/**
+ * Get the server uptime.
+ *
+ * \param current_time The current time.
+ *
+ * The \a current_time pointer may be \p NULL. In this case the function
+ * obtains the current time from the system.
  *
- * \sa time(2), difftime(3).
+ * \return This returns the server uptime in seconds, i.e. the difference
+ * between the current time and the value stored previously via \ref
+ * set_server_start_time().
  */
-time_t server_uptime(enum uptime set_or_get)
+time_t get_server_uptime(const struct timeval *current_time)
 {
-       time_t now;
-       double diff;
+       time_t t;
 
-       if (set_or_get == UPTIME_SET) {
-               time(&me->startuptime);
-               return 0;
-       }
-       time(&now);
-       diff = difftime(now, me->startuptime);
-       return (time_t) diff;
+       if (current_time)
+               return current_time->tv_sec - me->startuptime;
+       time(&t);
+       return difftime(t, me->startuptime);
 }
 
 /**
- * Construct string containing uptime.
+ * Construct a string containing the current uptime.
+ *
+ * \param current_time See a \ref get_server_uptime().
  *
  * \return A dynamically allocated string of the form "days:hours:minutes".
  *
  * \sa server_uptime.
  */
-__malloc char *uptime_str(void)
+__malloc char *get_server_uptime_str(const struct timeval *current_time)
 {
-       long t = server_uptime(UPTIME_GET);
+       long t = get_server_uptime(current_time);
        return make_message("%li:%02li:%02li", t / 86400,
                (t / 3600) % 24, (t / 60) % 60);
 }
index 4e803bd..d5583f5 100644 (file)
--- a/daemon.h
+++ b/daemon.h
@@ -7,9 +7,9 @@ void daemon_close_log(void);
 void log_welcome(const char *whoami);
 void drop_privileges_or_die(const char *username, const char *groupname);
 /** used for server_uptime() */
-enum uptime {UPTIME_SET, UPTIME_GET};
-time_t server_uptime(enum uptime set_or_get);
-__malloc char *uptime_str(void);
+void set_server_start_time(const struct timeval *startuptime);
+time_t get_server_uptime(const struct timeval *current_time);
+__malloc char *get_server_uptime_str(const struct timeval *current_time);
 void daemon_set_logfile(char *logfile_name);
 void daemon_set_flag(unsigned flag);
 void daemon_clear_flag(unsigned flag);
index af8e6b1..a9eab00 100644 (file)
@@ -40,13 +40,14 @@ struct private_dccp_recv_data {
 
 static void dccp_recv_close(struct receiver_node *rn)
 {
-
        struct private_dccp_recv_data *pdd = rn->private_data;
 
-       if (pdd && pdd->fd > 0)
+       if (!pdd)
+               return;
+       if (pdd->fd > 0)
                close(pdd->fd);
        btr_pool_free(pdd->btrp);
-       free(rn->private_data);
+       free(pdd);
        rn->private_data = NULL;
 }
 
diff --git a/error.h b/error.h
index 306546d..6549413 100644 (file)
--- a/error.h
+++ b/error.h
@@ -6,7 +6,7 @@
 
 /** \file error.h List of error messages for all subsystems. */
 
-/** \cond */
+/** \cond errors */
 
 /* List of all subsystems that use paraslash's error facility. */
 DEFINE_ERRLIST_OBJECT_ENUM;
@@ -455,7 +455,7 @@ extern const char **para_errlist[];
        PARA_ERROR(QUEUE, "packet queue overrun"), \
 
 
-/** \endcond */
+/** \endcond errors */
 
 /**
  * The subsystem shift.
diff --git a/imdct.c b/imdct.c
index 3292848..aab498a 100644 (file)
--- a/imdct.c
+++ b/imdct.c
@@ -293,7 +293,6 @@ static void imdct_half(struct mdct_context *s, fftsample_t *output,
        fft(&s->fft, z);
 
        /* post rotation + reordering */
-       output += n4;
        for (k = 0; k < n8; k++) {
                fftsample_t r0, i0, r1, i1;
                CMUL(r0, i1, z[n8 - k - 1].im, z[n8 - k - 1].re,
diff --git a/ipc.c b/ipc.c
index c1069ad..576bfe5 100644 (file)
--- a/ipc.c
+++ b/ipc.c
@@ -9,6 +9,10 @@
 #include "para.h"
 #include "error.h"
 #include "ipc.h"
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+
 #include <sys/ipc.h>
 #include <sys/shm.h>
 #include <sys/sem.h>
@@ -171,3 +175,54 @@ int shm_detach(void *addr)
        int ret = shmdt(addr);
        return ret < 0? -ERRNO_TO_PARA_ERROR(errno) : 1;
 }
+
+# if defined __FreeBSD__ || defined __NetBSD__
+#      define SYSCTL_SHMMAX_VARIABLE "kern.ipc.shmmax"
+# elif defined __APPLE__
+#      define SYSCTL_SHMMAX_VARIABLE "kern.sysv.shmmax"
+# else
+#      undef SYSCTL_SHMMAX_VARIABLE
+# endif
+
+/**
+ * Get the maximal size of a shared memory area.
+ *
+ * The value is only computed once when the function is called for the first
+ * time.  Subsequent calls return the number which was computed during the
+ * first call.
+ *
+ * \return A number suitable as an argument to \ref shm_new().
+ */
+size_t shm_get_shmmax(void)
+{
+       static size_t shmmax;
+
+       if (shmmax > 0) /* only dance once */
+               return shmmax;
+#ifdef __linux__ /* get it from proc fs */
+       {
+               int fd = open("/proc/sys/kernel/shmmax", O_RDONLY);
+               if (fd >= 0) {
+                       char buf[100] = "";
+                       int ret = read(fd, buf, sizeof(buf) - 1);
+                       if (ret > 0) {
+                               buf[ret] = '\0';
+                               shmmax = strtoul(buf, NULL, 10);
+                       }
+               }
+       }
+#elif defined SYSCTL_SHMMAX_VARIABLE
+       {
+               size_t len = sizeof(shmmax);
+               sysctlbyname(SYSCTL_SHMMAX_VARIABLE, &shmmax, &len, NULL, 0);
+       }
+#elif defined SHMMAX
+       shmmax = SHMMAX;
+#endif
+       if (shmmax == 0) {
+               PARA_WARNING_LOG("unable to determine shmmax\n");
+               shmmax = 65535; /* last ressort */
+       }
+       PARA_INFO_LOG("shmmax: %zu\n", shmmax);
+       return shmmax;
+}
diff --git a/ipc.h b/ipc.h
index 71e09ec..c8d31c0 100644 (file)
--- a/ipc.h
+++ b/ipc.h
@@ -11,7 +11,4 @@ int shm_new(size_t size);
 int shm_attach(int id, enum shm_attach_mode mode, void **result);
 int shm_detach(void *addr);
 int shm_destroy(int id);
-
-#ifndef SHMMAX
-#define SHMMAX 65535
-#endif
+size_t shm_get_shmmax(void);
diff --git a/mood.c b/mood.c
index 93461ee..d9ae48b 100644 (file)
--- a/mood.c
+++ b/mood.c
@@ -422,7 +422,7 @@ out:
 void mood_check_callback(int fd, __a_unused const struct osl_object *query)
 {
        struct para_buffer pb = {
-               .max_size = SHMMAX,
+               .max_size = shm_get_shmmax(),
                .private_data = &fd,
                .max_size_handler = pass_buffer_as_shm
        };
index b0d44ec..d72d85e 100644 (file)
--- a/mp3_afh.c
+++ b/mp3_afh.c
@@ -23,8 +23,6 @@
 #include "afh.h"
 #include "string.h"
 
-/** \cond some defines and structs which are only used in this file */
-
 /*
  * MIN_CONSEC_GOOD_FRAMES defines how many consecutive valid MP3 frames we need
  * to see before we decide we are looking at a real MP3 file
@@ -47,7 +45,6 @@ struct mp3header {
        unsigned int emphasis;
 };
 
-/** \endcond */
 static const int frequencies[3][4] = {
        {22050,24000,16000,50000}, /* MPEG 2.0 */
        {44100,48000,32000,50000}, /* MPEG 1.0 */
diff --git a/net.c b/net.c
index 9b58e22..49026db 100644 (file)
--- a/net.c
+++ b/net.c
@@ -578,10 +578,12 @@ static inline int estimated_header_overhead(const int af_type)
 /**
  * Get the maximum transport-layer message size (MMS_S).
  *
- * The socket must be connected. See RFC 1122, 3.3.3.
+ * \param sockfd The socket file descriptor.
  *
- * \return If the protocol familiy could not be determined, \p AF_INET is
- * assumed.
+ * The socket must be connected. See RFC 1122, 3.3.3. If the protocol familiy
+ * could not be determined, \p AF_INET is assumed.
+ *
+ * \return The maximum message size of the address family type.
  */
 int generic_max_transport_msg_size(int sockfd)
 {
diff --git a/net.h b/net.h
index 80f5794..79c5994 100644 (file)
--- a/net.h
+++ b/net.h
@@ -8,13 +8,15 @@
 /** \file net.h exported symbols from net.c */
 
 /**
- * the buffer size of the sun_path component of struct sockaddr_un
+ * The buffer size of the sun_path component of struct sockaddr_un.
  *
- * While glibc doesn't define \p UNIX_PATH_MAX, it
- * documents it has being limited to 108 bytes.
+ * While glibc doesn't define \p UNIX_PATH_MAX, it documents it has being
+ * limited to 108 bytes. On NetBSD it is only 104 bytes though. We trust \p
+ * UNIX_PATH_MAX if it is defined and use the size of the ->sun_path member
+ * otherwise. This should be safe everywhere.
  */
 #ifndef UNIX_PATH_MAX
-#define UNIX_PATH_MAX 108
+#define UNIX_PATH_MAX (sizeof(((struct sockaddr_un *)0)->sun_path))
 #endif
 
 /* Userland defines for Linux DCCP support. */
index 46c7b08..0802345 100644 (file)
--- a/ogg_afh.c
+++ b/ogg_afh.c
@@ -105,7 +105,6 @@ static int vorbis_get_header_callback(ogg_packet *packet, int packet_num,
                return 0;
        if (packet_num == 0) {
                ogg_stream_init(&vghd->os, serial);
-               ret = -E_OGG_PACKET_IN;
                ret = ogg_stream_packetin(&vghd->os, packet);
                if (ret < 0)
                        goto out;
index 32ffdef..07e4cec 100644 (file)
@@ -175,6 +175,7 @@ out:
                pod->converted = 0;
                fn->min_iqs = 0;
                pod->vf = vf;
+               pod->have_more = true;
        }
        return ret;
 }
diff --git a/para.h b/para.h
index 5dc3912..bc6aa92 100644 (file)
--- a/para.h
+++ b/para.h
@@ -229,12 +229,12 @@ _static_inline_ long int para_random(unsigned max)
        SAMPLE_FORMAT(SF_U16_LE, "16 bit unsigned, little endian"), \
        SAMPLE_FORMAT(SF_U16_BE, "16 bit unsigned, big endian"), \
 
-/** \cond */
+/** \cond sample_format */
 #define SAMPLE_FORMAT(a, b) a
 enum sample_format {SAMPLE_FORMATS};
 #undef SAMPLE_FORMAT
 #define SAMPLE_FORMAT(a, b) b
-/** \endcond */
+/** \endcond sample_format */
 
 /** Debug loglevel, gets really noisy. */
 #define LL_DEBUG 0
@@ -256,7 +256,7 @@ enum sample_format {SAMPLE_FORMATS};
 /** Log messages with lower priority than that will not be compiled in. */
 #define COMPILE_TIME_LOGLEVEL 0
 
-/** \cond */
+/** \cond log */
 #if LL_DEBUG >= COMPILE_TIME_LOGLEVEL
 #define PARA_DEBUG_LOG(f,...) para_log(LL_DEBUG, "%s: " f, __FUNCTION__, ## __VA_ARGS__)
 #else
@@ -298,4 +298,4 @@ enum sample_format {SAMPLE_FORMATS};
 #else
 #define PARA_EMERG_LOG(...)
 #endif
-/** \endcond */
+/** \endcond log */
index 2d2f23b..806e49d 100644 (file)
@@ -131,7 +131,7 @@ static int check_playlist(struct osl_row *row, void *data)
 void playlist_check_callback(int fd, __a_unused const struct osl_object *query)
 {
        struct para_buffer pb = {
-               .max_size = SHMMAX,
+               .max_size = shm_get_shmmax(),
                .private_data = &fd,
                .max_size_handler = pass_buffer_as_shm
        };
diff --git a/recv.h b/recv.h
index ee8138f..7555dfb 100644 (file)
--- a/recv.h
+++ b/recv.h
@@ -121,7 +121,7 @@ void *check_receiver_arg(char *ra, int *receiver_num);
 void print_receiver_helps(int detailed);
 int generic_recv_pre_select(struct sched *s, struct task *t);
 
-/** \cond */
+/** \cond receiver */
 extern void http_recv_init(struct receiver *r);
 #define HTTP_RECEIVER {.name = "http", .init = http_recv_init},
 extern void dccp_recv_init(struct receiver *r);
@@ -130,5 +130,5 @@ extern void udp_recv_init(struct receiver *r);
 #define UDP_RECEIVER {.name = "udp", .init = udp_recv_init},
 
 extern struct receiver receivers[];
-/** \endcond */
+/** \endcond receiver */
 
diff --git a/sched.c b/sched.c
index 06aabe0..66a1741 100644 (file)
--- a/sched.c
+++ b/sched.c
@@ -335,8 +335,8 @@ int sched_request_barrier(struct timeval *barrier, struct sched *s)
  * \param barrier Absolute time before select() should return.
  * \param s Pointer to the scheduler struct.
  *
- * If \a barrier is in the past, this function requests a minimal timeout and
- * returns zero. Otherwise it returns one.
+ * \return If \a barrier is in the past, this function requests a minimal
+ * timeout and returns zero. Otherwise it returns one.
  *
  * \sa sched_min_delay(), sched_request_barrier().
  */
index 142e2ab..15ae5c9 100644 (file)
--- a/server.c
+++ b/server.c
@@ -491,7 +491,7 @@ static void server_init(int argc, char **argv)
        init_ipc_or_die(); /* init mmd struct and mmd->lock */
        /* make sure, the global now pointer is uptodate */
        gettimeofday(now, NULL);
-       server_uptime(UPTIME_SET); /* reset server uptime */
+       set_server_start_time(now);
        init_user_list(user_list_file);
        /* become daemon */
        if (conf.daemon_given)
@@ -525,7 +525,7 @@ static void server_init(int argc, char **argv)
 static void status_refresh(void)
 {
        static int prev_uptime = -1, prev_events = -1;
-       int uptime = server_uptime(UPTIME_GET), ret = 1;
+       int uptime = get_server_uptime(now);
 
        if (prev_events != mmd->events)
                goto out;
@@ -540,11 +540,8 @@ out:
        prev_uptime = uptime;
        prev_events = mmd->events;
        mmd->vss_status_flags = mmd->new_vss_status_flags;
-       if (ret) {
-               PARA_DEBUG_LOG("%d events, forcing status update\n",
-                       mmd->events);
-               killpg(0, SIGUSR1);
-       }
+       PARA_DEBUG_LOG("%d events, forcing status update\n", mmd->events);
+       killpg(0, SIGUSR1);
 }
 
 static int server_select(int max_fileno, fd_set *readfds, fd_set *writefds,
index 0a32c0f..cefb45d 100644 (file)
--- a/string.c
+++ b/string.c
@@ -521,14 +521,15 @@ __printf_2_3 int para_printf(struct para_buffer *b, const char *fmt, ...)
        }
 }
 
-/** \cond LLONG_MAX and LLONG_MIN might not be defined. */
+/** \cond llong_minmax */
+/* LLONG_MAX and LLONG_MIN might not be defined. */
 #ifndef LLONG_MAX
 #define LLONG_MAX 9223372036854775807LL
 #endif
 #ifndef LLONG_MIN
 #define LLONG_MIN (-LLONG_MAX - 1LL)
 #endif
-/** \endcond */
+/** \endcond llong_minmax */
 
 /**
  * Convert a string to a 64-bit signed integer value.
diff --git a/time.c b/time.c
index 3ec2a2d..d7d803d 100644 (file)
--- a/time.c
+++ b/time.c
@@ -82,7 +82,7 @@ int tv_diff(const struct timeval *b, const struct timeval *a, struct timeval *di
  *
  * \param a First addend.
  * \param b Second addend.
- * \param sum Contains the sum \a + \a b on return.
+ * \param sum Contains the sum \a + \a b on return.
  */
 void tv_add(const struct timeval *a, const struct timeval *b,
        struct timeval *sum)
@@ -180,7 +180,7 @@ int tv_convex_combination(const long a, const struct timeval *tv1,
  * \param stream_start When the first chunk was sent.
  * \param result The time when to send chunk number \a chunk_num.
  *
- * This function computes stream_start + chunk_num * chunk_time.
+ * This function computes \a stream_start + \a chunk_num * \a chunk_time.
  */
 void compute_chunk_time(long unsigned chunk_num,
                struct timeval *chunk_tv, struct timeval *stream_start,
diff --git a/vss.c b/vss.c
index e833543..e336a9e 100644 (file)
--- a/vss.c
+++ b/vss.c
@@ -132,6 +132,7 @@ struct fec_group {
        uint16_t slice_bytes;
 };
 
+/** A FEC client is always in one of these states. */
 enum fec_client_state {
        FEC_STATE_NONE = 0,     /**< not initialized and not enabled */
        FEC_STATE_DISABLED,     /**< temporarily disabled */
index 1dde835..519be89 100644 (file)
@@ -28,6 +28,8 @@
  * \param pattern_len The length of the pattern in bytes.
  * \param buf The buffer to search for the pattern.
  * \param buf_size The number of bytes in \a buf.
+ *
+ * \return A pointer into \a buf or \p NULL if the pattern was not found.
  */
 const char *search_pattern(const char *pattern, int pattern_len,
                const char *buf, int buf_size)
index 0b381c5..c6eb0b1 100644 (file)
@@ -769,7 +769,6 @@ static void compute_mdct_coefficients(struct private_wmadec_data *pwd,
                                *coefs++ = 0.0;
                        continue;
                }
-               mult1 = mult;
                n1 = pwd->exponent_high_sizes[bsize];
                /* compute power of high bands */
                exponents = pwd->exponents[ch] +
@@ -803,8 +802,7 @@ static void compute_mdct_coefficients(struct private_wmadec_data *pwd,
                                mult1 = sqrt(exp_power[j]
                                        / exp_power[last_high_band]);
                                /* XXX: use a table */
-                               mult1 = mult1 * pow(10,
-                                       pwd->high_band_values[ch][j] * 0.05);
+                               mult1 *= pow(10, pwd->high_band_values[ch][j] * 0.05);
                                mult1 /= (pwd->max_exponent[ch] * pwd->noise_mult);
                                mult1 *= mdct_norm;
                                for (i = 0; i < n; i++) {
@@ -1012,7 +1010,6 @@ next:
        for (ch = 0; ch < pwd->ahi.channels; ch++) {
                int n4, idx;
 
-               n = pwd->block_len;
                n4 = pwd->block_len / 2;
                if (pwd->channel_coded[ch])
                        imdct(pwd->mdct_ctx[bsize], pwd->output, pwd->coefs[ch]);