[xiph-commits] r11146 - icecast/branches/kh/icecast/src
karl at svn.xiph.org
karl at svn.xiph.org
Sun Apr 16 16:22:31 PDT 2006
Author: karl
Date: 2006-04-16 16:22:20 -0700 (Sun, 16 Apr 2006)
New Revision: 11146
Modified:
icecast/branches/kh/icecast/src/admin.c
icecast/branches/kh/icecast/src/auth.c
icecast/branches/kh/icecast/src/auth.h
icecast/branches/kh/icecast/src/auth_url.c
icecast/branches/kh/icecast/src/cfgfile.c
icecast/branches/kh/icecast/src/cfgfile.h
icecast/branches/kh/icecast/src/connection.c
icecast/branches/kh/icecast/src/format_flac.c
icecast/branches/kh/icecast/src/format_midi.c
icecast/branches/kh/icecast/src/format_mp3.c
icecast/branches/kh/icecast/src/format_mp3.h
icecast/branches/kh/icecast/src/format_ogg.c
icecast/branches/kh/icecast/src/format_ogg.h
icecast/branches/kh/icecast/src/format_speex.c
icecast/branches/kh/icecast/src/format_theora.c
icecast/branches/kh/icecast/src/format_vorbis.c
icecast/branches/kh/icecast/src/slave.c
icecast/branches/kh/icecast/src/source.c
icecast/branches/kh/icecast/src/xslt.c
Log:
various bits collected, so better commit -
. allow filtering of a theora logical stream before pushing onto queue.
. allow conversion of mp3 metadata from a specified charset to UTF8 for stats/log
. handle content type better from xsl pages.
. handle 403 return from auth url backend, also allow the message header to contain
a '403 message' for the listener.
. allow a port-based shoutcast-mount, allows multiple sc source clients and removes
the need to define a second port.
. xml parsing re-organised. lets see how this works out
Modified: icecast/branches/kh/icecast/src/admin.c
===================================================================
--- icecast/branches/kh/icecast/src/admin.c 2006-04-16 15:29:18 UTC (rev 11145)
+++ icecast/branches/kh/icecast/src/admin.c 2006-04-16 23:22:20 UTC (rev 11146)
@@ -394,27 +394,29 @@
if (strcmp (uri, "/admin.cgi") != 0 && strncmp("/admin/", uri, 7) != 0)
return -1;
+ mount = httpp_get_query_param(client->parser, "mount");
+
if (strcmp (uri, "/admin.cgi") == 0)
{
- ice_config_t *config;
char *pass = httpp_get_query_param (client->parser, "pass");
if (pass == NULL)
{
client_send_400 (client, "missing pass parameter");
return 0;
}
- config = config_get_config ();
- httpp_set_query_param (client->parser, "mount", config->shoutcast_mount);
+ if (mount)
+ {
+ ice_config_t *config = config_get_config ();
+ httpp_set_query_param (client->parser, "mount", config->shoutcast_mount);
+ config_release_config ();
+ }
httpp_setvar (client->parser, HTTPP_VAR_PROTOCOL, "ICY");
httpp_setvar (client->parser, HTTPP_VAR_ICYPASSWORD, pass);
- config_release_config ();
}
if (connection_check_admin_pass (client->parser))
client->authenticated = 1;
- mount = httpp_get_query_param(client->parser, "mount");
-
if (mount)
{
/* certain commands may not need auth */
Modified: icecast/branches/kh/icecast/src/auth.c
===================================================================
--- icecast/branches/kh/icecast/src/auth.c 2006-04-16 15:29:18 UTC (rev 11145)
+++ icecast/branches/kh/icecast/src/auth.c 2006-04-16 23:22:20 UTC (rev 11146)
@@ -370,6 +370,7 @@
source->active_clients = client;
source->listeners++;
stats_event_inc (NULL, "listener_connections");
+ stats_event_inc (source->mount, "listener_connections");
thread_mutex_unlock (&source->lock);
@@ -585,15 +586,16 @@
}
-auth_t *auth_get_authenticator (xmlNodePtr node)
+int auth_get_authenticator (xmlNodePtr node, void *x)
{
auth_t *auth = calloc (1, sizeof (auth_t));
config_options_t *options = NULL, **next_option = &options;
xmlNodePtr option;
if (auth == NULL)
- return NULL;
+ return -1;
+ *(auth_t**)x = auth;
option = node->xmlChildrenNode;
while (option)
{
@@ -633,7 +635,7 @@
xmlFree (opt->value);
free (opt);
}
- return auth;
+ return 0;
}
Modified: icecast/branches/kh/icecast/src/auth.h
===================================================================
--- icecast/branches/kh/icecast/src/auth.h 2006-04-16 15:29:18 UTC (rev 11145)
+++ icecast/branches/kh/icecast/src/auth.h 2006-04-16 23:22:20 UTC (rev 11146)
@@ -86,7 +86,7 @@
void auth_initialise (void);
void auth_shutdown (void);
-auth_t *auth_get_authenticator (xmlNodePtr node);
+int auth_get_authenticator (xmlNodePtr node, void *x);
void auth_release (auth_t *authenticator);
/* call to send a url request when source starts */
Modified: icecast/branches/kh/icecast/src/auth_url.c
===================================================================
--- icecast/branches/kh/icecast/src/auth_url.c 2006-04-16 15:29:18 UTC (rev 11145)
+++ icecast/branches/kh/icecast/src/auth_url.c 2006-04-16 23:22:20 UTC (rev 11146)
@@ -132,6 +132,18 @@
{
auth_t *auth = client->auth;
auth_url *url = auth->state;
+ int retcode = 0;
+
+ if (sscanf (ptr, "HTTP/%*u.%*u %3d %*c", &retcode) == 1)
+ {
+ if (retcode == 403)
+ {
+ char *p = strchr (ptr, ' ') + 1;
+ snprintf (url->errormsg, sizeof(url->errormsg), p);
+ p = strchr (url->errormsg, '\r');
+ if (p) *p='\0';
+ }
+ }
if (strncasecmp (ptr, url->auth_header, url->auth_header_len) == 0)
client->authenticated = 1;
if (strncasecmp (ptr, url->timelimit_header, url->timelimit_header_len) == 0)
@@ -332,6 +344,11 @@
/* we received a response, lets see what it is */
if (client->authenticated)
return AUTH_OK;
+ if (atoi (url->errormsg) == 403)
+ {
+ client_send_403 (client, url->errormsg+4);
+ auth_user->client = NULL;
+ }
INFO2 ("client auth (%s) failed with \"%s\"", url->addurl, url->errormsg);
return AUTH_FAILED;
}
Modified: icecast/branches/kh/icecast/src/cfgfile.c
===================================================================
--- icecast/branches/kh/icecast/src/cfgfile.c 2006-04-16 15:29:18 UTC (rev 11145)
+++ icecast/branches/kh/icecast/src/cfgfile.c 2006-04-16 23:22:20 UTC (rev 11146)
@@ -72,19 +72,7 @@
static ice_config_locks _locks;
static void _set_defaults(ice_config_t *c);
-static void _parse_root(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
-static void _parse_limits(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
-static void _parse_directory(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
-static void _parse_paths(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
-static void _parse_logging(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
-static void _parse_security(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
-static void _parse_authentication(xmlDocPtr doc, xmlNodePtr node,
- ice_config_t *c);
-static void _parse_relay(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
-static void _parse_mount(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
-static void _parse_listen_socket(xmlDocPtr doc, xmlNodePtr node,
- ice_config_t *c);
-static void _add_server(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
+static int _parse_root (xmlNodePtr node, ice_config_t *config);
static void create_locks(void) {
thread_mutex_create("relay lock", &_locks.relay_lock);
@@ -96,6 +84,85 @@
thread_rwlock_destroy(&_locks.config_lock);
}
+/*
+ */
+struct cfg_tag
+{
+ const char *name;
+ int (*retrieve) (xmlNodePtr node, void *x);
+ void *storage;
+};
+
+
+/* Process xml node for boolean value, it may be true, yes, or 1
+ */
+int config_get_bool (xmlNodePtr node, void *x)
+{
+ char *str = (char *)xmlNodeListGetString (node->doc, node->xmlChildrenNode, 1);
+ if (str == NULL)
+ return -1;
+ if (strcasecmp (str, "true") == 0)
+ *(int*)x = 1;
+ else
+ if (strcasecmp (str, "yes") == 0)
+ *(int*)x = 1;
+ else
+ *(int*)x = strtol (str, NULL, 0)==0 ? 0 : 1;
+ xmlFree (str);
+ return 0;
+}
+
+int config_get_str (xmlNodePtr node, void *x)
+{
+ xmlChar *str = xmlNodeListGetString (node->doc, node->xmlChildrenNode, 1);
+ xmlChar *p = *(xmlChar**)x;
+ if (str == NULL)
+ return -1;
+ if (p)
+ xmlFree (p);
+ *(char **)x = str;
+ return 0;
+}
+
+int config_get_int (xmlNodePtr node, void *x)
+{
+ xmlChar *str = xmlNodeListGetString (node->doc, node->xmlChildrenNode, 1);
+ if (str == NULL)
+ return -1;
+ *(int*)x = strtol ((char*)str, NULL, 0);
+ return 0;
+}
+
+
+int parse_xml_tags (xmlNodePtr parent, const struct cfg_tag *args)
+{
+ int ret = 0;
+ xmlNodePtr node = parent->xmlChildrenNode;
+
+ for (; node != NULL && ret == 0; node = node->next)
+ {
+ const struct cfg_tag *argp;
+
+ if (xmlIsBlankNode (node) || strcmp ((char*)node->name, "comment") == 0 ||
+ strcmp ((char*)node->name, "text") == 0)
+ continue;
+ argp = args;
+ while (argp->name)
+ {
+ if (strcmp ((const char*)node->name, argp->name) == 0)
+ {
+ ret = argp->retrieve (node, argp->storage);
+ break;
+ }
+ argp++;
+ }
+ if (argp->name == NULL)
+ WARN2 ("unknown element \"%s\" parsing \"%s\"\n", node->name, parent->name);
+ }
+ return ret;
+}
+
+
void config_initialize(void) {
create_locks();
}
@@ -293,7 +360,7 @@
configuration->config_filename = (char *)strdup(filename);
- _parse_root(doc, node->xmlChildrenNode, configuration);
+ _parse_root (node, configuration);
xmlFreeDoc(doc);
@@ -339,7 +406,7 @@
static void _set_defaults(ice_config_t *configuration)
{
- configuration->location = CONFIG_DEFAULT_LOCATION;
+ configuration->location = xmlCharStrdup (CONFIG_DEFAULT_LOCATION);
configuration->server_id = (char *)xmlCharStrdup (ICECAST_VERSION_STRING);
configuration->admin = CONFIG_DEFAULT_ADMIN;
configuration->client_limit = CONFIG_DEFAULT_CLIENT_LIMIT;
@@ -350,13 +417,13 @@
configuration->header_timeout = CONFIG_DEFAULT_HEADER_TIMEOUT;
configuration->source_timeout = CONFIG_DEFAULT_SOURCE_TIMEOUT;
configuration->source_password = CONFIG_DEFAULT_SOURCE_PASSWORD;
- configuration->shoutcast_mount = CONFIG_DEFAULT_SHOUTCAST_MOUNT;
+ configuration->shoutcast_mount = xmlCharStrdup (CONFIG_DEFAULT_SHOUTCAST_MOUNT);
configuration->ice_login = CONFIG_DEFAULT_ICE_LOGIN;
configuration->fileserve = CONFIG_DEFAULT_FILESERVE;
configuration->touch_interval = CONFIG_DEFAULT_TOUCH_FREQ;
configuration->on_demand = 0;
configuration->dir_list = NULL;
- configuration->hostname = CONFIG_DEFAULT_HOSTNAME;
+ configuration->hostname = xmlCharStrdup (CONFIG_DEFAULT_HOSTNAME);
configuration->port = 0;
configuration->listeners[0].port = 0;
configuration->listeners[0].bind_address = NULL;
@@ -367,13 +434,13 @@
configuration->master_username = (char*)xmlCharStrdup (CONFIG_DEFAULT_MASTER_USERNAME);
configuration->master_password = NULL;
configuration->master_relay_auth = 0;
- configuration->base_dir = CONFIG_DEFAULT_BASE_DIR;
- configuration->log_dir = CONFIG_DEFAULT_LOG_DIR;
- configuration->webroot_dir = CONFIG_DEFAULT_WEBROOT_DIR;
- configuration->adminroot_dir = CONFIG_DEFAULT_ADMINROOT_DIR;
- configuration->playlist_log = CONFIG_DEFAULT_PLAYLIST_LOG;
- configuration->access_log = CONFIG_DEFAULT_ACCESS_LOG;
- configuration->error_log = CONFIG_DEFAULT_ERROR_LOG;
+ configuration->base_dir = xmlCharStrdup (CONFIG_DEFAULT_BASE_DIR);
+ configuration->log_dir = xmlCharStrdup (CONFIG_DEFAULT_LOG_DIR);
+ configuration->webroot_dir = xmlCharStrdup (CONFIG_DEFAULT_WEBROOT_DIR);
+ configuration->adminroot_dir = xmlCharStrdup (CONFIG_DEFAULT_ADMINROOT_DIR);
+ configuration->playlist_log = xmlCharStrdup (CONFIG_DEFAULT_PLAYLIST_LOG);
+ configuration->access_log = xmlCharStrdup (CONFIG_DEFAULT_ACCESS_LOG);
+ configuration->error_log = xmlCharStrdup (CONFIG_DEFAULT_ERROR_LOG);
configuration->loglevel = CONFIG_DEFAULT_LOG_LEVEL;
configuration->chroot = CONFIG_DEFAULT_CHROOT;
configuration->chuid = CONFIG_DEFAULT_CHUID;
@@ -387,719 +454,374 @@
configuration->burst_size = CONFIG_DEFAULT_BURST_SIZE;
}
-static void _parse_root(xmlDocPtr doc, xmlNodePtr node,
- ice_config_t *configuration)
+
+static int _parse_alias (xmlNodePtr node, void *arg)
{
- char *tmp;
+ ice_config_t *config = arg;
+ aliases **cur, *alias = calloc (1, sizeof (aliases));
+ xmlChar *temp;
+
+ alias->source = xmlGetProp (node, "source");
+ alias->destination = xmlGetProp (node, "dest");
+ if (alias->source == NULL || alias->destination == NULL)
+ {
+ if (alias->source) xmlFree (alias->source);
+ if (alias->destination) xmlFree (alias->destination);
+ free (alias);
+ WARN0 ("incomplete alias definition");
+ return -1;
+ }
+ alias->bind_address = xmlGetProp (node, "bind-address");
+ temp = xmlGetProp(node, "port");
+ alias->port = -1;
+ if (temp)
+ {
+ alias->port = atoi ((char*)temp);
+ xmlFree (temp);
+ }
+ cur = &config->aliases;
+ while (*cur) cur = &((*cur)->next);
+ *cur = alias;
+ return 0;
+}
- do {
- if (node == NULL) break;
- if (xmlIsBlankNode(node)) continue;
+static int _parse_authentication (xmlNodePtr node, void *arg)
+{
+ ice_config_t *config = arg;
+ struct cfg_tag icecast_tags[] =
+ {
+ { "source-password", config_get_str, &config->source_password },
+ { "admin-user", config_get_str, &config->admin_username },
+ { "admin-password", config_get_str, &config->admin_password },
+ { "relay-user", config_get_str, &config->relay_username },
+ { "relay-password", config_get_str, &config->relay_password },
+ { NULL, NULL, NULL }
+ };
- if (xmlStrcmp(node->name, XMLSTR ("location")) == 0) {
- if (configuration->location && configuration->location != CONFIG_DEFAULT_LOCATION) xmlFree(configuration->location);
- configuration->location = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- } else if (xmlStrcmp(node->name, XMLSTR ("admin")) == 0) {
- if (configuration->admin && configuration->admin != CONFIG_DEFAULT_ADMIN) xmlFree(configuration->admin);
- configuration->admin = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- } else if (xmlStrcmp(node->name, XMLSTR ("server_id")) == 0) {
- xmlFree (configuration->server_id);
- configuration->server_id = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- } else if(xmlStrcmp(node->name, XMLSTR ("authentication")) == 0) {
- _parse_authentication(doc, node->xmlChildrenNode, configuration);
- } else if (xmlStrcmp(node->name, XMLSTR ("source-password")) == 0) {
- /* TODO: This is the backwards-compatibility location */
- char *mount, *pass;
- if ((mount = (char *)xmlGetProp(node, XMLSTR ("mount"))) != NULL) {
- pass = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- /* FIXME: This is a placeholder for per-mount passwords */
- }
- else {
- if (configuration->source_password && configuration->source_password != CONFIG_DEFAULT_SOURCE_PASSWORD) xmlFree(configuration->source_password);
- configuration->source_password = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- }
- } else if (xmlStrcmp(node->name, XMLSTR ("icelogin")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- configuration->ice_login = atoi(tmp);
- if (tmp) xmlFree(tmp);
- } else if (xmlStrcmp(node->name, XMLSTR ("fileserve")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- configuration->fileserve = atoi(tmp);
- if (tmp) xmlFree(tmp);
- } else if (xmlStrcmp(node->name, XMLSTR ("relays-on-demand")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- configuration->on_demand = atoi(tmp);
- if (tmp) xmlFree(tmp);
- } else if (xmlStrcmp(node->name, XMLSTR ("hostname")) == 0) {
- if (configuration->hostname && configuration->hostname != CONFIG_DEFAULT_HOSTNAME) xmlFree(configuration->hostname);
- configuration->hostname = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- } else if (xmlStrcmp(node->name, XMLSTR ("listen-socket")) == 0) {
- _parse_listen_socket(doc, node->xmlChildrenNode, configuration);
- } else if (xmlStrcmp(node->name, XMLSTR ("port")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- configuration->port = atoi(tmp);
- configuration->listeners[0].port = atoi(tmp);
- if (tmp) xmlFree(tmp);
- } else if (xmlStrcmp(node->name, XMLSTR ("bind-address")) == 0) {
- if (configuration->listeners[0].bind_address)
- xmlFree(configuration->listeners[0].bind_address);
- configuration->listeners[0].bind_address = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- } else if (xmlStrcmp(node->name, XMLSTR ("master-server")) == 0) {
- if (configuration->master_server) xmlFree(configuration->master_server);
- configuration->master_server = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- } else if (xmlStrcmp(node->name, XMLSTR ("master-username")) == 0) {
- if (configuration->master_username) xmlFree(configuration->master_username);
- configuration->master_username = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- } else if (xmlStrcmp(node->name, XMLSTR ("master-password")) == 0) {
- if (configuration->master_password) xmlFree(configuration->master_password);
- configuration->master_password = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- } else if (xmlStrcmp(node->name, XMLSTR ("master-server-port")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- configuration->master_server_port = atoi(tmp);
- xmlFree (tmp);
- } else if (xmlStrcmp(node->name, XMLSTR ("master-update-interval")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- configuration->master_update_interval = atoi(tmp);
- xmlFree (tmp);
- } else if (xmlStrcmp(node->name, XMLSTR ("master-relay-auth")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- configuration->master_relay_auth = atoi(tmp);
- xmlFree (tmp);
- } else if (xmlStrcmp(node->name, XMLSTR ("master-ssl-port")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- configuration->master_ssl_port = atoi(tmp);
- xmlFree (tmp);
- } else if (xmlStrcmp(node->name, XMLSTR ("master-redirect")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- configuration->master_redirect = atoi(tmp);
- xmlFree (tmp);
- } else if (xmlStrcmp(node->name, XMLSTR ("max-redirect-slaves")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- configuration->max_redirects = atoi(tmp);
- xmlFree (tmp);
- } else if (xmlStrcmp(node->name, XMLSTR ("shoutcast-mount")) == 0) {
- if (configuration->shoutcast_mount &&
- configuration->shoutcast_mount != CONFIG_DEFAULT_SHOUTCAST_MOUNT)
- xmlFree(configuration->shoutcast_mount);
- configuration->shoutcast_mount = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- } else if (xmlStrcmp(node->name, XMLSTR ("limits")) == 0) {
- _parse_limits(doc, node->xmlChildrenNode, configuration);
- } else if (xmlStrcmp(node->name, XMLSTR ("relay")) == 0) {
- _parse_relay(doc, node->xmlChildrenNode, configuration);
- } else if (xmlStrcmp(node->name, XMLSTR ("mount")) == 0) {
- _parse_mount(doc, node->xmlChildrenNode, configuration);
- } else if (xmlStrcmp(node->name, XMLSTR ("directory")) == 0) {
- _parse_directory(doc, node->xmlChildrenNode, configuration);
- } else if (xmlStrcmp(node->name, XMLSTR ("paths")) == 0) {
- _parse_paths(doc, node->xmlChildrenNode, configuration);
- } else if (xmlStrcmp(node->name, XMLSTR ("logging")) == 0) {
- _parse_logging(doc, node->xmlChildrenNode, configuration);
- } else if (xmlStrcmp(node->name, XMLSTR ("security")) == 0) {
- _parse_security(doc, node->xmlChildrenNode, configuration);
- }
- } while ((node = node->next));
- if (configuration->max_redirects == 0 && configuration->master_redirect)
- configuration->max_redirects = 1;
+ if (parse_xml_tags (node, icecast_tags))
+ return -1;
+ return 0;
}
-static void _parse_limits(xmlDocPtr doc, xmlNodePtr node,
- ice_config_t *configuration)
+static int _parse_chown (xmlNodePtr node, void *arg)
{
- char *tmp;
+ ice_config_t *config = arg;
+ struct cfg_tag icecast_tags[] =
+ {
+ { "user", config_get_str, &config->user },
+ { "group", config_get_str, &config->group },
+ { NULL, NULL, NULL }
+ };
- do {
- if (node == NULL) break;
- if (xmlIsBlankNode(node)) continue;
+ if (parse_xml_tags (node, icecast_tags))
+ return -1;
+ return 0;
+}
- if (xmlStrcmp(node->name, XMLSTR ("clients")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- configuration->client_limit = atoi(tmp);
- if (tmp) xmlFree(tmp);
- } else if (xmlStrcmp(node->name, XMLSTR ("sources")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- configuration->source_limit = atoi(tmp);
- if (tmp) xmlFree(tmp);
- } else if (xmlStrcmp(node->name, XMLSTR ("queue-size")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- configuration->queue_size_limit = atoi(tmp);
- if (tmp) xmlFree(tmp);
- } else if (xmlStrcmp(node->name, XMLSTR ("client-timeout")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- configuration->client_timeout = atoi(tmp);
- if (tmp) xmlFree(tmp);
- } else if (xmlStrcmp(node->name, XMLSTR ("header-timeout")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- configuration->header_timeout = atoi(tmp);
- if (configuration->header_timeout < 0 || configuration->header_timeout > 60)
- configuration->header_timeout = CONFIG_DEFAULT_HEADER_TIMEOUT;
- if (tmp) xmlFree(tmp);
- } else if (xmlStrcmp(node->name, XMLSTR("source-timeout")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- configuration->source_timeout = atoi(tmp);
- if (tmp) xmlFree(tmp);
- } else if (xmlStrcmp(node->name, XMLSTR("burst-on-connect")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- if (atoi(tmp) == 0)
- configuration->burst_size = 0;
- if (tmp) xmlFree(tmp);
- } else if (xmlStrcmp(node->name, XMLSTR("burst-size")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- configuration->burst_size = atoi(tmp);
- if (tmp) xmlFree(tmp);
- }
- } while ((node = node->next));
+static int _parse_security (xmlNodePtr node, void *arg)
+{
+ ice_config_t *config = arg;
+ struct cfg_tag icecast_tags[] =
+ {
+ { "chroot", config_get_bool, &config->chroot },
+ { "changeowner", _parse_chown, config },
+ { NULL, NULL, NULL }
+ };
+
+ if (parse_xml_tags (node, icecast_tags))
+ return -1;
+ return 0;
}
-static void _parse_mount(xmlDocPtr doc, xmlNodePtr node,
- ice_config_t *configuration)
+static int _parse_logging (xmlNodePtr node, void *arg)
{
- char *tmp;
+ ice_config_t *config = arg;
+ struct cfg_tag icecast_tags[] =
+ {
+ { "accesslog", config_get_str, &config->access_log },
+ { "accesslog_lines",
+ config_get_int, &config->access_log_lines },
+ { "errorlog", config_get_str, &config->error_log },
+ { "errorlog_lines", config_get_int, &config->error_log_lines },
+ { "playlistlog", config_get_str, &config->access_log },
+ { "playlistlog_lines",
+ config_get_int, &config->playlist_log_lines },
+ { "logsize", config_get_int, &config->logsize },
+ { "loglevel", config_get_int, &config->loglevel },
+ { "logarchive", config_get_bool, &config->logarchive },
+ { NULL, NULL, NULL }
+ };
+
+ if (parse_xml_tags (node, icecast_tags))
+ return -1;
+ return 0;
+}
+
+static int _parse_paths (xmlNodePtr node, void *arg)
+{
+ ice_config_t *config = arg;
+ struct cfg_tag icecast_tags[] =
+ {
+ { "basedir", config_get_str, &config->base_dir },
+ { "logdir", config_get_str, &config->log_dir },
+ { "pidfile", config_get_str, &config->pidfile },
+ { "ssl_certificate",
+ config_get_str, &config->cert_file },
+ { "webroot", config_get_str, &config->webroot_dir },
+ { "adminroot", config_get_str, &config->adminroot_dir },
+ { "alias", _parse_alias, config },
+ { NULL, NULL, NULL }
+ };
+
+ if (parse_xml_tags (node, icecast_tags))
+ return -1;
+ return 0;
+}
+
+static int _parse_directory (xmlNodePtr node, void *arg)
+{
+ ice_config_t *config = arg;
+
+ struct cfg_tag icecast_tags[] =
+ {
+ { "yp-url", config_get_str, &config->yp_url [config->num_yp_directories]},
+ { "yp-url-timeout", config_get_int, &config->yp_url_timeout [config->num_yp_directories]},
+ { "touch-interval", config_get_int, &config->yp_touch_interval [config->num_yp_directories]},
+ { NULL, NULL, NULL }
+ };
+
+ if (config->num_yp_directories >= MAX_YP_DIRECTORIES)
+ {
+ ERROR0("Maximum number of yp directories exceeded!");
+ return -1;
+ }
+
+ if (parse_xml_tags (node, icecast_tags))
+ return -1;
+ config->num_yp_directories++;
+ return 0;
+}
+
+
+static int _parse_mount (xmlNodePtr node, void *arg)
+{
+ ice_config_t *config = arg;
mount_proxy *mount = calloc(1, sizeof(mount_proxy));
- mount_proxy *current = configuration->mounts;
- mount_proxy *last=NULL;
-
+
+ struct cfg_tag icecast_tags[] =
+ {
+ { "mount-name", config_get_str, &mount->mountname },
+ { "source-timeout", config_get_int, &mount->source_timeout },
+ { "queue-size", config_get_int, &mount->queue_size_limit },
+ { "burst-size", config_get_int, &mount->burst_size},
+ { "username", config_get_str, &mount->username },
+ { "password", config_get_str, &mount->password },
+ { "dump-file", config_get_str, &mount->dumpfile },
+ { "intro", config_get_str, &mount->intro_filename },
+ { "fallback-mount", config_get_str, &mount->fallback_mount },
+ { "fallback-override",
+ config_get_bool, &mount->fallback_override },
+ { "fallback-when-full",
+ config_get_bool, &mount->fallback_when_full },
+ { "max-listeners", config_get_int, &mount->max_listeners },
+ { "filter-theora", config_get_bool, &mount->filter_theora },
+ { "mp3-metadata-charset",
+ config_get_str, &mount->mp3_charset },
+ { "mp3-metadata-interval",
+ config_get_int, &mount->mp3_meta_interval },
+ { "no-mount", config_get_bool, &mount->no_mount },
+ { "hidden", config_get_bool, &mount->hidden },
+ { "authentication", auth_get_authenticator,
+ &mount->auth },
+ { "on-connect", config_get_str, &mount->on_connect },
+ { "on-disconnect", config_get_str, &mount->on_disconnect },
+ { "max-listener-duration",
+ config_get_int, &mount->max_listener_duration },
+ /* YP settings */
+ { "cluster-password",
+ config_get_str, &mount->cluster_password },
+ { "stream-name", config_get_str, &mount->stream_name },
+ { "stream-description",
+ config_get_str, &mount->stream_description },
+ { "stream-url", config_get_str, &mount->stream_url },
+ { "genre", config_get_str, &mount->stream_genre },
+ { "bitrate", config_get_str, &mount->bitrate },
+ { "public", config_get_bool, &mount->yp_public },
+ { "type", config_get_str, &mount->type },
+ { "subtype", config_get_str, &mount->subtype },
+ { NULL, NULL, NULL },
+ };
+
/* default <mount> settings */
mount->max_listeners = -1;
mount->burst_size = -1;
mount->mp3_meta_interval = -1;
mount->yp_public = -1;
- mount->next = NULL;
- do {
- if (node == NULL) break;
- if (xmlIsBlankNode(node)) continue;
-
- if (xmlStrcmp(node->name, XMLSTR ("mount-name")) == 0) {
- mount->mountname = (char *)xmlNodeListGetString(
- doc, node->xmlChildrenNode, 1);
- }
- else if (xmlStrcmp(node->name, XMLSTR ("username")) == 0) {
- mount->username = (char *)xmlNodeListGetString(
- doc, node->xmlChildrenNode, 1);
- }
- else if (xmlStrcmp(node->name, XMLSTR ("password")) == 0) {
- mount->password = (char *)xmlNodeListGetString(
- doc, node->xmlChildrenNode, 1);
- }
- else if (xmlStrcmp(node->name, XMLSTR ("dump-file")) == 0) {
- mount->dumpfile = (char *)xmlNodeListGetString(
- doc, node->xmlChildrenNode, 1);
- }
- else if (xmlStrcmp(node->name, XMLSTR ("intro")) == 0) {
- mount->intro_filename = (char *)xmlNodeListGetString(
- doc, node->xmlChildrenNode, 1);
- }
- else if (xmlStrcmp(node->name, XMLSTR ("fallback-mount")) == 0) {
- mount->fallback_mount = (char *)xmlNodeListGetString(
- doc, node->xmlChildrenNode, 1);
- }
- else if (xmlStrcmp(node->name, XMLSTR ("fallback-when-full")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- mount->fallback_when_full = atoi(tmp);
- if(tmp) xmlFree(tmp);
- }
- else if (xmlStrcmp(node->name, XMLSTR ("max-listeners")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- mount->max_listeners = atoi(tmp);
- if(tmp) xmlFree(tmp);
- }
- else if (xmlStrcmp(node->name, XMLSTR ("mp3-metadata-interval")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- mount->mp3_meta_interval = atoi(tmp);
- if(tmp) xmlFree(tmp);
- }
- else if (xmlStrcmp(node->name, XMLSTR ("fallback-override")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- mount->fallback_override = atoi(tmp);
- if(tmp) xmlFree(tmp);
- }
- else if (xmlStrcmp(node->name, XMLSTR ("no-mount")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- mount->no_mount = atoi(tmp);
- if(tmp) xmlFree(tmp);
- }
- else if (xmlStrcmp(node->name, XMLSTR ("no-yp")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- mount->yp_public = atoi(tmp)==0 ? -1 : 0;
- if(tmp) xmlFree(tmp);
- }
- else if (xmlStrcmp(node->name, XMLSTR ("hidden")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- mount->hidden = atoi(tmp);
- if(tmp) xmlFree(tmp);
- }
- else if (xmlStrcmp(node->name, XMLSTR ("authentication")) == 0) {
- mount->auth = auth_get_authenticator (node);
- }
- else if (xmlStrcmp(node->name, XMLSTR ("on-connect")) == 0) {
- mount->on_connect = (char *)xmlNodeListGetString(
- doc, node->xmlChildrenNode, 1);
- }
- else if (xmlStrcmp(node->name, XMLSTR ("on-disconnect")) == 0) {
- mount->on_disconnect = (char *)xmlNodeListGetString(
- doc, node->xmlChildrenNode, 1);
- }
- else if (xmlStrcmp(node->name, XMLSTR ("max-listener-duration")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- mount->max_listener_duration = atoi(tmp);
- if(tmp) xmlFree(tmp);
- }
- else if (xmlStrcmp(node->name, XMLSTR ("queue-size")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- mount->queue_size_limit = atoi (tmp);
- if(tmp) xmlFree(tmp);
- }
- else if (xmlStrcmp(node->name, XMLSTR ("source-timeout")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- if (tmp)
- {
- mount->source_timeout = atoi (tmp);
- xmlFree(tmp);
- }
- } else if (xmlStrcmp(node->name, XMLSTR ("burst-size")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- mount->burst_size = atoi(tmp);
- if (tmp) xmlFree(tmp);
- } else if (xmlStrcmp(node->name, XMLSTR ("cluster-password")) == 0) {
- mount->cluster_password = (char *)xmlNodeListGetString(
- doc, node->xmlChildrenNode, 1);
- } else if (xmlStrcmp(node->name, XMLSTR ("stream-name")) == 0) {
- mount->stream_name = (char *)xmlNodeListGetString(
- doc, node->xmlChildrenNode, 1);
- } else if (xmlStrcmp(node->name, XMLSTR ("stream-description")) == 0) {
- mount->stream_description = (char *)xmlNodeListGetString(
- doc, node->xmlChildrenNode, 1);
- } else if (xmlStrcmp(node->name, XMLSTR ("stream-url")) == 0) {
- mount->stream_url = (char *)xmlNodeListGetString(
- doc, node->xmlChildrenNode, 1);
- } else if (xmlStrcmp(node->name, XMLSTR ("genre")) == 0) {
- mount->stream_genre = (char *)xmlNodeListGetString(
- doc, node->xmlChildrenNode, 1);
- } else if (xmlStrcmp(node->name, XMLSTR ("bitrate")) == 0) {
- mount->bitrate = (char *)xmlNodeListGetString(
- doc, node->xmlChildrenNode, 1);
- } else if (xmlStrcmp(node->name, XMLSTR ("public")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- mount->yp_public = atoi (tmp);
- if(tmp) xmlFree(tmp);
- } else if (xmlStrcmp(node->name, XMLSTR ("type")) == 0) {
- mount->type = (char *)xmlNodeListGetString(
- doc, node->xmlChildrenNode, 1);
- } else if (xmlStrcmp(node->name, XMLSTR ("subtype")) == 0) {
- mount->subtype = (char *)xmlNodeListGetString(
- doc, node->xmlChildrenNode, 1);
- }
- } while ((node = node->next));
-
+ if (parse_xml_tags (node, icecast_tags))
+ return -1;
+
if (mount->mountname == NULL)
{
config_clear_mount (mount);
- return;
+ return -1;
}
- while(current) {
- last = current;
- current = current->next;
- }
- if(last)
- last->next = mount;
- else
- configuration->mounts = mount;
+ mount->next = config->mounts;
+ config->mounts = mount;
+
+ return 0;
}
-static void _parse_relay(xmlDocPtr doc, xmlNodePtr node,
- ice_config_t *configuration)
+static int _parse_relay (xmlNodePtr node, void *arg)
{
- char *tmp;
+ ice_config_t *config = arg;
relay_server *relay = calloc(1, sizeof(relay_server));
- relay->next = NULL;
+ struct cfg_tag icecast_tags[] =
+ {
+ { "server", config_get_str, &relay->server },
+ { "port", config_get_int, &relay->port },
+ { "mount", config_get_str, &relay->mount },
+ { "local-mount", config_get_str, &relay->localmount },
+ { "on-demand", config_get_bool, &relay->on_demand },
+ { "relay-shoutcast-metadata",
+ config_get_bool, &relay->mp3metadata },
+ { "username", config_get_str, &relay->username },
+ { "password", config_get_str, &relay->password },
+ { "enable", config_get_bool, &relay->enable },
+ { NULL, NULL, NULL },
+ };
+
relay->mp3metadata = 1;
relay->enable = 1;
- relay->on_demand = configuration->on_demand;
- relay->port = 8000;
+ relay->on_demand = config->on_demand;
+ relay->port = config->port;
- do {
- if (node == NULL) break;
- if (xmlIsBlankNode(node)) continue;
+ if (parse_xml_tags (node, icecast_tags))
+ return -1;
- if (xmlStrcmp(node->name, XMLSTR ("server")) == 0) {
- relay->server = (char *)xmlNodeListGetString(
- doc, node->xmlChildrenNode, 1);
- }
- else if (xmlStrcmp(node->name, XMLSTR ("port")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- relay->port = atoi(tmp);
- if(tmp) xmlFree(tmp);
- }
- else if (xmlStrcmp(node->name, XMLSTR ("mount")) == 0) {
- relay->mount = (char *)xmlNodeListGetString(
- doc, node->xmlChildrenNode, 1);
- }
- else if (xmlStrcmp(node->name, XMLSTR ("local-mount")) == 0) {
- relay->localmount = (char *)xmlNodeListGetString(
- doc, node->xmlChildrenNode, 1);
- }
- else if (xmlStrcmp(node->name, XMLSTR ("relay-shoutcast-metadata")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- relay->mp3metadata = atoi(tmp);
- if(tmp) xmlFree(tmp);
- }
- else if (xmlStrcmp(node->name, XMLSTR ("username")) == 0) {
- relay->username = (char *)xmlNodeListGetString(doc,
- node->xmlChildrenNode, 1);
- }
- else if (xmlStrcmp(node->name, XMLSTR ("password")) == 0) {
- relay->password = (char *)xmlNodeListGetString(doc,
- node->xmlChildrenNode, 1);
- }
- else if (xmlStrcmp(node->name, XMLSTR ("on-demand")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- relay->on_demand = atoi(tmp);
- if (tmp) xmlFree(tmp);
- }
- else if (xmlStrcmp(node->name, XMLSTR ("enable")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- relay->enable = atoi(tmp);
- if (tmp) xmlFree(tmp);
- }
- } while ((node = node->next));
-
+ /* check for undefined entries */
if (relay->server == NULL)
- {
- config_clear_relay (relay);
- return;
- }
+ relay->server = (char *)xmlCharStrdup ("127.0.0.1");
if (relay->mount == NULL)
relay->mount = (char*)xmlCharStrdup ("/");
-
if (relay->localmount == NULL)
relay->localmount = (char*)xmlCharStrdup (relay->mount);
- relay->next = configuration->relay;
- configuration->relay = relay;
-}
+ relay->next = config->relay;
+ config->relay = relay;
-static void _parse_listen_socket(xmlDocPtr doc, xmlNodePtr node,
- ice_config_t *configuration)
-{
- listener_t *listener = NULL;
- int i;
- char *tmp;
-
- for(i=0; i < MAX_LISTEN_SOCKETS; i++) {
- if(configuration->listeners[i].port <= 0) {
- listener = &(configuration->listeners[i]);
- break;
- }
- }
-
- if (listener == NULL)
- return;
- do {
- if (node == NULL) break;
- if (xmlIsBlankNode(node)) continue;
-
- if (xmlStrcmp(node->name, XMLSTR ("port")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- if(configuration->port == 0)
- configuration->port = atoi(tmp);
- listener->port = atoi(tmp);
- if(tmp) xmlFree(tmp);
- }
- else if (xmlStrcmp(node->name, XMLSTR ("shoutcast-compat")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- listener->shoutcast_compat = atoi(tmp);
- if(tmp) xmlFree(tmp);
- }
- else if (xmlStrcmp(node->name, XMLSTR ("ssl")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- listener->ssl = atoi(tmp);
- if(tmp) xmlFree(tmp);
- }
- else if (xmlStrcmp(node->name, XMLSTR ("bind-address")) == 0) {
- listener->bind_address = (char *)xmlNodeListGetString(doc,
- node->xmlChildrenNode, 1);
- }
- } while ((node = node->next));
+ return 0;
}
-static void _parse_authentication(xmlDocPtr doc, xmlNodePtr node,
- ice_config_t *configuration)
+static int _parse_limits (xmlNodePtr node, void *arg)
{
- do {
- if (node == NULL) break;
- if (xmlIsBlankNode(node)) continue;
+ ice_config_t *config = arg;
- if (xmlStrcmp(node->name, XMLSTR ("source-password")) == 0) {
- char *mount, *pass;
- if ((mount = (char *)xmlGetProp(node, XMLSTR ("mount"))) != NULL) {
- pass = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- /* FIXME: This is a placeholder for per-mount passwords */
- }
- else {
- if (configuration->source_password &&
- configuration->source_password !=
- CONFIG_DEFAULT_SOURCE_PASSWORD)
- xmlFree(configuration->source_password);
- configuration->source_password =
- (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- }
- } else if (xmlStrcmp(node->name, XMLSTR ("admin-password")) == 0) {
- if(configuration->admin_password)
- xmlFree(configuration->admin_password);
- configuration->admin_password =
- (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- } else if (xmlStrcmp(node->name, XMLSTR ("admin-user")) == 0) {
- if(configuration->admin_username)
- xmlFree(configuration->admin_username);
- configuration->admin_username =
- (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- } else if (xmlStrcmp(node->name, XMLSTR ("relay-password")) == 0) {
- if(configuration->relay_password)
- xmlFree(configuration->relay_password);
- configuration->relay_password =
- (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- } else if (xmlStrcmp(node->name, XMLSTR ("relay-user")) == 0) {
- if(configuration->relay_username)
- xmlFree(configuration->relay_username);
- configuration->relay_username =
- (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- }
- } while ((node = node->next));
+ struct cfg_tag icecast_tags[] =
+ {
+ { "clients", config_get_int, &config->client_limit },
+ { "sources", config_get_int, &config->source_limit },
+ { "queue-size", config_get_int, &config->queue_size_limit },
+ { "burst-size", config_get_int, &config->burst_size },
+ { "client-timeout", config_get_int, &config->client_timeout },
+ { "header-timeout", config_get_int, &config->header_timeout },
+ { "source-timeout", config_get_int, &config->source_timeout },
+ { NULL, NULL, NULL },
+ };
+ if (parse_xml_tags (node, icecast_tags))
+ return -1;
+ return 0;
}
-static void _parse_directory(xmlDocPtr doc, xmlNodePtr node,
- ice_config_t *configuration)
-{
- char *tmp;
- if (configuration->num_yp_directories >= MAX_YP_DIRECTORIES) {
- ERROR0("Maximum number of yp directories exceeded!");
- return;
- }
- do {
- if (node == NULL) break;
- if (xmlIsBlankNode(node)) continue;
-
- if (xmlStrcmp(node->name, XMLSTR ("yp-url")) == 0) {
- if (configuration->yp_url[configuration->num_yp_directories])
- xmlFree(configuration->yp_url[configuration->num_yp_directories]);
- configuration->yp_url[configuration->num_yp_directories] =
- (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- } else if (xmlStrcmp(node->name, XMLSTR ("yp-url-timeout")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- configuration->yp_url_timeout[configuration->num_yp_directories] =
- atoi(tmp);
- if (tmp) xmlFree(tmp);
- } else if (xmlStrcmp(node->name, XMLSTR ("server")) == 0) {
- _add_server(doc, node->xmlChildrenNode, configuration);
- } else if (xmlStrcmp(node->name, XMLSTR ("touch-interval")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- configuration->yp_touch_interval[configuration->num_yp_directories] =
- atoi(tmp);
- if (tmp) xmlFree(tmp);
- }
- } while ((node = node->next));
- configuration->num_yp_directories++;
-}
-
-static void _parse_paths(xmlDocPtr doc, xmlNodePtr node,
- ice_config_t *configuration)
+static int _parse_listen_sock (xmlNodePtr node, void *arg)
{
- char *temp;
- aliases *alias, *current, *last;
+ ice_config_t *config = arg;
+ listener_t *listener = &config->listeners[0];
+ int i;
- do {
- if (node == NULL) break;
- if (xmlIsBlankNode(node)) continue;
-
- if (xmlStrcmp(node->name, XMLSTR ("basedir")) == 0) {
- if (configuration->base_dir && configuration->base_dir != CONFIG_DEFAULT_BASE_DIR) xmlFree(configuration->base_dir);
- configuration->base_dir = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- } else if (xmlStrcmp(node->name, XMLSTR ("logdir")) == 0) {
- if (configuration->log_dir && configuration->log_dir != CONFIG_DEFAULT_LOG_DIR) xmlFree(configuration->log_dir);
- configuration->log_dir = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- } else if (xmlStrcmp(node->name, XMLSTR ("pidfile")) == 0) {
- if (configuration->pidfile) xmlFree(configuration->pidfile);
- configuration->pidfile = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- } else if (xmlStrcmp(node->name, XMLSTR ("ssl_certificate")) == 0) {
- if (configuration->cert_file) xmlFree(configuration->cert_file);
- configuration->cert_file = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- } else if (xmlStrcmp(node->name, XMLSTR ("webroot")) == 0) {
- if (configuration->webroot_dir && configuration->webroot_dir != CONFIG_DEFAULT_WEBROOT_DIR) xmlFree(configuration->webroot_dir);
- configuration->webroot_dir = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- if(configuration->webroot_dir[strlen(configuration->webroot_dir)-1] == '/')
- configuration->webroot_dir[strlen(configuration->webroot_dir)-1] = 0;
- } else if (xmlStrcmp(node->name, XMLSTR ("adminroot")) == 0) {
- if (configuration->adminroot_dir && configuration->adminroot_dir != CONFIG_DEFAULT_ADMINROOT_DIR)
- xmlFree(configuration->adminroot_dir);
- configuration->adminroot_dir = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- if(configuration->adminroot_dir[strlen(configuration->adminroot_dir)-1] == '/')
- configuration->adminroot_dir[strlen(configuration->adminroot_dir)-1] = 0;
- } else if (xmlStrcmp(node->name, XMLSTR ("alias")) == 0) {
- alias = malloc(sizeof(aliases));
- alias->next = NULL;
- alias->source = (char*)xmlGetProp(node, XMLSTR ("source"));
- if(alias->source == NULL) {
- free(alias);
- continue;
+ for (i=0; i < MAX_LISTEN_SOCKETS; i++)
+ {
+ if (listener->port <= 0)
+ {
+ struct cfg_tag icecast_tags[] =
+ {
+ { "port", config_get_int, &listener->port },
+ { "shoutcast-compat", config_get_bool, &listener->shoutcast_compat },
+ { "bind-address", config_get_str, &listener->bind_address },
+ { "shoutcast-mount", config_get_str, &listener->shoutcast_mount },
+ { NULL, NULL, NULL },
+ };
+ if (parse_xml_tags (node, icecast_tags))
+ break;
+ if (listener->shoutcast_mount)
+ {
+ listener_t *sc_port = listener+1;
+ if (i+1 < MAX_LISTEN_SOCKETS && sc_port->port <= 0)
+ {
+ sc_port->port = listener->port+1;
+ sc_port->shoutcast_compat = 1;
+ sc_port->bind_address = xmlStrdup (listener->bind_address);
+ sc_port->shoutcast_mount= xmlStrdup (listener->shoutcast_mount);
+ }
}
- alias->destination = (char*)xmlGetProp(node, XMLSTR ("dest"));
- if(alias->destination == NULL) {
- xmlFree(alias->source);
- free(alias);
- continue;
- }
- temp = (char *)xmlGetProp(node, XMLSTR("port"));
- if(temp != NULL) {
- alias->port = atoi(temp);
- xmlFree(temp);
- }
- else
- alias->port = -1;
- alias->bind_address = (char*)xmlGetProp(node, XMLSTR("bind-address"));
- current = configuration->aliases;
- last = NULL;
- while(current) {
- last = current;
- current = current->next;
- }
- if(last)
- last->next = alias;
- else
- configuration->aliases = alias;
+ if (config->port == 0)
+ config->port = listener->port;
+ return 0;
}
- } while ((node = node->next));
+ listener++;
+ }
+ return -1;
}
-static void _parse_logging(xmlDocPtr doc, xmlNodePtr node,
- ice_config_t *configuration)
-{
- configuration->access_log_lines = 100;
- configuration->error_log_lines = 100;
- configuration->playlist_log_lines = 10;
- do {
- if (node == NULL) break;
- if (xmlIsBlankNode(node)) continue;
- if (xmlStrcmp(node->name, XMLSTR ("accesslog")) == 0) {
- if (configuration->access_log && configuration->access_log != CONFIG_DEFAULT_ACCESS_LOG) xmlFree(configuration->access_log);
- configuration->access_log = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- } else if (xmlStrcmp(node->name, XMLSTR ("accesslog_lines")) == 0) {
- char *tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- configuration->access_log_lines = atoi(tmp);
- if (tmp) xmlFree(tmp);
- } else if (xmlStrcmp(node->name, XMLSTR ("errorlog")) == 0) {
- if (configuration->error_log && configuration->error_log != CONFIG_DEFAULT_ERROR_LOG) xmlFree(configuration->error_log);
- configuration->error_log = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- } else if (xmlStrcmp(node->name, XMLSTR ("errorlog_lines")) == 0) {
- char *tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- configuration->error_log_lines = atoi(tmp);
- if (tmp) xmlFree(tmp);
- } else if (xmlStrcmp(node->name, XMLSTR ("playlistlog")) == 0) {
- if (configuration->playlist_log && configuration->playlist_log != CONFIG_DEFAULT_PLAYLIST_LOG) xmlFree(configuration->playlist_log);
- configuration->playlist_log = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- } else if (xmlStrcmp(node->name, XMLSTR ("playlistlog_lines")) == 0) {
- char *tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- configuration->playlist_log_lines = atoi(tmp);
- if (tmp) xmlFree(tmp);
- } else if (xmlStrcmp(node->name, XMLSTR ("logsize")) == 0) {
- char *tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- configuration->logsize = atoi(tmp);
- if (tmp) xmlFree(tmp);
- } else if (xmlStrcmp(node->name, XMLSTR ("loglevel")) == 0) {
- char *tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- configuration->loglevel = atoi(tmp);
- if (tmp) xmlFree(tmp);
- } else if (xmlStrcmp(node->name, XMLSTR ("logarchive")) == 0) {
- char *tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- configuration->logarchive = atoi(tmp);
- if (tmp) xmlFree(tmp);
- }
- } while ((node = node->next));
-}
-
-static void _parse_security(xmlDocPtr doc, xmlNodePtr node,
- ice_config_t *configuration)
+static int _parse_root (xmlNodePtr node, ice_config_t *config)
{
- char *tmp;
- xmlNodePtr oldnode;
+ struct cfg_tag icecast_tags[] =
+ {
+ { "location", config_get_str, &config->location },
+ { "admin", config_get_str, &config->admin },
+ { "server_id", config_get_str, &config->server_id },
+ { "source-password", config_get_str, &config->source_password },
+ { "hostname", config_get_str, &config->hostname },
+ { "port", config_get_int, &config->port },
+ { "fileserve", config_get_bool, &config->fileserve },
+ { "relays-on-demand", config_get_bool, &config->on_demand },
+ { "master-server", config_get_str, &config->master_server },
+ { "master-username", config_get_str, &config->master_username },
+ { "master-password", config_get_str, &config->master_password },
+ { "master-server-port", config_get_int, &config->master_server_port },
+ { "master-update-interval",
+ config_get_int, &config->master_update_interval },
+ { "master-relay-auth", config_get_bool, &config->master_relay_auth },
+ { "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 },
+ { "shoutcast-mount", config_get_str, &config->shoutcast_mount },
+ { "listen-socket", _parse_listen_sock, config },
+ { "limits", _parse_limits, config },
+ { "relay", _parse_relay, config },
+ { "mount", _parse_mount, config },
+ { "directory", _parse_directory, config },
+ { "paths", _parse_paths, config },
+ { "logging", _parse_logging, config },
+ { "security", _parse_security, config },
+ { "authentication", _parse_authentication, config},
+ { NULL, NULL, NULL }
+ };
+ if (parse_xml_tags (node, icecast_tags))
+ return -1;
- do {
- if (node == NULL) break;
- if (xmlIsBlankNode(node)) continue;
-
- if (xmlStrcmp(node->name, XMLSTR ("chroot")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- configuration->chroot = atoi(tmp);
- if (tmp) xmlFree(tmp);
- } else if (xmlStrcmp(node->name, XMLSTR ("changeowner")) == 0) {
- configuration->chuid = 1;
- oldnode = node;
- node = node->xmlChildrenNode;
- do {
- if(node == NULL) break;
- if(xmlIsBlankNode(node)) continue;
- if(xmlStrcmp(node->name, XMLSTR ("user")) == 0) {
- if(configuration->user) xmlFree(configuration->user);
- configuration->user = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- } else if(xmlStrcmp(node->name, XMLSTR ("group")) == 0) {
- if(configuration->group) xmlFree(configuration->group);
- configuration->group = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- }
- } while((node = node->next));
- node = oldnode;
- }
- } while ((node = node->next));
+ if (config->max_redirects == 0 && config->master_redirect)
+ config->max_redirects = 1;
+ return 0;
}
-static void _add_server(xmlDocPtr doc, xmlNodePtr node,
- ice_config_t *configuration)
-{
- ice_config_dir_t *dirnode, *server;
- int addnode;
- char *tmp;
- server = (ice_config_dir_t *)malloc(sizeof(ice_config_dir_t));
- server->touch_interval = configuration->touch_interval;
- server->host = NULL;
- addnode = 0;
-
- do {
- if (node == NULL) break;
- if (xmlIsBlankNode(node)) continue;
-
- if (xmlStrcmp(node->name, XMLSTR ("host")) == 0) {
- server->host = (char *)xmlNodeListGetString(doc,
- node->xmlChildrenNode, 1);
- addnode = 1;
- } else if (xmlStrcmp(node->name, XMLSTR ("touch-interval")) == 0) {
- tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- server->touch_interval = atoi(tmp);
- if (tmp) xmlFree(tmp);
- }
- server->next = NULL;
- } while ((node = node->next));
-
- if (addnode) {
- dirnode = configuration->dir_list;
- if (dirnode == NULL) {
- configuration->dir_list = server;
- } else {
- while (dirnode->next) dirnode = dirnode->next;
-
- dirnode->next = server;
- }
-
- server = NULL;
- addnode = 0;
- }
-
-}
-
-
/* return the mount details that match the supplied mountpoint */
mount_proxy *config_find_mount (ice_config_t *config, const char *mount)
{
Modified: icecast/branches/kh/icecast/src/cfgfile.h
===================================================================
--- icecast/branches/kh/icecast/src/cfgfile.h 2006-04-16 15:29:18 UTC (rev 11145)
+++ icecast/branches/kh/icecast/src/cfgfile.h 2006-04-16 23:22:20 UTC (rev 11146)
@@ -66,7 +66,9 @@
unsigned int queue_size_limit;
int hidden; /* Do we list this on the xsl pages */
unsigned int source_timeout; /* source timeout in seconds */
+ char *mp3_charset; /* character set for metadata */
int mp3_meta_interval; /* outgoing per-stream metadata interval */
+ int filter_theora; /* prevent theora pages getting queued */
char *auth_type; /* Authentication type */
struct auth_tag *auth;
@@ -100,6 +102,7 @@
int port;
char *bind_address;
int shoutcast_compat;
+ char *shoutcast_mount;
int ssl;
} listener_t;
Modified: icecast/branches/kh/icecast/src/connection.c
===================================================================
--- icecast/branches/kh/icecast/src/connection.c 2006-04-16 15:29:18 UTC (rev 11145)
+++ icecast/branches/kh/icecast/src/connection.c 2006-04-16 23:22:20 UTC (rev 11146)
@@ -82,6 +82,7 @@
int offset;
int stream_offset;
int shoutcast;
+ char *shoutcast_mount;
struct client_queue_tag *next;
} client_queue_t;
@@ -604,6 +605,8 @@
node->shoutcast = 1;
if (config->listeners[i].ssl && ssl_ok)
connection_uses_ssl (client->con);
+ if (config->listeners[i].shoutcast_mount)
+ node->shoutcast_mount = strdup (config->listeners[i].shoutcast_mount);
}
}
config_release_config();
@@ -1059,11 +1062,18 @@
char *shoutcast_mount;
client_t *client = node->client;
+ if (node->shoutcast_mount)
+ shoutcast_mount = node->shoutcast_mount;
+ else
+ shoutcast_mount = config->shoutcast_mount;
+
if (node->shoutcast == 1)
{
char *source_password, *ptr, *headers;
- mount_proxy *mountinfo = config_find_mount (config, config->shoutcast_mount);
+ mount_proxy *mountinfo;
+ mountinfo = config_find_mount (config, shoutcast_mount);
+
if (mountinfo && mountinfo->password)
source_password = strdup (mountinfo->password);
else
@@ -1091,6 +1101,7 @@
{
client_destroy (client);
free (source_password);
+ free (node->shoutcast_mount);
free (node);
return;
}
@@ -1113,10 +1124,12 @@
else
INFO1 ("password does not match \"%s\"", client->refbuf->data);
client_destroy (client);
+ free (node->shoutcast_mount);
free (node);
return;
}
- shoutcast_mount = strdup (config->shoutcast_mount);
+ /* actually make a copy as we are dropping the config lock */
+ shoutcast_mount = strdup (shoutcast_mount);
config_release_config();
/* Here we create a valid HTTP request based of the information
that was passed in via the non-HTTP style protocol above. This
@@ -1148,6 +1161,7 @@
}
free (http_compliant);
free (shoutcast_mount);
+ free (node->shoutcast_mount);
free (node);
return;
}
@@ -1192,6 +1206,14 @@
client->refbuf->len = node->offset - node->stream_offset;
memmove (ptr, ptr + node->stream_offset, client->refbuf->len);
}
+
+ rawuri = httpp_getvar (parser, HTTPP_VAR_URI);
+
+ /* assign a port-based shoutcast mountpoint if required */
+ if (node->shoutcast_mount && strcmp (rawuri, "/admin.cgi") == 0)
+ httpp_set_query_param (client->parser, "mount", node->shoutcast_mount);
+
+ free (node->shoutcast_mount);
free (node);
if (strcmp("ICE", httpp_getvar(parser, HTTPP_VAR_PROTOCOL)) &&
@@ -1201,7 +1223,6 @@
continue;
}
- rawuri = httpp_getvar(parser, HTTPP_VAR_URI);
uri = util_normalise_uri(rawuri);
if (uri == NULL)
Modified: icecast/branches/kh/icecast/src/format_flac.c
===================================================================
--- icecast/branches/kh/icecast/src/format_flac.c 2006-04-16 15:29:18 UTC (rev 11145)
+++ icecast/branches/kh/icecast/src/format_flac.c 2006-04-16 23:22:20 UTC (rev 11146)
@@ -71,11 +71,11 @@
}
if (codec->headers)
{
- format_ogg_attach_header (ogg_info, page);
+ format_ogg_attach_header (codec, page);
return NULL;
}
}
- refbuf = make_refbuf_with_page (page);
+ refbuf = make_refbuf_with_page (codec, page);
return refbuf;
}
@@ -113,9 +113,10 @@
codec->process_page = process_flac_page;
codec->codec_free = flac_codec_free;
codec->headers = 1;
+ codec->parent = ogg_info;
codec->name = "FLAC";
- format_ogg_attach_header (ogg_info, page);
+ format_ogg_attach_header (codec, page);
return codec;
} while (0);
Modified: icecast/branches/kh/icecast/src/format_midi.c
===================================================================
--- icecast/branches/kh/icecast/src/format_midi.c 2006-04-16 15:29:18 UTC (rev 11145)
+++ icecast/branches/kh/icecast/src/format_midi.c 2006-04-16 23:22:20 UTC (rev 11146)
@@ -50,7 +50,7 @@
ogg_info->error = 1;
return NULL;
}
- refbuf = make_refbuf_with_page (page);
+ refbuf = make_refbuf_with_page (codec, page);
return refbuf;
}
@@ -82,9 +82,10 @@
codec->process_page = process_midi_page;
codec->codec_free = midi_codec_free;
codec->headers = 1;
+ codec->parent = ogg_info;
codec->name = "MIDI";
- format_ogg_attach_header (ogg_info, page);
+ format_ogg_attach_header (codec, page);
return codec;
} while (0);
Modified: icecast/branches/kh/icecast/src/format_mp3.c
===================================================================
--- icecast/branches/kh/icecast/src/format_mp3.c 2006-04-16 15:29:18 UTC (rev 11145)
+++ icecast/branches/kh/icecast/src/format_mp3.c 2006-04-16 23:22:20 UTC (rev 11146)
@@ -182,9 +182,35 @@
p = calloc (1, len+1);
if (p)
{
+ mp3_state *source_mp3 = source->format->_state;
+
memcpy (p, metadata+13, len);
- logging_playlist (source->mount, p, source->listeners);
- stats_event (source->mount, "title", p);
+
+ if (source_mp3->charset)
+ {
+ xmlBufferPtr raw = xmlBufferCreate ();
+ xmlBufferPtr buf = xmlBufferCreate ();
+
+ xmlCharEncodingHandlerPtr handle =
+ xmlFindCharEncodingHandler (source_mp3->charset);
+ xmlBufferAdd (raw, (const xmlChar *) p, len);
+ if (xmlCharEncInFunc (handle, buf, raw) > 0)
+ {
+ stats_event (source->mount, "title", xmlBufferContent (buf));
+ logging_playlist (source->mount,
+ xmlBufferContent (buf), source->listeners);
+ }
+ else
+ logging_playlist (source->mount, p, source->listeners);
+ xmlFree (raw);
+ xmlFree (buf);
+ }
+ else
+ {
+ stats_event (source->mount, "title", p);
+ logging_playlist (source->mount, p, source->listeners);
+ }
+
yp_touch (source->mount);
free (p);
}
@@ -211,6 +237,17 @@
else
source_mp3->interval = mount->mp3_meta_interval;
DEBUG1 ("mp3 interval %d", source_mp3->interval);
+
+ if (source_mp3->charset)
+ {
+ xmlFree (source_mp3->charset);
+ source_mp3->charset = NULL;
+ }
+ if (mount)
+ {
+ source_mp3->charset = xmlStrdup (mount->mp3_charset);
+ DEBUG1 ("mp3 charset %s", source_mp3->charset);
+ }
}
Modified: icecast/branches/kh/icecast/src/format_mp3.h
===================================================================
--- icecast/branches/kh/icecast/src/format_mp3.h 2006-04-16 15:29:18 UTC (rev 11145)
+++ icecast/branches/kh/icecast/src/format_mp3.h 2006-04-16 23:22:20 UTC (rev 11146)
@@ -25,6 +25,7 @@
int interval;
char *url_artist;
char *url_title;
+ char *charset;
int update_metadata;
refbuf_t *metadata;
Modified: icecast/branches/kh/icecast/src/format_ogg.c
===================================================================
--- icecast/branches/kh/icecast/src/format_ogg.c 2006-04-16 15:29:18 UTC (rev 11145)
+++ icecast/branches/kh/icecast/src/format_ogg.c 2006-04-16 23:22:20 UTC (rev 11146)
@@ -59,6 +59,8 @@
static void write_ogg_to_file (struct source_tag *source, refbuf_t *refbuf);
static refbuf_t *ogg_get_buffer (source_t *source);
static int write_buf_to_client (client_t *client);
+static void apply_ogg_settings (client_t *client,
+ format_plugin_t *format, mount_proxy *mount);
struct ogg_client
@@ -70,10 +72,14 @@
};
-refbuf_t *make_refbuf_with_page (ogg_page *page)
+refbuf_t *make_refbuf_with_page (ogg_codec_t *codec, ogg_page *page)
{
- refbuf_t *refbuf = refbuf_new (page->header_len + page->body_len);
+ refbuf_t *refbuf;
+ if (codec && codec->filtered)
+ return NULL;
+ refbuf = refbuf_new (page->header_len + page->body_len);
+
memcpy (refbuf->data, page->header, page->header_len);
memcpy (refbuf->data+page->header_len, page->body, page->body_len);
return refbuf;
@@ -83,10 +89,16 @@
/* routine for taking the provided page (should be a header page) and
* placing it on the collection of header pages
*/
-void format_ogg_attach_header (ogg_state_t *ogg_info, ogg_page *page)
+void format_ogg_attach_header (ogg_codec_t *codec, ogg_page *page)
{
- refbuf_t *refbuf = make_refbuf_with_page (page);
+ ogg_state_t *ogg_info = codec->parent;
+ refbuf_t *refbuf;
+
+ if (codec->filtered)
+ return;
+ refbuf = make_refbuf_with_page (codec, page);
+
if (ogg_page_bos (page))
{
DEBUG0 ("attaching BOS page");
@@ -168,6 +180,7 @@
plugin->create_client_data = create_ogg_client_data;
plugin->free_plugin = format_ogg_free_plugin;
plugin->set_tag = NULL;
+ plugin->apply_settings = apply_ogg_settings;
plugin->contenttype = "application/ogg";
ogg_sync_init (&state->oy);
@@ -197,6 +210,19 @@
}
+static void apply_ogg_settings (client_t *client,
+ format_plugin_t *format, mount_proxy *mount)
+{
+ ogg_state_t *ogg_info = format->_state;
+
+ if (mount == NULL)
+ return;
+ if (mount->filter_theora)
+ ogg_info->filter_theora = 1;
+ DEBUG1 ("filter for theora is %d", ogg_info->filter_theora);
+}
+
+
/* a new BOS page has been seen so check which codec it is */
static int process_initial_page (format_plugin_t *plugin, ogg_page *page)
{
@@ -249,6 +275,7 @@
codec->next = ogg_info->codecs;
ogg_info->codecs = codec;
ogg_info->codec_count++;
+ DEBUG2 ("%s codec has filter mark %d", codec->name, codec->filtered);
}
return 0;
Modified: icecast/branches/kh/icecast/src/format_ogg.h
===================================================================
--- icecast/branches/kh/icecast/src/format_ogg.h 2006-04-16 15:29:18 UTC (rev 11145)
+++ icecast/branches/kh/icecast/src/format_ogg.h 2006-04-16 23:22:20 UTC (rev 11146)
@@ -39,6 +39,7 @@
refbuf_t **bos_end;
int bos_completed;
long bitrate;
+ int filter_theora;
struct ogg_codec_tag *current;
struct ogg_codec_tag *codec_sync;
} ogg_state_t;
@@ -48,9 +49,11 @@
typedef struct ogg_codec_tag
{
struct ogg_codec_tag *next;
+ ogg_state_t *parent;
ogg_stream_state os;
unsigned headers;
const char *name;
+ int filtered;
void *specific;
refbuf_t *possible_start;
refbuf_t *page;
@@ -62,8 +65,8 @@
} ogg_codec_t;
-refbuf_t *make_refbuf_with_page (ogg_page *page);
-void format_ogg_attach_header (ogg_state_t *ogg_info, ogg_page *page);
+refbuf_t *make_refbuf_with_page (ogg_codec_t *codec, ogg_page *page);
+void format_ogg_attach_header (ogg_codec_t *codec, ogg_page *page);
void format_ogg_free_headers (ogg_state_t *ogg_info);
int format_ogg_get_plugin (source_t *source);
Modified: icecast/branches/kh/icecast/src/format_speex.c
===================================================================
--- icecast/branches/kh/icecast/src/format_speex.c 2006-04-16 15:29:18 UTC (rev 11145)
+++ icecast/branches/kh/icecast/src/format_speex.c 2006-04-16 23:22:20 UTC (rev 11146)
@@ -53,10 +53,10 @@
codec->headers++;
}
/* add header page to associated list */
- format_ogg_attach_header (ogg_info, page);
+ format_ogg_attach_header (codec, page);
return NULL;
}
- refbuf = make_refbuf_with_page (page);
+ refbuf = make_refbuf_with_page (codec, page);
return refbuf;
}
@@ -86,7 +86,8 @@
codec->process_page = process_speex_page;
codec->codec_free = speex_codec_free;
codec->headers = 1;
- format_ogg_attach_header (ogg_info, page);
+ codec->parent = ogg_info;
+ format_ogg_attach_header (codec, page);
free (header);
return codec;
}
Modified: icecast/branches/kh/icecast/src/format_theora.c
===================================================================
--- icecast/branches/kh/icecast/src/format_theora.c 2006-04-16 15:29:18 UTC (rev 11145)
+++ icecast/branches/kh/icecast/src/format_theora.c 2006-04-16 23:22:20 UTC (rev 11146)
@@ -117,11 +117,11 @@
}
if (header_page)
{
- format_ogg_attach_header (ogg_info, page);
+ format_ogg_attach_header (codec, page);
return NULL;
}
- refbuf = make_refbuf_with_page (page);
+ refbuf = make_refbuf_with_page (codec, page);
/* DEBUG3 ("refbuf %p has pageno %ld, %llu", refbuf, ogg_page_pageno (page), (uint64_t)granulepos); */
if (has_keyframe && codec->possible_start)
@@ -134,8 +134,11 @@
{
if (codec->possible_start)
refbuf_release (codec->possible_start);
- refbuf_addref (refbuf);
- codec->possible_start = refbuf;
+ if (refbuf)
+ {
+ refbuf_addref (refbuf);
+ codec->possible_start = refbuf;
+ }
}
theora->prev_granulepos = granulepos;
@@ -176,11 +179,15 @@
codec->specific = theora_codec;
codec->process_page = process_theora_page;
codec->codec_free = theora_codec_free;
+ codec->parent = ogg_info;
codec->headers = 1;
+ if (ogg_info->filter_theora)
+ codec->filtered = 1;
codec->name = "Theora";
- format_ogg_attach_header (ogg_info, page);
- ogg_info->codec_sync = codec;
+ format_ogg_attach_header (codec, page);
+ if (codec->filtered == 0)
+ ogg_info->codec_sync = codec;
return codec;
}
Modified: icecast/branches/kh/icecast/src/format_vorbis.c
===================================================================
--- icecast/branches/kh/icecast/src/format_vorbis.c 2006-04-16 15:29:18 UTC (rev 11145)
+++ icecast/branches/kh/icecast/src/format_vorbis.c 2006-04-16 23:22:20 UTC (rev 11146)
@@ -158,7 +158,7 @@
source_vorbis->samples_in_page -= (ogg_page_granulepos (&page) - source_vorbis->prev_page_samples);
source_vorbis->prev_page_samples = ogg_page_granulepos (&page);
- refbuf = make_refbuf_with_page (&page);
+ refbuf = make_refbuf_with_page (codec, &page);
}
return refbuf;
}
@@ -172,7 +172,7 @@
while (ogg_stream_flush (&source_vorbis->new_os, &page) > 0)
{
- format_ogg_attach_header (ogg_info, &page);
+ format_ogg_attach_header (codec, &page);
headers_flushed = 1;
}
if (headers_flushed)
@@ -194,8 +194,7 @@
source_vorbis->samples_in_page -= (ogg_page_granulepos (&page) - source_vorbis->prev_page_samples);
source_vorbis->prev_page_samples = ogg_page_granulepos (&page);
- refbuf = make_refbuf_with_page (&page);
- DEBUG0 ("flushing page");
+ refbuf = make_refbuf_with_page (codec, &page);
return refbuf;
}
ogg_stream_clear (&source_vorbis->new_os);
@@ -357,6 +356,7 @@
*/
ogg_codec_t *initial_vorbis_page (format_plugin_t *plugin, ogg_page *page)
{
+ ogg_state_t *ogg_info = plugin->_state;
ogg_codec_t *codec = calloc (1, sizeof (ogg_codec_t));
ogg_packet packet;
@@ -384,6 +384,7 @@
codec->specific = vorbis;
codec->codec_free = vorbis_codec_free;
codec->headers = 1;
+ codec->parent = ogg_info;
codec->name = "Vorbis";
free_ogg_packet (vorbis->header[0]);
@@ -497,7 +498,7 @@
static refbuf_t *process_vorbis_passthru_page (ogg_state_t *ogg_info,
ogg_codec_t *codec, ogg_page *page)
{
- return make_refbuf_with_page (page);
+ return make_refbuf_with_page (codec, page);
}
@@ -534,7 +535,7 @@
if (ogg_stream_packetout (&codec->os, &header) <= 0)
{
if (ogg_info->codecs->next)
- format_ogg_attach_header (ogg_info, page);
+ format_ogg_attach_header (codec, page);
return NULL;
}
@@ -561,8 +562,8 @@
}
else
{
- format_ogg_attach_header (ogg_info, &source_vorbis->bos_page);
- format_ogg_attach_header (ogg_info, page);
+ format_ogg_attach_header (codec, &source_vorbis->bos_page);
+ format_ogg_attach_header (codec, page);
codec->process_page = process_vorbis_passthru_page;
}
Modified: icecast/branches/kh/icecast/src/slave.c
===================================================================
--- icecast/branches/kh/icecast/src/slave.c 2006-04-16 15:29:18 UTC (rev 11145)
+++ icecast/branches/kh/icecast/src/slave.c 2006-04-16 23:22:20 UTC (rev 11146)
@@ -448,7 +448,7 @@
slave_rebuild_mounts();
return;
}
- if (relay->on_demand)
+ if (relay->on_demand && relay->source)
{
ice_config_t *config = config_get_config ();
mount_proxy *mountinfo = config_find_mount (config, relay->localmount);
Modified: icecast/branches/kh/icecast/src/source.c
===================================================================
--- icecast/branches/kh/icecast/src/source.c 2006-04-16 15:29:18 UTC (rev 11145)
+++ icecast/branches/kh/icecast/src/source.c 2006-04-16 23:22:20 UTC (rev 11146)
@@ -702,6 +702,7 @@
/* start off the statistics */
stats_event_inc (NULL, "source_total_connections");
stats_event (source->mount, "slow_listeners", "0");
+ stats_event (source->mount, "listener_connections", "0");
stats_event (source->mount, "server_type", source->format->contenttype);
stats_event_args (source->mount, "listener_peak", "%lu", source->peak_listeners);
stats_event_time (source->mount, "stream_start");
Modified: icecast/branches/kh/icecast/src/xslt.c
===================================================================
--- icecast/branches/kh/icecast/src/xslt.c 2006-04-16 15:29:18 UTC (rev 11145)
+++ icecast/branches/kh/icecast/src/xslt.c 2006-04-16 23:22:20 UTC (rev 11146)
@@ -189,6 +189,7 @@
xsltStylesheetPtr cur;
xmlChar *string;
int len, problem = 0;
+ const char *mediatype = NULL;
xmlSetGenericErrorFunc ("", log_parse_failure);
xsltSetGenericErrorFunc ("", log_parse_failure);
@@ -208,19 +209,34 @@
if (xsltSaveResultToString (&string, &len, res, cur) < 0)
problem = 1;
- thread_mutex_unlock(&xsltlock);
+
+ /* lets find out the content type to use */
+ if (cur->mediaType)
+ mediatype = (char *)cur->mediaType;
+ else
+ {
+ /* check method for the default, a missing method assumes xml */
+ if (cur->method && xmlStrcmp (cur->method, "html") == 0)
+ mediatype = "text/html";
+ else
+ if (cur->method && xmlStrcmp (cur->method, "text") == 0)
+ mediatype = "text/plain";
+ else
+ mediatype = "text/xml";
+ }
if (problem == 0)
{
- const char *http = "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nContent-Length: ";
- size_t buf_len = strlen (http) + 20 + len;
+ /* the 100 is to allow for the hardcoded headers */
+ unsigned int header_len = strlen (mediatype) + len + 100;
+ refbuf_t *refbuf = refbuf_new (header_len);
- if (string == NULL)
- string = xmlCharStrdup ("");
+ len = snprintf (refbuf->data, header_len,
+ "HTTP/1.0 200 OK\r\nContent-Type: %s\r\nContent-Length: %d\r\n\r\n%s",
+ mediatype, len, string);
+
client->respcode = 200;
- client_set_queue (client, NULL);
- client->refbuf = refbuf_new (buf_len);
- len = snprintf (client->refbuf->data, buf_len, "%s%d\r\n\r\n%s", http, len, string);
- client->refbuf->len = len;
+ client_set_queue (client, refbuf);
+ refbuf->len = strlen (refbuf->data);
fserve_add_client (client, NULL);
xmlFree (string);
}
@@ -229,6 +245,7 @@
WARN1 ("problem applying stylesheet \"%s\"", xslfilename);
client_send_404 (client, "XSLT problem");
}
+ thread_mutex_unlock (&xsltlock);
xmlFreeDoc(res);
}
More information about the commits
mailing list