[SCM] ices2/master: Add patch 0001 to sync with most recent upstream snapshot.
js at users.alioth.debian.org
js at users.alioth.debian.org
Sat Jan 1 20:04:19 UTC 2011
The following commit has been merged in the master branch:
commit 9477b27472084f8921d024e71b07a6eac47b80ad
Author: Jonas Smedegaard <dr at jones.dk>
Date: Sat Jan 1 20:33:24 2011 +0100
Add patch 0001 to sync with most recent upstream snapshot.
diff --git a/debian/patches/0001_sync_20090819.patch b/debian/patches/0001_sync_20090819.patch
new file mode 100644
index 0000000..4dbd9d9
--- /dev/null
+++ b/debian/patches/0001_sync_20090819.patch
@@ -0,0 +1,1293 @@
+Description: Sync with upstream snapshot
+Origin: http://people.xiph.org/~brendan/snapshots/ices2/
+--- a/configure.in
++++ b/configure.in
+@@ -14,12 +14,6 @@
+
+ dnl BSD headers break when _XOPEN_SOURCE is defined but without it seems
+ dnl to be fine
+-case "$host" in
+- *bsd*|*irix*)
+- ;;
+- *) AC_DEFINE(_XOPEN_SOURCE, 600, [Define if you have POSIX and XPG specifications])
+- ;;
+-esac
+ if test -n "$GCC"; then
+ AC_DEFINE(_GNU_SOURCE, ,[Define if you have POSIX and GNU specifications])
+ XIPH_VAR_APPEND([XIPH_CPPFLAGS], [-ffast-math -fsigned-char])
+@@ -52,7 +46,7 @@
+
+ dnl Checks for header files.
+ AC_HEADER_STDC
+-AC_CHECK_HEADERS([stropts.h])
++AC_CHECK_HEADERS([stropts.h sys/timeb.h sys/select.h])
+
+ dnl Check for OSS
+
+@@ -91,6 +85,16 @@
+ AC_DEFINE(HAVE_ALSA, ,[Define to enable ALSA input module])
+ fi
+
++dnl Check for RoarAudio
++
++AC_CHECK_HEADER(roaraudio.h, have_roaraudio=yes, have_roaraudio=no)
++AM_CONDITIONAL(HAVE_ROARAUDIO,test "$have_roaraudio" = yes)
++
++if test "$have_roaraudio" = yes; then
++ ROARAUDIO_LIBS="-lroar"
++ AC_DEFINE(HAVE_ROARAUDIO, ,[Define to enable RoarAudio input module])
++fi
++
+ dnl Checks for typedefs, structures, and compiler characteristics.
+ AC_C_CONST
+
+@@ -99,6 +103,8 @@
+
+ dnl Checks for library functions.
+
++AC_CHECK_FUNCS([gettimeofday ftime])
++
+ XIPH_PATH_XML
+ XIPH_VAR_APPEND([XIPH_CFLAGS], [$XML_CFLAGS])
+ XIPH_VAR_PREPEND([XIPH_LIBS], [$XML_LIBS])
+@@ -120,6 +126,7 @@
+ dnl Make substitutions
+
+ AC_SUBST(ALSA_LIBS)
++AC_SUBST(ROARAUDIO_LIBS)
+ AC_SUBST(XML_LIBS)
+ AC_SUBST(XML_CFLAGS)
+ AC_SUBST(LIBTOOL_DEPS)
+--- a/m4/ogg.m4
++++ b/m4/ogg.m4
+@@ -15,7 +15,7 @@
+ ogg_prefix="$withval",
+ ogg_prefix="$OGG_PREFIX"
+ )
+-if test "x$ogg_prefix" = "x"; then
++if test "x$ogg_prefix" = "x" -o "x$ogg_prefix" = "xyes"; then
+ if test "x$prefix" = "xNONE"; then
+ ogg_prefix=/usr/local
+ else
+--- a/m4/vorbis.m4
++++ b/m4/vorbis.m4
+@@ -21,7 +21,7 @@
+ vorbis_prefix="$withval",
+ vorbis_prefix="$VORBIS_PREFIX"
+ )
+-if test "x$vorbis_prefix" = "x"; then
++if test "x$vorbis_prefix" = "x" -o "x$vorbis_prefix" = "xyes"; then
+ if test "x$prefix" = "xNONE"; then
+ vorbis_prefix="/usr/local"
+ else
+@@ -58,16 +58,17 @@
+ )
+ ])
+
+-AC_MSG_RESULT([$xt_lib_vorbis])
+ if test "x$xt_lib_vorbis" = "xok"; then
+ #
+ # Now check if the installed Vorbis is sufficiently new.
+ #
+-AC_CHECK_TYPES([struct ovectl_ratemanage_arg],,
+- [xt_lib_vorbis="old version found"], [
++AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
+ #include <vorbis/codec.h>
+ #include <vorbis/vorbisenc.h>
+- ])
++ ], [
++struct ovectl_ratemanage_arg a;
++])],,[xt_lib_vorbis="old version found"])
++AC_MSG_RESULT([$xt_lib_vorbis])
+ fi
+ CPPFLAGS="$xt_save_CPPFLAGS"
+ LIBS="$xt_save_LIBS"
+--- a/m4/xiph_compiler.m4
++++ b/m4/xiph_compiler.m4
+@@ -178,9 +178,9 @@
+ [ AH_TEMPLATE([__func__], [Replace __func__ if not supported])
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[const char *x = __FUNCTION__;])],
+ [ AC_DEFINE([__func__],[__FUNCTION__])
+- AC_MSG_RESULT([yes])],
+- [ AC_DEFINE([__func__],[""])
+- AC_MSG_RESULT([no])
++ AC_MSG_RESULT([Using __FUNCTION__])],
++ [ AC_DEFINE([__func__],["__FILE__"])
++ AC_MSG_RESULT([using __FILE__])
+ ])
+ ])
+ ])dnl XIPH_C__FUNC__
+--- a/m4/xiph_xml2.m4
++++ b/m4/xiph_xml2.m4
+@@ -52,7 +52,7 @@
+ ac_xslt_save_CFLAGS="$CFLAGS"
+ LIBS="$XSLT_LIBS $LIBS"
+ CFLAGS="$CFLAGS $XSLT_CFLAGS"
+-AC_CHECK_FUNC(xsltSaveResultToString,,[AC_MSG_ERROR([Unable to link with libxslt (>=v1.0.18)])])
++AC_CHECK_FUNCS([xsltSaveResultToString])
+ CFLAGS="$ac_xslt_save_CFLAGS"
+ LIBS="$ac_xslt_save_LIBS"
+ ])
+--- a/src/avl/avl.c
++++ b/src/avl/avl.c
+@@ -54,7 +54,9 @@
+ node->rank_and_balance = 0;
+ AVL_SET_BALANCE (node, 0);
+ AVL_SET_RANK (node, 1);
++#ifdef HAVE_AVL_NODE_LOCK
+ thread_rwlock_create(&node->rwlock);
++#endif
+ return node;
+ }
+ }
+@@ -70,6 +72,7 @@
+ } else {
+ avl_node * root = avl_node_new((void *)NULL, (avl_node *) NULL);
+ if (!root) {
++ free (t);
+ return NULL;
+ } else {
+ t->root = root;
+@@ -94,7 +97,9 @@
+ if (node->right) {
+ avl_tree_free_helper (node->right, free_key_fun);
+ }
++#ifdef HAVE_AVL_NODE_LOCK
+ thread_rwlock_destroy (&node->rwlock);
++#endif
+ free (node);
+ }
+
+@@ -105,7 +110,9 @@
+ avl_tree_free_helper (tree->root->right, free_key_fun);
+ }
+ if (tree->root) {
++#ifdef HAVE_AVL_NODE_LOCK
+ thread_rwlock_destroy(&tree->root->rwlock);
++#endif
+ free (tree->root);
+ }
+ thread_rwlock_destroy(&tree->rwlock);
+@@ -449,7 +456,9 @@
+ /* return the key and node to storage */
+ if (free_key_fun)
+ free_key_fun (x->key);
++#ifdef HAVE_AVL_NODE_LOCK
+ thread_rwlock_destroy (&x->rwlock);
++#endif
+ free (x);
+
+ while (shorter && p->parent) {
+@@ -821,14 +830,14 @@
+ /* search left */
+ left = avl_get_prev (node);
+ i = m;
+- while ((i > 0) && (tree->compare_fun (tree->compare_arg, key, left->key) == 0)) {
++ while (left && (i > 0) && (tree->compare_fun (tree->compare_arg, key, left->key) == 0)) {
+ left = avl_get_prev (left);
+ i = i - 1;
+ }
+ /* search right */
+ right = avl_get_next (node);
+ j = m;
+- while ((j <= tree->length) && (tree->compare_fun (tree->compare_arg, key, right->key) == 0)) {
++ while (right && (j <= tree->length) && (tree->compare_fun (tree->compare_arg, key, right->key) == 0)) {
+ right = avl_get_next (right);
+ j = j + 1;
+ }
+@@ -869,7 +878,7 @@
+ avl_node * left;
+ /* search left */
+ left = avl_get_prev (low_node);
+- while ((i > 0) && (tree->compare_fun (tree->compare_arg, low_key, left->key) == 0)) {
++ while (left && (i > 0) && (tree->compare_fun (tree->compare_arg, low_key, left->key) == 0)) {
+ left = avl_get_prev (left);
+ i = i - 1;
+ }
+@@ -880,7 +889,7 @@
+ avl_node * right;
+ /* search right */
+ right = avl_get_next (high_node);
+- while ((j <= tree->length) && (tree->compare_fun (tree->compare_arg, high_key, right->key) == 0)) {
++ while (right && (j <= tree->length) && (tree->compare_fun (tree->compare_arg, high_key, right->key) == 0)) {
+ right = avl_get_next (right);
+ j = j + 1;
+ }
+@@ -1167,6 +1176,7 @@
+ thread_rwlock_unlock(&tree->rwlock);
+ }
+
++#ifdef HAVE_AVL_NODE_LOCK
+ void avl_node_rlock(avl_node *node)
+ {
+ thread_rwlock_rlock(&node->rwlock);
+@@ -1181,3 +1191,4 @@
+ {
+ thread_rwlock_unlock(&node->rwlock);
+ }
++#endif
+--- a/src/avl/avl.h
++++ b/src/avl/avl.h
+@@ -12,7 +12,7 @@
+ #endif
+
+ #ifndef NO_THREAD
+-#include <thread/thread.h>
++#include "thread/thread.h"
+ #else
+ #define thread_rwlock_create(x) do{}while(0)
+ #define thread_rwlock_destroy(x) do{}while(0)
+@@ -31,8 +31,8 @@
+ * factor: 00==-1, 01==0, 10==+1.
+ * The rest of the bits are used for <rank>
+ */
+- unsigned long rank_and_balance;
+-#ifndef NO_THREAD
++ unsigned int rank_and_balance;
++#if !defined(NO_THREAD) && defined(HAVE_AVL_NODE_LOCK)
+ rwlock_t rwlock;
+ #endif
+ } avl_node;
+@@ -92,8 +92,8 @@
+
+ typedef struct _avl_tree {
+ avl_node * root;
+- unsigned long height;
+- unsigned long length;
++ unsigned int height;
++ unsigned int length;
+ avl_key_compare_fun_type compare_fun;
+ void * compare_arg;
+ #ifndef NO_THREAD
+--- a/src/im_playlist.c
++++ b/src/im_playlist.c
+@@ -167,12 +167,8 @@
+ if (ogg_page_bos (&og))
+ {
+ if (ogg_page_serialno (&og) == pl->current_serial)
+- {
+- LOG_WARN1 ("Skipping \"%s\" as the serial number is the same as previous", pl->filename);
+- pl->nexttrack = 1;
+- pl->errors++;
+- return 0;
+- }
++ LOG_WARN1 ("detected duplicate serial number reading \"%s\"", pl->filename);
++
+ pl->current_serial = ogg_page_serialno (&og);
+ }
+ if (input_calculate_ogg_sleep (&og) < 0)
+--- /dev/null
++++ b/src/im_roar.c
+@@ -0,0 +1,266 @@
++/* im_oss.c
++ * - Raw PCM/Ogg Vorbis input from RoarAudio
++ *
++ * Copyright (c) 2001 Michael Smith <msmith at labyrinth.net.au>
++ * Copyright (c) 2009 Philipp Schafft <lion at lion.leolix.org>
++ *
++ * This program is distributed under the terms of the GNU General
++ * Public License, version 2. You may use, modify, and redistribute
++ * it under the terms of this license. A copy should be included
++ * with this source.
++ */
++
++#ifdef HAVE_CONFIG_H
++ #include <config.h>
++#endif
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <errno.h>
++#include <unistd.h>
++#include <ogg/ogg.h>
++#include <fcntl.h>
++
++
++#include <thread/thread.h>
++#include "cfgparse.h"
++#include "stream.h"
++#include "metadata.h"
++#include "inputmodule.h"
++
++#include "im_roar.h"
++
++#define MODULE "input-roar/"
++#include "logging.h"
++
++#define BUFSIZE 2048
++
++/* Some platforms (freebsd) don't define this, so just define it to something
++ * that should be treated the same
++ */
++#ifndef ERESTART
++#define ERESTART EINTR
++#endif
++
++static void close_module(input_module_t *mod)
++{
++ if(mod)
++ {
++ if(mod->internal)
++ {
++ im_roar_state *s = mod->internal;
++
++ if(s->fd >= 0)
++ close(s->fd);
++
++
++ thread_mutex_destroy(&s->metadatalock);
++ free(s);
++
++ roar_disconnect(&s->con);
++ }
++ free(mod);
++ }
++}
++
++static int event_handler(input_module_t *mod, enum event_type ev, void *param)
++{
++ im_roar_state *s = mod->internal;
++
++ switch(ev)
++ {
++ case EVENT_SHUTDOWN:
++ close_module(mod);
++ break;
++ case EVENT_NEXTTRACK:
++ s->newtrack = 1;
++ break;
++ case EVENT_METADATAUPDATE:
++ thread_mutex_lock(&s->metadatalock);
++ if(s->metadata)
++ {
++ char **md = s->metadata;
++ while(*md)
++ free(*md++);
++ free(s->metadata);
++ }
++ s->metadata = (char **)param;
++ s->newtrack = 1;
++ thread_mutex_unlock(&s->metadatalock);
++ break;
++ default:
++ LOG_WARN1("Unhandled event %d", ev);
++ return -1;
++ }
++
++ return 0;
++}
++
++static void metadata_update(void *self, vorbis_comment *vc)
++{
++ im_roar_state *s = self;
++ char **md;
++
++ thread_mutex_lock(&s->metadatalock);
++
++ md = s->metadata;
++
++ if(md)
++ {
++ while(*md)
++ vorbis_comment_add(vc, *md++);
++ }
++
++ thread_mutex_unlock(&s->metadatalock);
++}
++
++/* Core streaming function for this module
++ * This is what actually produces the data which gets streamed.
++ *
++ * returns: >0 Number of bytes read
++ * 0 Non-fatal error.
++ * <0 Fatal error.
++ */
++static int roar_read(void *self, ref_buffer *rb)
++{
++ int result;
++ im_roar_state *s = self;
++
++ rb->buf = malloc(BUFSIZE*2*s->channels);
++ if(!rb->buf)
++ return -1;
++
++ result = read(s->fd, rb->buf, BUFSIZE * 2 * s->channels);
++
++ rb->len = result;
++ rb->aux_data = s->rate * s->channels * 2;
++
++ if(s->newtrack)
++ {
++ rb->critical = 1;
++ s->newtrack = 0;
++ }
++
++ if(result == -1 && (errno == EINTR || errno == ERESTART))
++ {
++ return 0; /* Non-fatal error */
++ }
++ else if(result <= 0)
++ {
++ if(result == 0)
++ LOG_INFO0("Reached EOF, no more data available");
++ else
++ LOG_ERROR1("Error reading from sound server: %s", strerror(errno));
++ free(rb->buf);
++ return -1;
++ }
++
++ return rb->len;
++}
++
++input_module_t *roar_open_module(module_param_t *params)
++{
++ input_module_t *mod = calloc(1, sizeof(input_module_t));
++ im_roar_state *s;
++ module_param_t *current;
++ char * server = NULL;
++ int codec = ROAR_CODEC_DEFAULT;
++ int bits = 16;
++ int dir = ROAR_DIR_MONITOR;
++ int use_metadata = 1; /* Default to on */
++
++ mod->getdata = roar_read;
++ mod->handle_event = event_handler;
++ mod->metadata_update = metadata_update;
++
++ mod->internal = calloc(1, sizeof(im_roar_state));
++ s = mod->internal;
++
++ s->fd = -1; /* Set it to something invalid, for now */
++ s->rate = 44100; /* Defaults */
++ s->channels = 2;
++
++ thread_mutex_create(&s->metadatalock);
++
++ current = params;
++
++ while(current)
++ {
++ if(!strcmp(current->name, "rate"))
++ s->rate = atoi(current->value);
++ else if(!strcmp(current->name, "channels"))
++ s->channels = atoi(current->value);
++ else if(!strcmp(current->name, "codec"))
++ codec = roar_str2codec(current->value);
++ else if(!strcmp(current->name, "device"))
++ server = current->value;
++ else if(!strcmp(current->name, "metadata"))
++ use_metadata = atoi(current->value);
++ else if(!strcmp(current->name, "metadatafilename"))
++ ices_config->metadata_filename = current->value;
++ else
++ LOG_WARN1("Unknown parameter %s for roar module", current->name);
++
++ current = current->next;
++ }
++
++ mod->type = ICES_INPUT_PCM;
++
++ switch (codec) {
++ case ROAR_CODEC_PCM_LE:
++ mod->subtype = INPUT_PCM_LE_16;
++ break;
++ case ROAR_CODEC_PCM_BE:
++ mod->subtype = INPUT_PCM_BE_16;
++ break;
++ case ROAR_CODEC_OGG_GENERAL:
++ LOG_WARN0("Codec may not work, specify ogg_vorbis for Vorbis streaming");
++ case ROAR_CODEC_OGG_VORBIS:
++ mod->type = ICES_INPUT_VORBIS;
++ // we do not set mod->subtype here, strange design ices2 has...
++ break;
++ case -1:
++ LOG_ERROR0("Unknown Codec");
++ return NULL;
++ default:
++ LOG_ERROR1("Unsupported Codec: %s", roar_codec2str(codec));
++ return NULL;
++ }
++
++
++ /* First up, lets open the audio device */
++ if ( roar_simple_connect(&s->con, server, "ices2") == -1 ) {
++ LOG_ERROR2("Failed to open sound server %s: %s",
++ server, strerror(errno));
++ goto fail;
++ }
++
++ /* Now, set the required parameters on that device */
++ if ( (s->fd = roar_simple_new_stream_obj(&s->con, &s->stream, s->rate, s->channels, bits, codec, dir)) == -1 ) {
++ LOG_ERROR2("Failed to create a new stream on sound server %s: %s",
++ server, strerror(errno));
++ goto fail;
++ }
++
++ /* We're done, and we didn't fail! */
++ LOG_INFO3("Opened sound server at %s at %d channel(s), %d Hz",
++ server, s->channels, s->rate);
++
++ if(use_metadata)
++ {
++ LOG_INFO0("Starting metadata update thread");
++ if(ices_config->metadata_filename)
++ thread_create("im_roar-metadata", metadata_thread_signal, mod, 1);
++ else
++ thread_create("im_roar-metadata", metadata_thread_stdin, mod, 1);
++ }
++
++ return mod;
++
++fail:
++ close_module(mod); /* safe, this checks for valid contents */
++ return NULL;
++}
++
++
+--- /dev/null
++++ b/src/im_roar.h
+@@ -0,0 +1,36 @@
++/* im_oss.h
++ * - Raw PCM/Ogg Vorbis input from RoarAudio
++ *
++ * Copyright (c) 2001 Michael Smith <msmith at labyrinth.net.au>
++ * Copyright (c) 2009 Philipp Schafft <lion at lion.leolix.org>
++ *
++ * This program is distributed under the terms of the GNU General
++ * Public License, version 2. You may use, modify, and redistribute
++ * it under the terms of this license. A copy should be included
++ * with this source.
++ */
++
++#ifndef __IM_ROAR_H__
++#define __IM_ROAR_H__
++
++#include <thread/thread.h>
++#include <roaraudio.h>
++#include "inputmodule.h"
++
++typedef struct
++{
++ int rate;
++ int channels;
++
++ struct roar_connection con;
++ struct roar_stream stream;
++
++ int fd;
++ char **metadata;
++ int newtrack;
++ mutex_t metadatalock;
++} im_roar_state;
++
++input_module_t *roar_open_module(module_param_t *params);
++
++#endif /* __IM_ROAR_H__ */
+--- a/src/input.c
++++ b/src/input.c
+@@ -19,7 +19,9 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <sys/types.h>
+-#ifdef HAVE_STDINT_H
++#ifdef HAVE_INTTYPES_H
++#include <inttypes.h>
++#elif defined(HAVE_STDINT_H)
+ # include <stdint.h>
+ #endif
+ #include <ogg/ogg.h>
+@@ -36,6 +38,10 @@
+ #include "im_playlist.h"
+ #include "im_stdinpcm.h"
+
++#ifdef HAVE_ROARAUDIO
++#include "im_roar.h"
++#endif
++
+ #ifdef HAVE_OSS
+ #include "im_oss.h"
+ #endif
+@@ -77,6 +83,9 @@
+ static module modules[] = {
+ { "playlist", playlist_open_module},
+ { "stdinpcm", stdin_open_module},
++#ifdef HAVE_ROARAUDIO
++ { "roar", roar_open_module},
++#endif
+ #ifdef HAVE_OSS
+ { "oss", oss_open_module},
+ #endif
+@@ -280,6 +289,7 @@
+ int valid_stream = 1;
+ int inc_count;
+ int not_waiting_for_critical;
++ int foundmodule = 0;
+
+ thread_cond_create(&ices_config->queue_cond);
+ thread_cond_create(&ices_config->event_pending_cond);
+@@ -292,6 +302,7 @@
+ {
+ if(!strcmp(ices_config->playlist_module, modules[current_module].name))
+ {
++ foundmodule = 1;
+ inmod = modules[current_module].open(ices_config->module_params);
+ break;
+ }
+@@ -300,8 +311,12 @@
+
+ if(!inmod)
+ {
+- LOG_ERROR1("Couldn't initialise input module \"%s\"",
+- ices_config->playlist_module);
++ if(foundmodule)
++ LOG_ERROR1("Couldn't initialise input module \"%s\"",
++ ices_config->playlist_module);
++ else
++ LOG_ERROR1("No input module named \"%s\" could be found",
++ ices_config->playlist_module);
+ return;
+ }
+
+--- a/src/log/log.c
++++ b/src/log/log.c
+@@ -46,6 +46,14 @@
+ static mutex_t _logger_mutex;
+ static int _initialized = 0;
+
++typedef struct _log_entry_t
++{
++ char *line;
++ unsigned int len;
++ struct _log_entry_t *next;
++} log_entry_t;
++
++
+ typedef struct log_tag
+ {
+ int in_use;
+@@ -54,18 +62,25 @@
+
+ char *filename;
+ FILE *logfile;
+- unsigned size;
+- unsigned trigger_level;
++ off_t size;
++ off_t trigger_level;
++ int archive_timestamp;
++
++ unsigned long total;
++ unsigned int entries;
++ unsigned int keep_entries;
++ log_entry_t *log_head;
++ log_entry_t **log_tail;
+
+ char *buffer;
+ } log_t;
+
+ static log_t loglist[LOG_MAXLOGS];
+
+-static int _get_log_id();
++static int _get_log_id(void);
+ static void _release_log_id(int log_id);
+-static void _lock_logger();
+-static void _unlock_logger();
++static void _lock_logger(void);
++static void _unlock_logger(void);
+
+
+ static int _log_open (int id)
+@@ -83,11 +98,25 @@
+
+ if (loglist [id] . logfile)
+ {
+- char new_name [255];
++ char new_name [4096];
+ fclose (loglist [id] . logfile);
+ loglist [id] . logfile = NULL;
+ /* simple rename, but could use time providing locking were used */
+- snprintf (new_name, sizeof(new_name), "%s.old", loglist [id] . filename);
++ if (loglist[id].archive_timestamp)
++ {
++ char timestamp [128];
++ time_t now = time(NULL);
++
++ strftime (timestamp, sizeof (timestamp), "%Y%m%d_%H%M%S", localtime (&now));
++ snprintf (new_name, sizeof(new_name), "%s.%s", loglist[id].filename, timestamp);
++ }
++ else {
++ snprintf (new_name, sizeof(new_name), "%s.old", loglist [id] . filename);
++ }
++#ifdef _WIN32
++ if (stat (new_name, &st) == 0)
++ remove (new_name);
++#endif
+ rename (loglist [id] . filename, new_name);
+ }
+ loglist [id] . logfile = fopen (loglist [id] . filename, "a");
+@@ -105,7 +134,7 @@
+ return 1;
+ }
+
+-void log_initialize()
++void log_initialize(void)
+ {
+ int i;
+
+@@ -115,10 +144,15 @@
+ loglist[i].in_use = 0;
+ loglist[i].level = 2;
+ loglist[i].size = 0;
+- loglist[i].trigger_level = 0;
++ loglist[i].trigger_level = 1000000000;
+ loglist[i].filename = NULL;
+ loglist[i].logfile = NULL;
+ loglist[i].buffer = NULL;
++ loglist[i].total = 0;
++ loglist[i].entries = 0;
++ loglist[i].keep_entries = 0;
++ loglist[i].log_head = NULL;
++ loglist[i].log_tail = &loglist[i].log_head;
+ }
+
+ /* initialize mutexes */
+@@ -168,6 +202,9 @@
+ loglist [id] . filename = strdup (filename);
+ if (stat (loglist [id] . filename, &st) == 0)
+ loglist [id] . size = st.st_size;
++ loglist [id] . entries = 0;
++ loglist [id] . log_head = NULL;
++ loglist [id] . log_tail = &loglist [id] . log_head;
+ }
+
+ return id;
+@@ -188,7 +225,8 @@
+ {
+ if (id < 0 || id >= LOG_MAXLOGS)
+ return LOG_EINSANE;
+- if (!strcmp(filename, "") || loglist [id] . in_use == 0)
++ /* NULL filename is ok, empty filename is not. */
++ if ((filename && !strcmp(filename, "")) || loglist [id] . in_use == 0)
+ return LOG_EINSANE;
+ _lock_logger();
+ if (loglist [id] . filename)
+@@ -201,6 +239,16 @@
+ return id;
+ }
+
++int log_set_archive_timestamp(int id, int value)
++{
++ if (id < 0 || id >= LOG_MAXLOGS)
++ return LOG_EINSANE;
++ _lock_logger();
++ loglist[id].archive_timestamp = value;
++ _unlock_logger();
++ return id;
++}
++
+
+ int log_open_with_buffer(const char *filename, int size)
+ {
+@@ -209,6 +257,26 @@
+ }
+
+
++void log_set_lines_kept (int log_id, unsigned int count)
++{
++ if (log_id < 0 || log_id >= LOG_MAXLOGS) return;
++ if (loglist[log_id].in_use == 0) return;
++
++ _lock_logger ();
++ loglist[log_id].keep_entries = count;
++ while (loglist[log_id].entries > count)
++ {
++ log_entry_t *to_go = loglist [log_id].log_head;
++ loglist [log_id].log_head = to_go->next;
++ loglist [log_id].total -= to_go->len;
++ free (to_go->line);
++ free (to_go);
++ loglist [log_id].entries--;
++ }
++ _unlock_logger ();
++}
++
++
+ void log_set_level(int log_id, unsigned level)
+ {
+ if (log_id < 0 || log_id >= LOG_MAXLOGS) return;
+@@ -265,10 +333,19 @@
+ fclose (loglist [log_id] . logfile);
+ loglist [log_id] . logfile = NULL;
+ }
++ while (loglist[log_id].entries)
++ {
++ log_entry_t *to_go = loglist [log_id].log_head;
++ loglist [log_id].log_head = to_go->next;
++ loglist [log_id].total -= to_go->len;
++ free (to_go->line);
++ free (to_go);
++ loglist [log_id].entries--;
++ }
+ _unlock_logger();
+ }
+
+-void log_shutdown()
++void log_shutdown(void)
+ {
+ /* destroy mutexes */
+ #ifndef _WIN32
+@@ -280,18 +357,80 @@
+ _initialized = 0;
+ }
+
++
++static int create_log_entry (int log_id, const char *pre, const char *line)
++{
++ log_entry_t *entry;
++
++ if (loglist[log_id].keep_entries == 0)
++ return fprintf (loglist[log_id].logfile, "%s%s\n", pre, line);
++
++ entry = calloc (1, sizeof (log_entry_t));
++ entry->len = strlen (pre) + strlen (line) + 2;
++ entry->line = malloc (entry->len);
++ snprintf (entry->line, entry->len, "%s%s\n", pre, line);
++ loglist [log_id].total += entry->len;
++ fprintf (loglist[log_id].logfile, "%s", entry->line);
++
++ *loglist [log_id].log_tail = entry;
++ loglist [log_id].log_tail = &entry->next;
++
++ if (loglist [log_id].entries >= loglist [log_id].keep_entries)
++ {
++ log_entry_t *to_go = loglist [log_id].log_head;
++ loglist [log_id].log_head = to_go->next;
++ loglist [log_id].total -= to_go->len;
++ free (to_go->line);
++ free (to_go);
++ }
++ else
++ loglist [log_id].entries++;
++ return entry->len;
++}
++
++
++void log_contents (int log_id, char **_contents, unsigned int *_len)
++{
++ int remain;
++ log_entry_t *entry;
++ char *ptr;
++
++ if (log_id < 0) return;
++ if (log_id >= LOG_MAXLOGS) return; /* Bad log number */
++
++ _lock_logger ();
++ remain = loglist [log_id].total + 1;
++ *_contents = malloc (remain);
++ **_contents= '\0';
++ *_len = loglist [log_id].total;
++
++ entry = loglist [log_id].log_head;
++ ptr = *_contents;
++ while (entry)
++ {
++ int len = snprintf (ptr, remain, "%s", entry->line);
++ if (len > 0)
++ {
++ ptr += len;
++ remain -= len;
++ }
++ entry = entry->next;
++ }
++ _unlock_logger ();
++}
++
++
+ void log_write(int log_id, unsigned priority, const char *cat, const char *func,
+ const char *fmt, ...)
+ {
+ static char *prior[] = { "EROR", "WARN", "INFO", "DBUG" };
+- char tyme[128];
++ int datelen;
++ time_t now;
+ char pre[256];
+ char line[LOG_MAXLINELEN];
+- time_t now;
+ va_list ap;
+
+- if (log_id < 0) return;
+- if (log_id > LOG_MAXLOGS) return; /* Bad log number */
++ if (log_id < 0 || log_id >= LOG_MAXLOGS) return; /* Bad log number */
+ if (loglist[log_id].level < priority) return;
+ if (priority > sizeof(prior)/sizeof(prior[0])) return; /* Bad priority */
+
+@@ -301,13 +440,13 @@
+ now = time(NULL);
+
+ _lock_logger();
+- strftime(tyme, sizeof (tyme), "[%Y-%m-%d %H:%M:%S]", localtime(&now));
++ datelen = strftime (pre, sizeof (pre), "[%Y-%m-%d %H:%M:%S]", localtime(&now));
+
+- snprintf(pre, sizeof (pre), "%s %s%s", prior[priority-1], cat, func);
++ snprintf (pre+datelen, sizeof (pre)-datelen, " %s %s%s ", prior [priority-1], cat, func);
+
+ if (_log_open (log_id))
+ {
+- int len = fprintf (loglist[log_id].logfile, "%s %s %s\n", tyme, pre, line);
++ int len = create_log_entry (log_id, pre, line);
+ if (len > 0)
+ loglist[log_id].size += len;
+ }
+@@ -318,18 +457,21 @@
+
+ void log_write_direct(int log_id, const char *fmt, ...)
+ {
+- char line[LOG_MAXLINELEN];
+ va_list ap;
++ time_t now;
++ char line[LOG_MAXLINELEN];
+
+- if (log_id < 0) return;
++ if (log_id < 0 || log_id >= LOG_MAXLOGS) return;
+
+ va_start(ap, fmt);
+
++ now = time(NULL);
++
+ _lock_logger();
+ vsnprintf(line, LOG_MAXLINELEN, fmt, ap);
+ if (_log_open (log_id))
+ {
+- int len = fprintf(loglist[log_id].logfile, "%s\n", line);
++ int len = create_log_entry (log_id, "", line);
+ if (len > 0)
+ loglist[log_id].size += len;
+ }
+@@ -340,7 +482,7 @@
+ fflush(loglist[log_id].logfile);
+ }
+
+-static int _get_log_id()
++static int _get_log_id(void)
+ {
+ int i;
+ int id = -1;
+@@ -372,7 +514,7 @@
+ _unlock_logger();
+ }
+
+-static void _lock_logger()
++static void _lock_logger(void)
+ {
+ #ifndef _WIN32
+ pthread_mutex_lock(&_logger_mutex);
+@@ -381,7 +523,7 @@
+ #endif
+ }
+
+-static void _unlock_logger()
++static void _unlock_logger(void)
+ {
+ #ifndef _WIN32
+ pthread_mutex_unlock(&_logger_mutex);
+--- a/src/log/log.h
++++ b/src/log/log.h
+@@ -22,20 +22,23 @@
+ #define IO_BUFFER_TYPE _IOLBF
+ #endif
+
+-void log_initialize();
++void log_initialize(void);
+ int log_open_file(FILE *file);
+ int log_open(const char *filename);
+ int log_open_with_buffer(const char *filename, int size);
+ void log_set_level(int log_id, unsigned level);
+ void log_set_trigger(int id, unsigned trigger);
+ int log_set_filename(int id, const char *filename);
++void log_set_lines_kept (int log_id, unsigned int count);
++void log_contents (int log_id, char **_contents, unsigned int *_len);
++int log_set_archive_timestamp(int id, int value);
+ void log_flush(int log_id);
+ void log_reopen(int log_id);
+ void log_close(int log_id);
+-void log_shutdown();
++void log_shutdown(void);
+
+ void log_write(int log_id, unsigned priority, const char *cat, const char *func,
+ const char *fmt, ...);
+-void log_write_direct(int log_id, const char *fmt, ...);
++void log_write_direct(int log_id, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
+
+ #endif /* __LOG_H__ */
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -8,7 +8,7 @@
+ AM_CPPFLAGS = @XIPH_CPPFLAGS@
+ AM_CFLAGS = @XIPH_CFLAGS@
+
+-EXTRA_ices_SOURCES = im_oss.c im_sun.c im_alsa.c
++EXTRA_ices_SOURCES = im_oss.c im_sun.c im_alsa.c im_roar.c
+
+ if HAVE_OSS
+ oss = im_oss.c
+@@ -22,14 +22,19 @@
+ alsa = im_alsa.c
+ endif
+
+-dist_noinst_HEADERS = cfgparse.h input.h inputmodule.h im_playlist.h signals.h stream.h reencode.h encode.h playlist_basic.h logging.h im_stdinpcm.h event.h stream_shared.h metadata.h audio.h resample.h im_sun.h im_oss.h im_alsa.h
++if HAVE_ROARAUDIO
++roar = im_roar.c
++endif
++
++dist_noinst_HEADERS = cfgparse.h input.h inputmodule.h im_playlist.h signals.h stream.h reencode.h encode.h playlist_basic.h logging.h im_stdinpcm.h event.h stream_shared.h metadata.h audio.h resample.h im_sun.h im_oss.h im_alsa.h im_roar.h
+
+-ices_SOURCES = input.c cfgparse.c stream.c ices.c signals.c im_playlist.c reencode.c encode.c playlist_basic.c im_stdinpcm.c stream_shared.c metadata.c playlist_script.c audio.c resample.c $(oss) $(sun) $(alsa)
++ices_SOURCES = input.c cfgparse.c stream.c ices.c signals.c im_playlist.c reencode.c encode.c playlist_basic.c im_stdinpcm.c stream_shared.c metadata.c playlist_script.c audio.c resample.c $(oss) $(sun) $(alsa) $(roar)
+
+ ices_LDADD = log/libicelog.la \
+ timing/libicetiming.la \
+ thread/libicethread.la \
+ avl/libiceavl.la \
++ @ROARAUDIO_LIBS@ \
+ @ALSA_LIBS@ @XIPH_LIBS@
+
+ debug:
+--- a/src/metadata.c
++++ b/src/metadata.c
+@@ -20,6 +20,9 @@
+ #include <string.h>
+ #include <errno.h>
+ #include <unistd.h>
++#ifdef HAVE_SYS_SELECT_H
++#include <sys/select.h>
++#endif
+
+ #include "cfgparse.h"
+ #include "inputmodule.h"
+--- a/src/stream.c
++++ b/src/stream.c
+@@ -291,13 +291,16 @@
+ input_flush_queue(stream->queue, 1);
+ thread_mutex_unlock(&ices_config->flush_lock);
+
++ shout_close(sdsc->shout);
++
++ if (i >= stream->reconnect_attempts)
++ break;
+ while((i < stream->reconnect_attempts ||
+ stream->reconnect_attempts==-1) &&
+ !ices_config->shutdown)
+ {
+- i++;
+ LOG_WARN0("Trying reconnect after server socket error");
+- shout_close(sdsc->shout);
++ i++;
+ if((shouterr = shout_open(sdsc->shout)) == SHOUTERR_SUCCESS)
+ {
+ LOG_INFO3("Connected to server: %s:%d%s",
+@@ -312,6 +315,7 @@
+ thread_mutex_lock(&ices_config->flush_lock);
+ stream->wait_for_critical = 1;
+ input_flush_queue(stream->queue, 0);
++ stream->skip = 0;
+ thread_mutex_unlock(&ices_config->flush_lock);
+ break;
+ }
+@@ -331,7 +335,6 @@
+ thread_sleep (stream->reconnect_delay*1000000);
+ }
+ }
+- stream->skip = 0;
+ }
+ stream->buffer_failures++;
+ }
+--- a/src/thread/thread.c
++++ b/src/thread/thread.c
+@@ -36,7 +36,6 @@
+ #else
+ #include <windows.h>
+ #include <winbase.h>
+-#include <implement.h>
+ #endif
+
+ #include <signal.h>
+@@ -196,6 +195,7 @@
+ avl_tree_free(_mutextree, _free_mutex);
+ #endif
+ avl_tree_free(_threadtree, _free_thread);
++ _threadtree = NULL;
+ }
+
+ #ifdef THREAD_DEBUG
+@@ -223,6 +223,7 @@
+ sigdelset(&ss, SIGKILL);
+ sigdelset(&ss, SIGSTOP);
+ sigdelset(&ss, SIGSEGV);
++ sigdelset(&ss, SIGCHLD);
+ sigdelset(&ss, SIGBUS);
+ if (pthread_sigmask(SIG_BLOCK, &ss, NULL) != 0) {
+ #ifdef THREAD_DEBUG
+@@ -292,6 +293,7 @@
+ start->arg = arg;
+ start->thread = thread;
+
++ pthread_attr_setstacksize (&attr, 512*1024);
+ pthread_attr_setinheritsched (&attr, PTHREAD_INHERIT_SCHED);
+ if (detached)
+ {
+@@ -594,7 +596,7 @@
+ avl_delete(_threadtree, th, _free_thread);
+ _mutex_unlock(&_threadtree_mutex);
+ }
+-
++
+ pthread_exit ((void*)val);
+ }
+
+@@ -811,3 +813,29 @@
+ }
+
+
++#ifdef HAVE_PTHREAD_SPIN_LOCK
++void thread_spin_create (spin_t *spin)
++{
++ int x = pthread_spin_init (&spin->lock, PTHREAD_PROCESS_PRIVATE);
++ if (x)
++ abort();
++}
++
++void thread_spin_destroy (spin_t *spin)
++{
++ pthread_spin_destroy (&spin->lock);
++}
++
++void thread_spin_lock (spin_t *spin)
++{
++ int x = pthread_spin_lock (&spin->lock);
++ if (x != 0)
++ abort();
++}
++
++void thread_spin_unlock (spin_t *spin)
++{
++ pthread_spin_unlock (&spin->lock);
++}
++#endif
++
+--- a/src/thread/thread.h
++++ b/src/thread/thread.h
+@@ -89,6 +89,24 @@
+ pthread_rwlock_t sys_rwlock;
+ } rwlock_t;
+
++#ifdef HAVE_PTHREAD_SPIN_LOCK
++typedef struct
++{
++ pthread_spinlock_t lock;
++} spin_t;
++
++void thread_spin_create (spin_t *spin);
++void thread_spin_destroy (spin_t *spin);
++void thread_spin_lock (spin_t *spin);
++void thread_spin_unlock (spin_t *spin);
++#else
++typedef mutex_t spin_t;
++#define thread_spin_create(x) thread_mutex_create(x)
++#define thread_spin_destroy(x) thread_mutex_destroy(x)
++#define thread_spin_lock(x) thread_mutex_lock(x)
++#define thread_spin_unlock(x) thread_mutex_unlock(x)
++#endif
++
+ #define thread_create(n,x,y,z) thread_create_c(n,x,y,z,__LINE__,__FILE__)
+ #define thread_mutex_create(x) thread_mutex_create_c(x,__LINE__,__FILE__)
+ #define thread_mutex_lock(x) thread_mutex_lock_c(x,__LINE__,__FILE__)
+--- a/src/timing/timing.c
++++ b/src/timing/timing.c
+@@ -11,15 +11,22 @@
+
+ #include <stdlib.h>
+ #include <sys/types.h>
+-#ifdef HAVE_STDINT_H
+-# include <stdint.h>
+-#endif
+
+ #ifdef _WIN32
+ #include <windows.h>
+ #include <mmsystem.h>
+ #else
+-#include <sys/time.h>
++#ifdef TIME_WITH_SYS_TIME
++# include <sys/time.h>
++# include <time.h>
++#else
++# ifdef HAVE_SYS_TIME_H
++# include <sys/time.h>
++# else
++# include <time.h>
++# endif
++#endif
++
+ #include <unistd.h>
+ #endif
+
+@@ -27,7 +34,7 @@
+ #include <sys/select.h>
+ #endif
+
+-#ifdef __MINGW32__
++#ifdef HAVE_SYS_TIMEB_H
+ #include <sys/timeb.h>
+ #endif
+
+@@ -40,24 +47,23 @@
+ */
+ uint64_t timing_get_time(void)
+ {
+-#ifdef _WIN32
+-#ifdef __MINGW32__
+- struct timeb t;
+-
+- ftime(&t);
+- return t.time * 1000 + t.millitm;
+-#else
+- return timeGetTime();
+-#endif
+-#else
++#ifdef HAVE_GETTIMEOFDAY
+ struct timeval mtv;
+
+ gettimeofday(&mtv, NULL);
+
+ return (uint64_t)(mtv.tv_sec) * 1000 + (uint64_t)(mtv.tv_usec) / 1000;
++#elif HAVE_FTIME
++ struct timeb t;
++
++ ftime(&t);
++ return t.time * 1000 + t.millitm;
++#else
++#error need time query handler
+ #endif
+ }
+
++
+ void timing_sleep(uint64_t sleeptime)
+ {
+ struct timeval sleeper;
+--- a/src/timing/timing.h
++++ b/src/timing/timing.h
+@@ -9,11 +9,13 @@
+ #define __TIMING_H__
+
+ #include <sys/types.h>
+-#ifdef HAVE_STDINT_H
++#ifdef HAVE_INTTYPES_H
++#include <inttypes.h>
++#elif defined(HAVE_STDINT_H)
+ #include <stdint.h>
+ #endif
+
+-#ifdef _WIN32
++#if defined(_WIN32) && !defined(int64_t)
+ typedef __int64 int64_t;
+ typedef unsigned __int64 uint64_t;
+ #endif
diff --git a/debian/patches/README b/debian/patches/README
new file mode 100644
index 0000000..80c1584
--- /dev/null
+++ b/debian/patches/README
@@ -0,0 +1,3 @@
+0xxx: Grabbed from upstream development.
+1xxx: Possibly relevant for upstream adoption.
+2xxx: Only relevant for official Debian release.
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644
index 0000000..04e5e1e
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1 @@
+0001_sync_20090819.patch
--
ices2 packaging
More information about the pkg-multimedia-commits
mailing list