Commit 1f3c6c2d authored by Karl Heyes's avatar Karl Heyes

bump to kh31

The main changes are listed below but there is a lot of noise from behind the scenes
work like quicker stats updates, code re-arranging and infrequent used code like the
allocation code which is not usually compiled in.

Implement scatter-gather IO, initially for flv wrapping as that will make a lot of
use of it and should save a lot of memory copies. The icy metadata should also be a
candidate for this.

Add better handling to relays with multiple servers and fallbacks. Problem entries
can be skipped when restarting. 

Fixup build system for mingw32 cross compile. VC was getting too annoying but should
still be an option if needed later.  This now allows us to build with newer dependent
libs without much extra work.   The GUI component is not built now (VC specific) but
it was of limited use and most win32 users configure the service.



svn path=/icecast/branches/kh/icecast/; revision=18147
parent deba1eba
......@@ -3,7 +3,10 @@
AUTOMAKE_OPTIONS = foreign
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = src conf doc web admin win32
SUBDIRS = conf doc web admin src
if WIN32
SUBDIRS += win32
endif
EXTRA_DIST = HACKING config.h.vc6 m4/acx_pthread.m4 m4/ogg.m4 \
m4/theora.m4 m4/vorbis.m4 m4/speex.m4\
......@@ -19,5 +22,7 @@ debug:
profile:
$(MAKE) all CFLAGS="@PROFILE@"
staticdebug:
$(MAKE) all CFLAGS="-g -DLIBXML_STATIC -DCURL_STATICLIB" LDFLAGS="${LDFLAGS} -all-static"
static:
$(MAKE) all LDFLAGS="${LDFLAGS} -all-static"
$(MAKE) all CFLAGS="-O2 -DLIBXML_STATIC -DCURL_STATICLIB" LDFLAGS="${LDFLAGS} -all-static"
......@@ -16,6 +16,40 @@ Feature differences from SVN trunk
any extra tags are show in the conf/icecast.xml.dist file
2.3.2-kh31
. Add generic scattered IO routines, listeners wanting FLV wrapping now use this which
saves a lot of memory copying and therefore load.
. build setup for mingw32. This should help with library updates for us, drop GUI build
. relay restarting fixes included for certain error cases. relays are treaated as
failed if they stop within 60 seconds and skip on to next server if specified.
. a better trigger for on-demand relay if fallback has listeners.
. on reload when changeowner used, allow for listening sockets to be reopend but
prevent closing priviledged ports unless missing from xml
. prevent unescape routine from creating non-printable chars
. ignore per-mount username when source is using shoutcast protocol.
. URL auth can now accept a "ice-username: ..." in the response headers for setting the
username. For setups that use query args for auth
. expand args applied to xsl requests, url encoded now.
. modify k and m in bitrates to be on 1000 not 1024
. accesslog modification to parsing, optionally set <type> in <accesslog> to CLF-ESC
to escape-encode strings instead of using "".
. if falling back to file, the bitrate used takes, in order of priority, incoming
bitrate, limit-rate and then [value] in filename eg /fallback-[128]
. fix a large ogg page bug, flac is probably the only one showing this up currently
. fix a couple of rare crash cases with file serving clients.
. prevent intro file sending when override triggered.
. make access log report query args on the request, but truncate the strings if too long.
. minor change to send limiter
. move incoming rate limiter to source client specific code.
. Add server-wide redirect tags.
. use per-source stats handles for updates, reduces lookups and avoids taking a
shared lock.
. minor log message changes.
. fix fallback trigger if source timeout occurs
. fix possible sources count inconsistency with failed relays
. entity expansion in stats conversion routines added
. fixup debug allocation code. not normally used.
2.3.2-kh30
. stats updates.
Split stats lock into global and source stats locks, reduces contention.
......
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="iso-8859-1" indent="yes"/>
<xsl:template match = "/icestats" >
<xsl:for-each select="source">
<SHOUTCASTSERVER>
<CURRENTLISTENERS><xsl:value-of select="listeners" /></CURRENTLISTENERS>
<PEAKLISTENERS><xsl:value-of select="listener_peak" /></PEAKLISTENERS>
<MAXLISTENERS><xsl:value-of select="max_listeners" /></MAXLISTENERS>
<REPORTEDLISTENERS>NA</REPORTEDLISTENERS>
<AVERAGETIME>NA</AVERAGETIME>
<SERVERGENRE><xsl:value-of select="genre" /></SERVERGENRE>
<SERVERURL><xsl:value-of select="server_url" /></SERVERURL>
<SERVERTITLE><xsl:value-of select="server_name" /></SERVERTITLE>
<SONGTITLE><xsl:if test="artist"><xsl:value-of select="artist" /> - </xsl:if><xsl:value-of select="title" /></SONGTITLE>
<SONGURL><xsl:value-of select="listenurl" /></SONGURL>
<IRC>NA</IRC>
<ICQ>NA</ICQ>
<AIM>NA</AIM>
<WEBHITS>NA</WEBHITS>
<STREAMHITS>NA</STREAMHITS>
<STREAMSTATUS>NA</STREAMSTATUS>
<BITRATE><xsl:value-of select="bitrate" /></BITRATE>
<CONTENT><xsl:value-of select="server_type" /></CONTENT>
<VERSION><xsl:value-of select="server_id" /></VERSION>
<WEBDATA>
<INDEX>NA</INDEX>
<LISTEN>NA</LISTEN>
<PALM7>NA</PALM7>
<LOGIN>NA</LOGIN>
<LOGINFAIL>NA</LOGINFAIL>
<PLAYED>NA</PLAYED>
<COOKIE>NA</COOKIE>
<ADMIN>NA</ADMIN>
<UPDINFO>NA</UPDINFO>
<KICKSRC>NA</KICKSRC>
<KICKDST>NA</KICKDST>
<UNBANDST>NA</UNBANDST>
<BANDST>NA</BANDST>
<VIEWBAN>NA</VIEWBAN>
<UNRIPDST>NA</UNRIPDST>
<RIPDST>NA</RIPDST>
<VIEWRIP>NA</VIEWRIP>
<VIEWXML>NA</VIEWXML>
<VIEWLOG>NA</VIEWLOG>
<INVALID>NA</INVALID>
</WEBDATA>
<LISTENERS>
<xsl:for-each select="listener">
<LISTENER>
<HOSTNAME><xsl:value-of select="IP" /><xsl:if test="username"> (<xsl:value-of select="username" />)</xsl:if></HOSTNAME>
<USERAGENT><xsl:value-of select="UserAgent" /></USERAGENT>
<UNDERRUNS>NA</UNDERRUNS>
<CONNECTTIME><xsl:value-of select="Connected" /></CONNECTTIME>
<POINTER>NA</POINTER>
<UID>NA</UID>
</LISTENER>
</xsl:for-each>
</LISTENERS>
<SONGHISTORY>
<SONG>
<PLAYEDAT>1259797160</PLAYEDAT>
<TITLE>Little Texas - She&#x27;s Got Her Daddy&#x27;s Money</TITLE>
</SONG>
</SONGHISTORY>
</SHOUTCASTSERVER>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
\ No newline at end of file
AC_INIT([Icecast], [2.3.2-kh30], [karl@xiph.org])
AC_INIT([Icecast], [2.3.2-kh31], [karl@xiph.org])
LT_INIT
AC_PREREQ(2.59)
......@@ -9,6 +9,7 @@ AM_INIT_AUTOMAKE
AM_CONFIG_HEADER(config.h)
AM_MAINTAINER_MODE
AC_PROG_CXX
AC_PROG_CC
AC_CANONICAL_HOST
AC_PROG_LIBTOOL
......@@ -25,6 +26,7 @@ else
PROFILE="-pg -g"
AC_DEFINE([_GNU_SOURCE], 1, [Define to include GNU extensions to POSIX])
fi
AM_CONDITIONAL([WIN32], [test x$host_os = xmingw32])
dnl Checks for programs.
......@@ -34,9 +36,8 @@ dnl Checks for header files.
AC_HEADER_STDC
AC_HEADER_TIME
AC_CHECK_HEADERS([signal.h fnmatch.h limits.h sys/timeb.h])
AC_CHECK_HEADERS([signal.h fnmatch.h limits.h sys/timeb.h malloc.h])
AC_CHECK_HEADERS(pwd.h, AC_DEFINE(CHUID, 1, [Define if you have pwd.h]),,)
AC_CHECK_HEADERS(unistd.h, AC_DEFINE(CHROOT, 1, [Define if you have unistd.h]),,)
dnl Checks for typedefs, structures, and compiler characteristics.
XIPH_C__FUNC__
......@@ -46,10 +47,19 @@ AC_TYPE_OFF_T
AC_CHECK_TYPES([struct timespec])
dnl Checks for library functions.
AC_CHECK_FUNCS([localtime_r poll atoll strtoll strcasecmp getrlimit gettimeofday ftime fsync])
AC_CHECK_DECLS([localtime_r],,,
[#include <time.h>
#include <pthread.h>])
AC_CHECK_FUNCS([fnmatch chroot fork poll atoll strtoll strcasecmp getrlimit gettimeofday ftime fsync])
AC_CHECK_TYPES([struct signalfd_siginfo],
[AC_DEFINE(HAVE_SIGNALFD, 1 ,[Define if signalfd exists])], [],
[#include <sys/signalfd.h>])
if test "x$ac_cv_func_fnmatch" != "xyes"
then
AC_CHECK_LIB(fnmatch, fnmatch, [XIPH_VAR_APPEND([XIPH_LIBS],["-lfnmatch"])],
[ AC_CHECK_LIB(iberty, fnmatch, [XIPH_VAR_APPEND([XIPH_LIBS],["-liberty"])])
])
fi
AC_SEARCH_LIBS(nanosleep, rt posix4,
AC_DEFINE(HAVE_NANOSLEEP, 1, [Define if you have nanosleep]))
AC_SEARCH_LIBS(clock_gettime, rt posix4,
......@@ -140,8 +150,10 @@ XIPH_PATH_OPENSSL([
[ AC_MSG_NOTICE([SSL disabled!])
])
ICECAST_OPTIONAL="$ICECAST_OPTIONAL auth_cmd.o"
AC_DEFINE([MIMETYPESFILE],"/etc/mime.types", [Default location of mime types file])
if test "x$ac_cv_func_fork" = "xyes"
then
ICECAST_OPTIONAL="$ICECAST_OPTIONAL auth_cmd.o"
fi
AC_DEFINE([ICECAST_TIME_FMT],["%a, %d %b %Y %H:%M:%S %z"], [time format for strftime])
dnl Make substitutions
......
......@@ -4,7 +4,11 @@ AUTOMAKE_OPTIONS = foreign
SUBDIRS = avl thread httpp net log timing
bin_PROGRAMS = icecast
if WIN32
noinst_LIBRARIES = libicecast.a
else
bin_PROGRAMS = icecast
endif
noinst_HEADERS = admin.h cfgfile.h logging.h sighandler.h connection.h \
global.h util.h slave.h source.h stats.h refbuf.h client.h \
......@@ -27,6 +31,10 @@ icecast_DEPENDENCIES = @ICECAST_OPTIONAL@ net/libicenet.la thread/libicethread.l
httpp/libicehttpp.la log/libicelog.la avl/libiceavl.la timing/libicetiming.la
icecast_LDADD = $(icecast_DEPENDENCIES) @XIPH_LIBS@ @KATE_LIBS@
libicecast_a_SOURCES = $(icecast_SOURCES)
libicecast_a_DEPENDENCIES = $(icecast_DEPENDENCIES)
libicecast_a_LIBADD = $(icecast_DEPENDENCIES)
AM_CFLAGS = @XIPH_CFLAGS@
AM_CPPFLAGS = @XIPH_CPPFLAGS@
AM_LDFLAGS = @XIPH_LDFLAGS@ @KATE_LIBS@
......
......@@ -61,6 +61,9 @@ static int command_updatemetadata(client_t *client, source_t *source, int respon
static int command_admin_function (client_t *client, int response);
static int command_list_log (client_t *client, int response);
static int command_manage_relay (client_t *client, int response);
#ifdef MY_ALLOC
static int command_alloc(client_t *client);
#endif
static int admin_handle_general_request(client_t *client, const char *command);
......@@ -84,6 +87,9 @@ static struct admin_command admin_general[] =
{ "manageauth", RAW, { command_manageauth } },
{ "listmounts", RAW, { command_list_mounts } },
{ "function", RAW, { command_admin_function } },
#ifdef MY_ALLOC
{ "alloc", RAW, { command_alloc } },
#endif
{ "streamlist.txt", TEXT, { command_list_mounts } },
{ "streams", TEXT, { command_list_mounts } },
{ "showlog.txt", TEXT, { command_list_log } },
......@@ -592,50 +598,6 @@ static int command_manage_relay (client_t *client, int response)
}
static void add_listener_node (xmlNodePtr srcnode, client_t *listener)
{
const char *useragent;
char buf[30];
xmlNodePtr node = xmlNewChild (srcnode, NULL, XMLSTR("listener"), NULL);
snprintf (buf, sizeof (buf), "%lu", listener->connection.id);
xmlSetProp (node, XMLSTR("id"), XMLSTR(buf));
xmlNewChild (node, NULL, XMLSTR("IP"), XMLSTR(listener->connection.ip));
useragent = httpp_getvar (listener->parser, "user-agent");
if (useragent && xmlCheckUTF8((unsigned char *)useragent))
{
xmlChar *str = xmlEncodeEntitiesReentrant (srcnode->doc, XMLSTR(useragent));
xmlNewChild (node, NULL, XMLSTR("UserAgent"), str);
xmlFree (str);
}
if ((listener->flags & (CLIENT_ACTIVE|CLIENT_IN_FSERVE)) == CLIENT_ACTIVE)
{
source_t *source = listener->shared_data;
snprintf (buf, sizeof (buf), "%"PRIu64, source->client->queue_pos - listener->queue_pos);
}
else
snprintf (buf, sizeof (buf), "0");
xmlNewChild (node, NULL, XMLSTR("lag"), XMLSTR(buf));
if (listener->worker)
{
snprintf (buf, sizeof (buf), "%lu",
(unsigned long)(listener->worker->current_time.tv_sec - listener->connection.con_time));
xmlNewChild (node, NULL, XMLSTR("Connected"), XMLSTR(buf));
}
if (listener->username)
{
xmlChar *str = xmlEncodeEntitiesReentrant (srcnode->doc, XMLSTR(listener->username));
xmlNewChild (node, NULL, XMLSTR("username"), str);
xmlFree (str);
}
}
/* populate within srcnode, groups of 0 or more listener tags detailing
* information about each listener connected on the provide source.
*/
......@@ -649,7 +611,7 @@ void admin_source_listeners (source_t *source, xmlNodePtr srcnode)
while (node)
{
client_t *listener = (client_t *)node->key;
add_listener_node (srcnode, listener);
stats_listener_to_xml (listener, srcnode);
node = avl_get_next (node);
}
}
......@@ -724,7 +686,7 @@ static int command_show_listeners (client_t *client, source_t *source, int respo
client_t *listener = source_find_client (source, id);
if (listener)
add_listener_node (srcnode, listener);
stats_listener_to_xml (listener, srcnode);
}
thread_mutex_unlock (&source->lock);
......@@ -1242,3 +1204,33 @@ static int command_updatemetadata(client_t *client, source_t *source, int respon
return admin_send_response (doc, client, response, "updatemetadata.xsl");
}
#ifdef MY_ALLOC
static int command_alloc(client_t *client)
{
xmlDocPtr doc = xmlNewDoc (XMLSTR("1.0"));
xmlNodePtr rootnode = xmlNewDocNode(doc, NULL, XMLSTR("icestats"), NULL);
avl_node *node;
xmlDocSetRootElement(doc, rootnode);
avl_tree_rlock (global.alloc_tree);
node = avl_get_first (global.alloc_tree);
while (node)
{
alloc_node *an = node->key;
char value[25];
xmlNodePtr bnode = xmlNewChild (rootnode, NULL, XMLSTR("block"), NULL);
xmlSetProp (bnode, XMLSTR("name"), XMLSTR(an->name));
snprintf (value, sizeof value, "%d", an->count);
xmlNewChild (bnode, NULL, XMLSTR("count"), XMLSTR(value));
snprintf (value, sizeof value, "%d", an->allocated);
xmlNewChild (bnode, NULL, XMLSTR("allocated"), XMLSTR(value));
node = avl_get_next (node);
}
avl_tree_unlock (global.alloc_tree);
return admin_send_response (doc, client, RAW, "stats.xsl");
}
#endif
......@@ -22,6 +22,9 @@
#include <string.h>
#include <errno.h>
#include <stdio.h>
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif
#include "auth.h"
#include "auth_htpasswd.h"
......@@ -382,34 +385,52 @@ static void *auth_run_thread (void *arg)
int move_listener (client_t *client, struct _fbinfo *finfo)
{
source_t *source, *prev;
source_t *source;
const char *mount = finfo->mount;
int rate = finfo->limit;
mount_proxy *minfo;
ice_config_t *config = config_get_config();
DEBUG1 ("moving listener to %s", finfo->mount);
avl_tree_rlock (global.source_tree);
source = source_find_mount (finfo->mount);
while (source)
source = source_find_mount_raw (mount);
while (1)
{
minfo = config_find_mount (config, mount);
if (rate == 0 && minfo && minfo->limit_rate)
rate = minfo->limit_rate;
if (source == NULL)
break;
thread_mutex_lock (&source->lock);
if (source_available (source))
{
config_release_config();
avl_tree_unlock (global.source_tree);
source_setup_listener (source, client);
client->flags |= CLIENT_HAS_MOVED;
thread_mutex_unlock (&source->lock);
return 0;
}
prev = source;
if (prev->fallback.mount)
source = source_find_mount (prev->fallback.mount);
else
source = NULL;
thread_mutex_unlock (&prev->lock);
mount = minfo ? minfo->fallback_mount : NULL;
thread_mutex_unlock (&source->lock);
}
config_release_config();
avl_tree_unlock (global.source_tree);
if (client->flags & CLIENT_IS_SLAVE)
return -1;
DEBUG1 ("no source, trying %s as a file", finfo->mount);
if (finfo->flags & FS_OVERRIDE)
{
finfo->mount = finfo->fallback;
finfo->fallback = NULL;
finfo->flags &= ~FS_OVERRIDE;
}
if (finfo->limit == 0)
{
if (rate == 0)
if (sscanf (finfo->mount, "%*[^[][%d]", &rate) == 1)
rate = rate * 1000/8;
finfo->limit = rate;
}
return fserve_setup_client_fb (client, finfo);
}
......@@ -836,7 +857,7 @@ int auth_check_source (client_t *client, const char *mount)
ret = -1;
if (mountinfo->password)
pass = mountinfo->password;
if (mountinfo->username)
if (mountinfo->username && client->server_conn->shoutcast_compat == 0)
user = mountinfo->username;
}
if (connection_check_pass (client->parser, user, pass) > 0)
......@@ -858,6 +879,8 @@ void auth_initialise (void)
void auth_shutdown (void)
{
if (allow_auth == 0)
return;
allow_auth = 0;
thread_rwlock_wlock (&auth_lock);
thread_rwlock_unlock (&auth_lock);
......
......@@ -13,9 +13,6 @@
#ifndef __AUTH_H__
#define __AUTH_H__
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
struct source_tag;
struct auth_tag;
......
......@@ -44,6 +44,7 @@
#include "client.h"
#include "cfgfile.h"
#include "httpp/httpp.h"
#include "global.h"
#include "logging.h"
#define CATMODULE "auth_cmd"
......
......@@ -13,10 +13,6 @@
#ifndef __AUTH_CMD_H__
#define __AUTH_CMD_H__
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
int auth_get_cmd_auth (auth_t *, config_options_t *options);
#endif
......
......@@ -32,6 +32,7 @@
#include "cfgfile.h"
#include "httpp/httpp.h"
#include "md5.h"
#include "global.h"
#include "logging.h"
#define CATMODULE "auth_htpasswd"
......
......@@ -13,9 +13,6 @@
#ifndef __AUTH_HTPASSWD_H__
#define __AUTH_HTPASSWD_H__
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
int auth_get_htpasswd_auth (auth_t *auth, config_options_t *options);
......
......@@ -86,6 +86,7 @@
#include "cfgfile.h"
#include "httpp/httpp.h"
#include "mpeg.h"
#include "global.h"
#include "logging.h"
#define CATMODULE "auth_url"
......@@ -218,6 +219,17 @@ static int handle_returned_header (void *ptr, size_t size, size_t nmemb, void *s
if (eol)
*eol = '\0';
}
if (strncasecmp (ptr, "ice-username: ", 14) == 0)
{
int len = strcspn ((char*)ptr+14, "\r\n");
char *name = malloc (len+1);
if (name)
{
snprintf (name, len+1, "%s", (char *)ptr+14);
free (client->username);
client->username = name;
}
}
if (strncasecmp (ptr, "Location: ", 10) == 0)
{
int len = strcspn ((char*)ptr+10, "\r\n");
......
......@@ -13,9 +13,6 @@
#ifndef __AUTH_URL_H__
#define __AUTH_URL_H__
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
int auth_get_url_auth (auth_t *authenticator, config_options_t *options);
......
......@@ -62,11 +62,13 @@
#define CONFIG_DEFAULT_LOG_DIR "/usr/local/icecast/logs"
#define CONFIG_DEFAULT_WEBROOT_DIR "/usr/local/icecast/webroot"
#define CONFIG_DEFAULT_ADMINROOT_DIR "/usr/local/icecast/admin"
#define MIMETYPESFILE "/etc/mime.types"
#else
#define CONFIG_DEFAULT_BASE_DIR ".\\"
#define CONFIG_DEFAULT_LOG_DIR ".\\logs"
#define CONFIG_DEFAULT_WEBROOT_DIR ".\\webroot"
#define CONFIG_DEFAULT_ADMINROOT_DIR ".\\admin"
#define MIMETYPESFILE ".\\mime.types"
#endif
static ice_config_t _current_configuration;
......@@ -157,9 +159,9 @@ int config_get_bitrate (xmlNodePtr node, void *x)
return 1;
sscanf ((char*)str, "%"SCNd64 "%c", p, &metric);
if (metric == 'k' || metric == 'K')
(*p) *= 1024;
(*p) *= 1000;
if (metric == 'm' || metric == 'M')
(*p) *= 1024*1024;
(*p) *= 10000000;
xmlFree (str);
}
return 0;
......@@ -228,6 +230,19 @@ void config_init_configuration(ice_config_t *configuration)
}
redirect_host *config_clear_redirect (redirect_host *redir)
{
redirect_host *next = NULL;
if (redir)
{
next = redir->next;
xmlFree (redir->server);
free (redir);
}
return next;
}
relay_server *config_clear_relay (relay_server *relay)
{
relay_server *next = relay->next;
......@@ -353,6 +368,9 @@ void config_clear(ice_config_t *c)
while (c->relay)
c->relay = config_clear_relay (c->relay);
while (c->redirect_hosts)
c->redirect_hosts = config_clear_redirect (c->redirect_hosts);
while (c->mounts)
{
mount_proxy *to_go = c->mounts;
......@@ -602,11 +620,13 @@ static int _parse_security (xmlNodePtr node, void *arg)
static int _parse_accesslog (xmlNodePtr node, void *arg)
{
access_log *log = arg;
struct access_log *log = arg;
char *type = NULL;
struct cfg_tag icecast_tags[] =
{
{ "name", config_get_str, &log->name },
{ "ip", config_get_bool, &log->log_ip },
{ "type", config_get_str, &type },
{ "archive", config_get_bool, &log->archive },
{ "exclude_ext", config_get_str, &log->exclude_ext },
{ "display", config_get_int, &log->display },
......@@ -615,9 +635,16 @@ static int _parse_accesslog (xmlNodePtr node, void *arg)
};
log->logid = -1;
return parse_xml_tags (node, icecast_tags);
log->type = LOG_ACCESS_CLF;
if (parse_xml_tags (node, icecast_tags))
return 2;
if (type && strcmp (type, "CLF-ESC") == 0)
log->type = LOG_ACCESS_CLF_ESC;
xmlFree (type);
return 0;
}
static int _parse_errorlog (xmlNodePtr node, void *arg)
{
error_log *log = arg;
......@@ -659,7 +686,6 @@ static int _parse_logging (xmlNodePtr node, void *arg)
struct cfg_tag icecast_tags[] =
{
{ "accesslog", _parse_accesslog, &config->access_log },
{ "errorlog", _parse_errorlog, &config->error_log },
{ "playlistlog", _parse_playlistlog, &config->playlist_log },
{ "accesslog", config_get_str, &config->access_log.name },
{ "accesslog_ip", config_get_bool, &config->access_log.log_ip },
......@@ -667,7 +693,8 @@ static int _parse_logging (xmlNodePtr node, void *arg)
config_get_str, &config->access_log.exclude_ext },
{ "accesslog_lines",
config_get_int, &config->access_log.display },
{ "errorlog", config_get_str, &config->error_log },
{ "errorlog", _parse_errorlog, &config->error_log },
{ "errorlog", config_get_str, &config->error_log.name },
{ "errorlog_lines", config_get_int, &config->error_log.display },
{ "loglevel", config_get_int, &config->error_log.level },
{ "playlistlog", config_get_str, &config->playlist_log },
......@@ -678,6 +705,7 @@ static int _parse_logging (xmlNodePtr node, void *arg)
{ NULL, NULL, NULL }
};
config->access_log.type = LOG_ACCESS_CLF;
config->access_log.logid = -1;
config->access_log.display = 100;
config->access_log.archive = -1;
......@@ -830,8 +858,10 @@ static int _parse_mount (xmlNodePtr node, void *arg)
mount->url_ogg_meta = 1;
mount->source_timeout = config->source_timeout;
mount->file_seekable = 1;
mount->access_log.type = LOG_ACCESS_CLF;
mount->access_log.logid = -1;
mount->access_log.log_ip = 1;
mount->fallback_override = 1;
if (parse_xml_tags (node, icecast_tags))
return -1;
......@@ -963,6 +993,36 @@ static int _parse_relay (xmlNodePtr node, void *arg)
return 0;
}
static int _parse_redirect (xmlNodePtr node, void *arg)
{
ice_config_t *config = arg;
redirect_host *redir = calloc (1, sizeof (*redir));
struct cfg_tag icecast_tags[] =
{
{ "host", config_get_str, &redir->server },
{ "port", config_get_int, &redir->port },
{ NULL, NULL, NULL },
};
do
{
redir->port = 8000;
if (parse_xml_tags (node, icecast_tags))
break;
if (redir->server == NULL || redir->port < 1 || redir->port > 65536)
break;
redir->next = config->redirect_hosts;
config->redirect_hosts = redir;
return 0;
} while (0);
free (redir);
return -1;
}
static int _parse_limits (xmlNodePtr node, void *arg)
{
ice_config_t *config = arg;
......@@ -1095,6 +1155,7 @@ static int _parse_root (xmlNodePtr node, ice_config_t *config)
{ "master-ssl-port", config_get_int, &config->master_ssl_port },
{ "master-redirect", config_get_bool, &config->master_redirect },
{ "max-redirect-slaves",config_get_int, &config->max_redirects },
{ "redirect", _parse_redirect, config },
{ "shoutcast-mount", config_get_str, &config->shoutcast_mount },
{ "listen-socket", _parse_listen_sock, config },
{ "limits", _parse_limits, config },
......
......@@ -30,18 +30,32 @@ typedef struct _listener_t listener_t;
#include "auth.h"
#include "compat.h"
typedef struct
typedef struct _redirect_host
{
struct _redirect_host *next;
time_t next_update;
char *server;
int port;
} redirect_host;
typedef struct access_log
{
char *name;
int logid;
int log_ip;
int type;
int archive;
int display;
int size;
char *exclude_ext;
} access_log;
typedef struct
#define LOG_ACCESS_CLF 0
#define LOG_ACCESS_CLF_ESC 1
typedef struct error_log
{
char *name;
int logid;
......@@ -51,7 +65,7 @@ typedef struct
int level;
} error_log;
typedef struct
typedef struct playlist_log
{
char *name;
int logid;
......@@ -131,7 +145,7 @@ typedef struct _mount_proxy {
unsigned int max_stream_duration;
unsigned int max_listener_duration;
access_log access_log;