[xiph-commits] r11568 - icecast/branches/kh/icecast/src

karl at svn.xiph.org karl at svn.xiph.org
Tue Jun 13 15:38:21 PDT 2006


Author: karl
Date: 2006-06-13 15:37:58 -0700 (Tue, 13 Jun 2006)
New Revision: 11568

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_htpasswd.c
   icecast/branches/kh/icecast/src/cfgfile.c
   icecast/branches/kh/icecast/src/cfgfile.h
   icecast/branches/kh/icecast/src/client.c
   icecast/branches/kh/icecast/src/connection.c
   icecast/branches/kh/icecast/src/format.c
   icecast/branches/kh/icecast/src/format_ogg.c
   icecast/branches/kh/icecast/src/format_speex.c
   icecast/branches/kh/icecast/src/fserve.c
   icecast/branches/kh/icecast/src/logging.c
   icecast/branches/kh/icecast/src/slave.c
   icecast/branches/kh/icecast/src/source.c
   icecast/branches/kh/icecast/src/source.h
   icecast/branches/kh/icecast/src/stats.c
   icecast/branches/kh/icecast/src/stats.h
   icecast/branches/kh/icecast/src/util.c
   icecast/branches/kh/icecast/src/xslt.c
   icecast/branches/kh/icecast/src/yp.c
Log:
check in work, initial work on per-mount bitrate limits, various stats and type
cleanups that have accumulated.


Modified: icecast/branches/kh/icecast/src/admin.c
===================================================================
--- icecast/branches/kh/icecast/src/admin.c	2006-06-13 19:49:25 UTC (rev 11567)
+++ icecast/branches/kh/icecast/src/admin.c	2006-06-13 22:37:58 UTC (rev 11568)
@@ -253,7 +253,7 @@
     xmlDocSetRootElement(doc, xmlnode);
 
     if (mount) {
-        xmlNewChild(xmlnode, NULL, XMLSTR("current_source"), mount);
+        xmlNewChild(xmlnode, NULL, XMLSTR("current_source"), XMLSTR(mount));
     }
 
     node = avl_get_first(global.source_tree);
@@ -272,20 +272,20 @@
             mount_proxy *mountinfo;
 
             srcnode = xmlNewChild (xmlnode, NULL, XMLSTR("source"), NULL);
-            xmlSetProp (srcnode, "mount", source->mount);
+            xmlSetProp (srcnode, XMLSTR("mount"), XMLSTR(source->mount));
 
-            xmlNewChild (srcnode, NULL, "fallback", 
+            xmlNewChild (srcnode, NULL, XMLSTR("fallback"), 
                     (source->fallback_mount != NULL)?
-                    source->fallback_mount:"");
+                    XMLSTR(source->fallback_mount):XMLSTR(""));
             snprintf (buf, sizeof(buf), "%lu", source->listeners);
-            xmlNewChild (srcnode, NULL, "listeners", buf);
+            xmlNewChild (srcnode, NULL, XMLSTR("listeners"), XMLSTR(buf));
 
             config = config_get_config();
             mountinfo = config_find_mount (config, source->mount);
             if (mountinfo && mountinfo->auth)
             {
-                xmlNewChild(srcnode, NULL, "authenticator", 
-                        mountinfo->auth->type);
+                xmlNewChild(srcnode, NULL, XMLSTR("authenticator"), 
+                        XMLSTR(mountinfo->auth->type));
             }
             config_release_config();
 
@@ -295,10 +295,10 @@
                 {
                     snprintf (buf, sizeof(buf), "%lu",
                             (unsigned long)(now - source->client->con->con_time));
-                    xmlNewChild (srcnode, NULL, "Connected", buf);
+                    xmlNewChild (srcnode, NULL, XMLSTR("Connected"), XMLSTR(buf));
                 }
-                xmlNewChild (srcnode, NULL, "content-type", 
-                        source->format->contenttype);
+                xmlNewChild (srcnode, NULL, XMLSTR("content-type"), 
+                        XMLSTR(source->format->contenttype));
             }
         }
         thread_mutex_unlock (&source->lock);
@@ -649,17 +649,16 @@
 
     INFO2 ("source is \"%s\", destination is \"%s\"", source->mount, dest->mount);
 
-    doc = xmlNewDoc("1.0");
-    node = xmlNewDocNode(doc, NULL, "iceresponse", NULL);
+    doc = xmlNewDoc(XMLSTR("1.0"));
+    node = xmlNewDocNode(doc, NULL, XMLSTR("iceresponse"), NULL);
     xmlDocSetRootElement(doc, node);
 
     source_move_clients (source, dest);
 
-    memset(buf, '\000', sizeof(buf));
     snprintf (buf, sizeof(buf), "Clients moved from %s to %s",
             source->mount, dest_source);
-    xmlNewChild(node, NULL, "message", buf);
-    xmlNewChild(node, NULL, "return", "1");
+    xmlNewChild(node, NULL, XMLSTR("message"), XMLSTR(buf));
+    xmlNewChild(node, NULL, XMLSTR("return"), XMLSTR("1"));
 
     admin_send_response(doc, client, response, 
         ADMIN_XSL_RESPONSE);
@@ -700,12 +699,12 @@
         client_send_400 (client, "No such handler");
         return;
     }
-    doc = xmlNewDoc("1.0");
-    node = xmlNewDocNode(doc, NULL, "iceresponse", NULL);
+    doc = xmlNewDoc(XMLSTR("1.0"));
+    node = xmlNewDocNode(doc, NULL, XMLSTR("iceresponse"), NULL);
     xmlDocSetRootElement(doc, node);
 
-    xmlNewChild(node, NULL, "message", buf);
-    xmlNewChild(node, NULL, "return", "1");
+    xmlNewChild(node, NULL, XMLSTR("message"), XMLSTR(buf));
+    xmlNewChild(node, NULL, XMLSTR("return"), XMLSTR("1"));
 
     admin_send_response(doc, client, response, 
         ADMIN_XSL_RESPONSE);
@@ -715,19 +714,19 @@
 
 static void add_relay_xmlnode (xmlNodePtr node, relay_server *relay, int master)
 {
-    xmlNodePtr relaynode = xmlNewChild (node, NULL, "relay", NULL);
+    xmlNodePtr relaynode = xmlNewChild (node, NULL, XMLSTR("relay"), NULL);
     char str [20];
-    xmlNewChild (relaynode, NULL, "server", relay->server);
-    xmlNewChild (relaynode, NULL, "mount", relay->mount);
+    xmlNewChild (relaynode, NULL, XMLSTR("server"), XMLSTR(relay->server));
+    xmlNewChild (relaynode, NULL, XMLSTR("mount"), XMLSTR(relay->mount));
     snprintf (str, sizeof (str), "%d", relay->port);
-    xmlNewChild (relaynode, NULL, "port", str);
-    xmlNewChild (relaynode, NULL, "localmount", relay->localmount);
+    xmlNewChild (relaynode, NULL, XMLSTR("port"), XMLSTR(str));
+    xmlNewChild (relaynode, NULL, XMLSTR("localmount"), XMLSTR(relay->localmount));
     snprintf (str, sizeof (str), "%d", relay->enable);
-    xmlNewChild (relaynode, NULL, "enable", str);
+    xmlNewChild (relaynode, NULL, XMLSTR("enable"), XMLSTR(str));
     snprintf (str, sizeof (str), "%d", relay->on_demand);
-    xmlNewChild (relaynode, NULL, "on_demand", str);
+    xmlNewChild (relaynode, NULL, XMLSTR("on_demand"), XMLSTR(str));
     snprintf (str, sizeof (str), "%d", master);
-    xmlNewChild (relaynode, NULL, "master", str);
+    xmlNewChild (relaynode, NULL, XMLSTR("master"), XMLSTR(str));
 }
 
 
@@ -744,8 +743,8 @@
 
     if (relay_mount == NULL || enable == NULL)
     {
-        doc = xmlNewDoc ("1.0");
-        node = xmlNewDocNode (doc, NULL, "icerelaystats", NULL);
+        doc = xmlNewDoc (XMLSTR("1.0"));
+        node = xmlNewDocNode (doc, NULL, XMLSTR("icerelaystats"), NULL);
         xmlDocSetRootElement(doc, node);
         thread_mutex_lock (&(config_locks()->relay_lock));
 
@@ -780,11 +779,11 @@
     }
     thread_mutex_unlock (&(config_locks()->relay_lock));
 
-    doc = xmlNewDoc("1.0");
-    node = xmlNewDocNode(doc, NULL, "iceresponse", NULL);
+    doc = xmlNewDoc(XMLSTR("1.0"));
+    node = xmlNewDocNode(doc, NULL, XMLSTR("iceresponse"), NULL);
     xmlDocSetRootElement(doc, node);
-    xmlNewChild(node, NULL, "message", msg);
-    xmlNewChild(node, NULL, "return", "1");
+    xmlNewChild(node, NULL, XMLSTR("message"), XMLSTR(msg));
+    xmlNewChild(node, NULL, XMLSTR("return"), XMLSTR("1"));
     admin_send_response(doc, client, response, ADMIN_XSL_RESPONSE);
     xmlFreeDoc(doc);
 }
@@ -807,21 +806,21 @@
     while (listener)
     {
         char *useragent;
-        xmlNodePtr node = xmlNewChild (srcnode, NULL, "listener", NULL);
+        xmlNodePtr node = xmlNewChild (srcnode, NULL, XMLSTR("listener"), NULL);
 
         snprintf (buf, sizeof (buf), "%lu", listener->con->id);
-        xmlNewChild (node, NULL, "ID", buf);
+        xmlNewChild (node, NULL, XMLSTR("ID"), XMLSTR(buf));
 
-        xmlNewChild (node, NULL, "IP", listener->con->ip);
+        xmlNewChild (node, NULL, XMLSTR("IP"), XMLSTR(listener->con->ip));
 
         useragent = httpp_getvar (listener->parser, "user-agent");
-        xmlNewChild (node, NULL, "UserAgent", useragent); 
+        xmlNewChild (node, NULL, XMLSTR("UserAgent"), XMLSTR(useragent)); 
 
         snprintf (buf, sizeof (buf), "%lu",
                 (unsigned long)(global.time - listener->con->con_time));
-        xmlNewChild (node, NULL, "Connected", buf);
+        xmlNewChild (node, NULL, XMLSTR("Connected"), XMLSTR(buf));
         if (listener->username)
-            xmlNewChild (node, NULL, "Username", listener->username);
+            xmlNewChild (node, NULL, XMLSTR("Username"), XMLSTR(listener->username));
 
         listener = listener->next;
     }
@@ -836,15 +835,15 @@
     xmlNodePtr node, srcnode;
     char buf[22];
 
-    doc = xmlNewDoc("1.0");
-    node = xmlNewDocNode(doc, NULL, "icestats", NULL);
-    srcnode = xmlNewChild(node, NULL, "source", NULL);
+    doc = xmlNewDoc(XMLSTR("1.0"));
+    node = xmlNewDocNode(doc, NULL, XMLSTR("icestats"), NULL);
+    srcnode = xmlNewChild(node, NULL, XMLSTR("source"), NULL);
 
-    xmlSetProp(srcnode, "mount", source->mount);
+    xmlSetProp(srcnode, XMLSTR("mount"), XMLSTR(source->mount));
     xmlDocSetRootElement(doc, node);
 
     snprintf(buf, sizeof(buf), "%lu", source->listeners);
-    xmlNewChild(srcnode, NULL, "Listeners", buf);
+    xmlNewChild(srcnode, NULL, XMLSTR("Listeners"), XMLSTR(buf));
 
     admin_source_listeners (source, srcnode);
 
@@ -1202,7 +1201,7 @@
         doc = xmlNewDoc(XMLSTR("1.0"));
         xmlnode = xmlNewDocNode(doc, NULL, XMLSTR("icestats"), NULL);
         xmlDocSetRootElement(doc, xmlnode);
-        lognode = xmlNewTextChild (xmlnode, NULL, XMLSTR("log"), content->data);
+        lognode = xmlNewTextChild (xmlnode, NULL, XMLSTR("log"), XMLSTR(content->data));
         refbuf_release (content);
 
         admin_send_response (doc, client, TRANSFORMED, "showlog.xsl");
@@ -1247,6 +1246,8 @@
             source_t *source;
             mountinfo = mountinfo->next;
 
+            if (current->hidden)
+                continue;
             /* avoid non-specific mounts */
             if (strcmp (current->mountname, "all") == 0)
                 continue;
@@ -1257,8 +1258,6 @@
                 continue;
             if (source->running == 0 && source->on_demand == 0)
                 continue;
-            if (source->hidden)
-                continue;
             remaining -= ret;
             buf += ret;
             ret = snprintf (buf, remaining, "%s\n", current->mountname);

Modified: icecast/branches/kh/icecast/src/auth.c
===================================================================
--- icecast/branches/kh/icecast/src/auth.c	2006-06-13 19:49:25 UTC (rev 11567)
+++ icecast/branches/kh/icecast/src/auth.c	2006-06-13 22:37:58 UTC (rev 11568)
@@ -61,6 +61,7 @@
         if (client == NULL)
             break;
 
+        /* process any auth headers if any available */
         header = httpp_getvar(client->parser, "authorization");
         if (header == NULL)
             break;
@@ -348,7 +349,9 @@
             {
                 ERROR2("Fallback '%s' for full source '%s' not found",
                         source->mount, source->fallback_mount);
+                return -1;
             }
+
             INFO1 ("stream full trying %s", next->mount);
             source = next;
             loop--;
@@ -369,8 +372,6 @@
     client->next = source->active_clients;
     source->active_clients = client;
     source->listeners++;
-    stats_event_inc (NULL, "listener_connections");
-    stats_event_inc (source->mount, "listener_connections");
 
     thread_mutex_unlock (&source->lock);
 
@@ -468,7 +469,7 @@
 /* Add a listener. Check for any mount information that states any
  * authentication to be used.
  */
-void add_client (const char *mount, client_t *client)
+void auth_add_client (const char *mount, client_t *client)
 {
     mount_proxy *mountinfo; 
     ice_config_t *config;
@@ -521,7 +522,7 @@
 /* determine whether we need to process this client further. This
  * involves any auth exit, typically for external auth servers.
  */
-int release_client (client_t *client)
+int auth_client_release (client_t *client)
 {
     if (client->auth && client->authenticated)
     {
@@ -545,13 +546,16 @@
     do
     {
         DEBUG1 ("type is %s", auth->type);
-#ifdef HAVE_AUTH_URL
+
         if (strcmp (auth->type, "url") == 0)
         {
+#ifdef HAVE_AUTH_URL
             auth_get_url_auth (auth, options);
+#else
+            ERROR0 ("Auth URL disabled");
+#endif
             break;
         }
-#endif
         if (strcmp (auth->type, "command") == 0)
         {
 #ifdef WIN32
@@ -578,7 +582,7 @@
         if (strcmp(options->name, "allow_duplicate_users") == 0)
             auth->allow_duplicate_users = atoi (options->value);
         else if (strcmp(options->name, "realm") == 0)
-            auth->realm = xmlStrdup (options->value);
+            auth->realm = (char*)xmlStrdup (XMLSTR(options->value));
         else if (strcmp(options->name, "drop_existing_listener") == 0)
             auth->drop_existing_listener = atoi (options->value);
         options = options->next;
@@ -601,16 +605,16 @@
     {
         xmlNodePtr current = option;
         option = option->next;
-        if (strcmp (current->name, "option") == 0)
+        if (xmlStrcmp (current->name, XMLSTR("option")) == 0)
         {
             config_options_t *opt = calloc (1, sizeof (config_options_t));
-            opt->name = xmlGetProp (current, "name");
+            opt->name = (char *)xmlGetProp (current, XMLSTR("name"));
             if (opt->name == NULL)
             {
                 free(opt);
                 continue;
             }
-            opt->value = xmlGetProp (current, "value");
+            opt->value = (char *)xmlGetProp (current, XMLSTR("value"));
             if (opt->value == NULL)
             {
                 xmlFree (opt->name);
@@ -621,10 +625,10 @@
             next_option = &opt->next;
         }
         else
-            if (strcmp (current->name, "text") != 0)
+            if (xmlStrcmp (current->name, XMLSTR("text")) != 0)
                 WARN1 ("unknown auth setting (%s)", current->name);
     }
-    auth->type = xmlGetProp (node, "type");
+    auth->type = (char *)xmlGetProp (node, XMLSTR("type"));
     get_authenticator (auth, options);
     thread_mutex_create ("auth_t", &auth->lock);
     while (options)
@@ -660,32 +664,29 @@
 /* called when the stream starts, so that authentication engine can do any
  * cleanup/initialisation.
  */
-void auth_stream_start (mount_proxy *mountinfo, source_t *source)
+void auth_stream_start (mount_proxy *mountinfo, const char *mount)
 {
     if (mountinfo && mountinfo->auth && mountinfo->auth->stream_start)
     {
-        auth_client *auth_user = auth_client_setup (source->mount,
-                mountinfo, NULL);
+        auth_client *auth_user = auth_client_setup (mount, mountinfo, NULL);
         auth_user->process = stream_start_callback;
-        INFO1 ("request source start for \"%s\"", source->mount);
+        INFO1 ("request source start for \"%s\"", mount);
 
         queue_auth_client (auth_user);
     }
 }
 
 
-
 /* Called when the stream ends so that the authentication engine can do
  * any authentication cleanup
  */
-void auth_stream_end (mount_proxy *mountinfo, source_t *source)
+void auth_stream_end (mount_proxy *mountinfo, const char *mount)
 {
     if (mountinfo && mountinfo->auth && mountinfo->auth->stream_end)
     {
-        auth_client *auth_user = auth_client_setup (source->mount,
-                mountinfo, NULL);
+        auth_client *auth_user = auth_client_setup (mount, mountinfo, NULL);
         auth_user->process = stream_end_callback;
-        INFO1 ("request source end for \"%s\"", source->mount);
+        INFO1 ("request source end for \"%s\"", mount);
 
         queue_auth_client (auth_user);
     }

Modified: icecast/branches/kh/icecast/src/auth.h
===================================================================
--- icecast/branches/kh/icecast/src/auth.h	2006-06-13 19:49:25 UTC (rev 11567)
+++ icecast/branches/kh/icecast/src/auth.h	2006-06-13 22:37:58 UTC (rev 11568)
@@ -80,8 +80,8 @@
     char *realm;
 } auth_t;
 
-void add_client (const char *mount, client_t *client);
-int  release_client (client_t *client);
+void auth_add_client (const char *mount, client_t *client);
+int  auth_client_release (client_t *client);
 
 void auth_initialise (void);
 void auth_shutdown (void);
@@ -90,10 +90,10 @@
 void    auth_release (auth_t *authenticator);
 
 /* call to send a url request when source starts */
-void auth_stream_start (struct _mount_proxy *mountinfo, struct source_tag *source);
+void auth_stream_start (struct _mount_proxy *mountinfo, const char *mount);
 
 /* call to send a url request when source ends */
-void auth_stream_end (struct _mount_proxy *mountinfo, struct source_tag *source);
+void auth_stream_end (struct _mount_proxy *mountinfo, const char *mount);
 
 /* */
 int auth_stream_authenticate (client_t *client, const char *mount,

Modified: icecast/branches/kh/icecast/src/auth_htpasswd.c
===================================================================
--- icecast/branches/kh/icecast/src/auth_htpasswd.c	2006-06-13 19:49:25 UTC (rev 11567)
+++ icecast/branches/kh/icecast/src/auth_htpasswd.c	2006-06-13 22:37:58 UTC (rev 11568)
@@ -88,7 +88,7 @@
 
     MD5Init(&context);
 
-    MD5Update(&context, data, len);
+    MD5Update(&context, (const unsigned char *)data, len);
 
     MD5Final(digest, &context);
 

Modified: icecast/branches/kh/icecast/src/cfgfile.c
===================================================================
--- icecast/branches/kh/icecast/src/cfgfile.c	2006-06-13 19:49:25 UTC (rev 11567)
+++ icecast/branches/kh/icecast/src/cfgfile.c	2006-06-13 22:37:58 UTC (rev 11568)
@@ -26,7 +26,7 @@
 #include "client.h"
 #include "logging.h" 
 
-#define CATMODULE "CONFIG"
+#define CATMODULE "cfgfile"
 #define CONFIG_DEFAULT_LOCATION "Earth"
 #define CONFIG_DEFAULT_ADMIN "icemaster at localhost"
 #define CONFIG_DEFAULT_CLIENT_LIMIT 256
@@ -51,8 +51,6 @@
 #define CONFIG_DEFAULT_LOG_LEVEL 4
 #define CONFIG_DEFAULT_CHROOT 0
 #define CONFIG_DEFAULT_CHUID 0
-#define CONFIG_DEFAULT_USER NULL
-#define CONFIG_DEFAULT_GROUP NULL
 #define CONFIG_MASTER_UPDATE_INTERVAL 120
 #define CONFIG_YP_URL_TIMEOUT 10
 
@@ -120,7 +118,7 @@
         return -1;
     if (p)
         xmlFree (p);
-    *(char **)x = str;
+    *(xmlChar **)x = str;
     return 0;
 }
 
@@ -406,9 +404,9 @@
 
 static void _set_defaults(ice_config_t *configuration)
 {
-    configuration->location = xmlCharStrdup (CONFIG_DEFAULT_LOCATION);
+    configuration->location = (char *)xmlCharStrdup (CONFIG_DEFAULT_LOCATION);
     configuration->server_id = (char *)xmlCharStrdup (ICECAST_VERSION_STRING);
-    configuration->admin = CONFIG_DEFAULT_ADMIN;
+    configuration->admin = (char *)xmlCharStrdup (CONFIG_DEFAULT_ADMIN);
     configuration->client_limit = CONFIG_DEFAULT_CLIENT_LIMIT;
     configuration->source_limit = CONFIG_DEFAULT_SOURCE_LIMIT;
     configuration->queue_size_limit = CONFIG_DEFAULT_QUEUE_SIZE_LIMIT;
@@ -416,14 +414,14 @@
     configuration->client_timeout = CONFIG_DEFAULT_CLIENT_TIMEOUT;
     configuration->header_timeout = CONFIG_DEFAULT_HEADER_TIMEOUT;
     configuration->source_timeout = CONFIG_DEFAULT_SOURCE_TIMEOUT;
-    configuration->source_password = CONFIG_DEFAULT_SOURCE_PASSWORD;
-    configuration->shoutcast_mount = xmlCharStrdup (CONFIG_DEFAULT_SHOUTCAST_MOUNT);
+    configuration->source_password = (char *)xmlCharStrdup (CONFIG_DEFAULT_SOURCE_PASSWORD);
+    configuration->shoutcast_mount = (char *)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 = xmlCharStrdup (CONFIG_DEFAULT_HOSTNAME);
+    configuration->hostname = (char *)xmlCharStrdup (CONFIG_DEFAULT_HOSTNAME);
     configuration->port = 0;
     configuration->listeners[0].port = 0;
     configuration->listeners[0].bind_address = NULL;
@@ -434,18 +432,18 @@
     configuration->master_username = (char*)xmlCharStrdup (CONFIG_DEFAULT_MASTER_USERNAME);
     configuration->master_password = NULL;
     configuration->master_relay_auth = 0;
-    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->base_dir = (char *)xmlCharStrdup (CONFIG_DEFAULT_BASE_DIR);
+    configuration->log_dir = (char *)xmlCharStrdup (CONFIG_DEFAULT_LOG_DIR);
+    configuration->webroot_dir = (char *)xmlCharStrdup (CONFIG_DEFAULT_WEBROOT_DIR);
+    configuration->adminroot_dir = (char *)xmlCharStrdup (CONFIG_DEFAULT_ADMINROOT_DIR);
+    configuration->playlist_log = (char *)xmlCharStrdup (CONFIG_DEFAULT_PLAYLIST_LOG);
+    configuration->access_log = (char *)xmlCharStrdup (CONFIG_DEFAULT_ACCESS_LOG);
+    configuration->error_log = (char *)xmlCharStrdup (CONFIG_DEFAULT_ERROR_LOG);
     configuration->loglevel = CONFIG_DEFAULT_LOG_LEVEL;
     configuration->chroot = CONFIG_DEFAULT_CHROOT;
     configuration->chuid = CONFIG_DEFAULT_CHUID;
-    configuration->user = CONFIG_DEFAULT_USER;
-    configuration->group = CONFIG_DEFAULT_GROUP;
+    configuration->user = NULL;
+    configuration->group = NULL;
     configuration->num_yp_directories = 0;
     configuration->slaves_count = 0;
     configuration->relay_username = (char *)xmlCharStrdup (CONFIG_DEFAULT_MASTER_USERNAME);
@@ -461,18 +459,18 @@
     aliases **cur, *alias = calloc (1, sizeof (aliases));
     xmlChar *temp;
     
-    alias->source = xmlGetProp (node, "source");
-    alias->destination = xmlGetProp (node, "dest");
+    alias->source = (char *)xmlGetProp (node, XMLSTR ("source"));
+    alias->destination = (char *)xmlGetProp (node, XMLSTR ("dest"));
     if (alias->source == NULL || alias->destination == NULL)
     {
-        if (alias->source) xmlFree (alias->source);
-        if (alias->destination) xmlFree (alias->destination);
+        if (alias->source) xmlFree (XMLSTR (alias->source));
+        if (alias->destination) xmlFree (XMLSTR (alias->destination));
         free (alias);
         WARN0 ("incomplete alias definition");
         return -1;
     }
-    alias->bind_address = xmlGetProp (node, "bind-address");
-    temp = xmlGetProp(node, "port");
+    alias->bind_address = (char *)xmlGetProp (node, XMLSTR("bind-address"));
+    temp = xmlGetProp(node, XMLSTR("port"));
     alias->port = -1;
     if (temp)
     {
@@ -631,7 +629,11 @@
         { "fallback-when-full",
                             config_get_bool,    &mount->fallback_when_full },
         { "max-listeners",  config_get_int,     &mount->max_listeners },
+        { "wait-time",      config_get_int,     &mount->wait_time },
         { "filter-theora",  config_get_bool,    &mount->filter_theora },
+        { "limit-rate",     config_get_int,     &mount->limit_rate },
+        { "avg-bitrate-duration",
+                            config_get_int,     &mount->avg_bitrate_duration },
         { "charset",        config_get_str,     &mount->charset },
         { "mp3-metadata-interval",
                             config_get_int,     &mount->mp3_meta_interval },
@@ -666,6 +668,7 @@
     mount->mp3_meta_interval = -1;
     mount->yp_public = -1;
     mount->url_ogg_meta = 0;
+    mount->avg_bitrate_duration = 60;
 
     if (parse_xml_tags (node, icecast_tags))
         return -1;
@@ -675,6 +678,8 @@
         config_clear_mount (mount);
         return -1;
     }
+    if (mount->avg_bitrate_duration < 2)
+        mount->avg_bitrate_duration = 2;
 
     mount->next = config->mounts;
     config->mounts = mount;
@@ -773,8 +778,8 @@
                 {
                     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);
+                    sc_port->bind_address = (char*)xmlStrdup (XMLSTR(listener->bind_address));
+                    sc_port->shoutcast_mount= (char*)xmlStrdup (XMLSTR(listener->shoutcast_mount));
                 }
             }
             if (config->port == 0)
@@ -827,6 +832,11 @@
 
     if (config->max_redirects == 0 && config->master_redirect)
         config->max_redirects = 1;
+    if (config->listeners[0].port <= 0)
+    {
+        WARN0 ("No listen-socket defintions");
+        return -1;
+    }
     return 0;
 }
 

Modified: icecast/branches/kh/icecast/src/cfgfile.h
===================================================================
--- icecast/branches/kh/icecast/src/cfgfile.h	2006-06-13 19:49:25 UTC (rev 11567)
+++ icecast/branches/kh/icecast/src/cfgfile.h	2006-06-13 22:37:58 UTC (rev 11568)
@@ -71,6 +71,15 @@
     int filter_theora; /* prevent theora pages getting queued */
     int url_ogg_meta; /* enable to allow updates via url requests for ogg */
 
+    /* duration in seconds for sampling the bandwidth */
+    int avg_bitrate_duration;
+
+    /* trigger level at which a timer is used to prevent excessive incoming bandwidth */
+    int limit_rate;
+
+    /* duration (secs) for mountpoint to be kept reserved after source client exits */
+    int wait_time;
+
     char *auth_type; /* Authentication type */
     struct auth_tag *auth;
     char *cluster_password;

Modified: icecast/branches/kh/icecast/src/client.c
===================================================================
--- icecast/branches/kh/icecast/src/client.c	2006-06-13 19:49:25 UTC (rev 11567)
+++ icecast/branches/kh/icecast/src/client.c	2006-06-13 22:37:58 UTC (rev 11568)
@@ -101,7 +101,7 @@
         client->refbuf = NULL;
     }
 
-    if (release_client (client))
+    if (auth_client_release (client))
         return;
 
     /* write log entry if ip is set (some things don't set it, like outgoing 
@@ -191,29 +191,7 @@
     fserve_add_client (client, NULL);
 }
 
-void client_send_403(client_t *client, const char *reason)
-{
-    if (reason == NULL)
-        reason = "Forbidden";
-    snprintf (client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
-            "HTTP/1.0 403 %s\r\n\r\n", reason);
-    client->respcode = 403;
-    client->refbuf->len = strlen (client->refbuf->data);
-    fserve_add_client (client, NULL);
-}
 
-void client_send_404(client_t *client, char *message) {
-
-    snprintf (client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
-            "HTTP/1.0 404 File Not Found\r\n"
-            "Content-Type: text/html\r\n\r\n"
-            "<b>%s</b>\r\n", message);
-    client->respcode = 404;
-    client->refbuf->len = strlen (client->refbuf->data);
-    fserve_add_client (client, NULL);
-}
-
-
 void client_send_401 (client_t *client)
 {
     ice_config_t *config = config_get_config ();
@@ -237,6 +215,30 @@
 }
 
 
+void client_send_403(client_t *client, const char *reason)
+{
+    if (reason == NULL)
+        reason = "Forbidden";
+    snprintf (client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
+            "HTTP/1.0 403 %s\r\n"
+            "Content-Type: text/html\r\n\r\n", reason);
+    client->respcode = 403;
+    client->refbuf->len = strlen (client->refbuf->data);
+    fserve_add_client (client, NULL);
+}
+
+void client_send_404(client_t *client, char *message) {
+
+    snprintf (client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
+            "HTTP/1.0 404 File Not Found\r\n"
+            "Content-Type: text/html\r\n\r\n"
+            "<b>%s</b>\r\n", message);
+    client->respcode = 404;
+    client->refbuf->len = strlen (client->refbuf->data);
+    fserve_add_client (client, NULL);
+}
+
+
 void client_send_416(client_t *client)
 {
     snprintf (client->refbuf->data, PER_CLIENT_REFBUF_SIZE,

Modified: icecast/branches/kh/icecast/src/connection.c
===================================================================
--- icecast/branches/kh/icecast/src/connection.c	2006-06-13 19:49:25 UTC (rev 11567)
+++ icecast/branches/kh/icecast/src/connection.c	2006-06-13 22:37:58 UTC (rev 11568)
@@ -994,10 +994,8 @@
     while (*pattern)
     {
         int len = strcspn (pattern, " ");
-        DEBUG3 ("...pattern is \"%.*s\" (%d)", len, pattern, len);
         if (strncmp (extension, pattern, len) == 0 && extension[len] == '\0')
         {
-            DEBUG0 ("found a match");
             httpp_setvar (client->parser, "__avoid_access_log", "");
             return;
         }
@@ -1005,7 +1003,6 @@
         len = strspn (pattern, " "); /* find next pattern */
         pattern += len;
     }
-    DEBUG0 ("no match for pattern");
 }
 
 
@@ -1077,7 +1074,7 @@
         return;
     }
 
-    add_client (uri, client);
+    auth_add_client (uri, client);
     if (uri != passed_uri) free (uri);
 }
 

Modified: icecast/branches/kh/icecast/src/format.c
===================================================================
--- icecast/branches/kh/icecast/src/format.c	2006-06-13 19:49:25 UTC (rev 11567)
+++ icecast/branches/kh/icecast/src/format.c	2006-06-13 22:37:58 UTC (rev 11568)
@@ -90,8 +90,6 @@
     default:
         break;
     }
-    source->format->in_bitrate = rate_setup (30);
-    source->format->out_bitrate = rate_setup (30);
 
     return ret;
 }
@@ -112,11 +110,11 @@
         refbuf = source->stream_data_tail;
     else
     {
-        long size = client->intro_offset;
+        size_t size = client->intro_offset;
         refbuf = source->burst_point;
-        while (size > 0 && refbuf->next)
+        while (size > 0 && refbuf && refbuf->next)
         {
-            size -= (long)refbuf->len;
+            size -= refbuf->len;
             refbuf = refbuf->next;
         }
     }
@@ -219,6 +217,9 @@
             client->con->error = 1;
             return -1;
         }
+        stats_event_inc (NULL, "listeners");
+        stats_event_inc (NULL, "listener_connections");
+        stats_event_inc (source->mount, "listener_connections");
     }
 
     if (client->pos == refbuf->len)

Modified: icecast/branches/kh/icecast/src/format_ogg.c
===================================================================
--- icecast/branches/kh/icecast/src/format_ogg.c	2006-06-13 19:49:25 UTC (rev 11567)
+++ icecast/branches/kh/icecast/src/format_ogg.c	2006-06-13 22:37:58 UTC (rev 11568)
@@ -215,7 +215,7 @@
 {
     ogg_state_t *ogg_info = format->_state;
 
-    if (mount == NULL && format == NULL)
+    if (mount == NULL || format == NULL)
         return;
     if (mount->filter_theora)
         ogg_info->filter_theora = 1;

Modified: icecast/branches/kh/icecast/src/format_speex.c
===================================================================
--- icecast/branches/kh/icecast/src/format_speex.c	2006-06-13 19:49:25 UTC (rev 11567)
+++ icecast/branches/kh/icecast/src/format_speex.c	2006-06-13 22:37:58 UTC (rev 11568)
@@ -74,7 +74,7 @@
     ogg_stream_packetout (&codec->os, &packet);
 
     DEBUG0("checking for speex codec");
-    header = speex_packet_to_header (packet.packet, packet.bytes);
+    header = speex_packet_to_header ((char*)packet.packet, packet.bytes);
     if (header == NULL)
     {
         ogg_stream_clear (&codec->os);

Modified: icecast/branches/kh/icecast/src/fserve.c
===================================================================
--- icecast/branches/kh/icecast/src/fserve.c	2006-06-13 19:49:25 UTC (rev 11567)
+++ icecast/branches/kh/icecast/src/fserve.c	2006-06-13 22:37:58 UTC (rev 11568)
@@ -354,6 +354,8 @@
             return "image/png";
         else if(!strcmp(ext, "m3u"))
             return "audio/x-mpegurl";
+        else if(!strcmp(ext, "aac"))
+            return "audio/aac";
         else
             return "application/octet-stream";
     }

Modified: icecast/branches/kh/icecast/src/logging.c
===================================================================
--- icecast/branches/kh/icecast/src/logging.c	2006-06-13 19:49:25 UTC (rev 11567)
+++ icecast/branches/kh/icecast/src/logging.c	2006-06-13 22:37:58 UTC (rev 11568)
@@ -156,7 +156,11 @@
     if (httpp_getvar (client->parser, "__avoid_access_log") == NULL)
         keep = 1;
 
+#ifdef HAVE_LOG_DIRECT_KEEP
     log_write_direct_keep (accesslog, keep,
+#else
+    log_write_direct_keep (accesslog,
+#endif
             "%s - %s [%s] \"%s\" %d " FORMAT_UINT64 " \"%s\" \"%s\" %lu",
             ip, username,
             datebuf, reqbuf, client->respcode, client->con->sent_bytes,
@@ -189,7 +193,7 @@
 #endif
     /* This format MAY CHANGE OVER TIME.  We are looking into finding a good
        standard format for this, if you have any ideas, please let us know */
-    log_write_direct (playlistlog, "%s|%s|%d|%s",
+    log_write_direct (playlistlog, "%s|%s|%ld|%s",
              datebuf,
              mount,
              listeners,

Modified: icecast/branches/kh/icecast/src/slave.c
===================================================================
--- icecast/branches/kh/icecast/src/slave.c	2006-06-13 19:49:25 UTC (rev 11567)
+++ icecast/branches/kh/icecast/src/slave.c	2006-06-13 22:37:58 UTC (rev 11568)
@@ -96,13 +96,13 @@
 
     if (copy)
     {
-        copy->server = xmlCharStrdup (r->server);
-        copy->mount = xmlCharStrdup (r->mount);
-        copy->localmount = xmlStrdup (r->localmount);
+        copy->server = (char *)xmlCharStrdup (r->server);
+        copy->mount = (char *)xmlCharStrdup (r->mount);
+        copy->localmount = (char *)xmlStrdup (XMLSTR(r->localmount));
         if (r->username)
-            copy->username = xmlStrdup (r->username);
+            copy->username = (char *)xmlStrdup (XMLSTR(r->username));
         if (r->password)
-            copy->password = xmlStrdup (r->password);
+            copy->password = (char *)xmlStrdup (XMLSTR(r->password));
         copy->port = r->port;
         copy->mp3metadata = r->mp3metadata;
         copy->on_demand = r->on_demand;
@@ -410,7 +410,6 @@
             if (source->fallback_mount && source->fallback_override)
             {
                 source_t *fallback;
-                DEBUG1 ("checking %s for fallback override", source->fallback_mount);
                 avl_tree_rlock (global.source_tree);
                 fallback = source_find_mount (source->fallback_mount);
                 if (fallback && fallback->running && fallback->listeners)
@@ -672,17 +671,17 @@
         if (strlen (buf))
         {
             relay_server *r = calloc (1, sizeof (relay_server));
-            r->server = xmlStrdup (master->server);
+            r->server = (char *)xmlStrdup (XMLSTR(master->server));
             r->port = master->port;
-            r->mount = xmlStrdup (buf);
-            r->localmount = xmlStrdup (buf);
+            r->mount = (char *)xmlStrdup (XMLSTR(buf));
+            r->localmount = (char *)xmlStrdup (XMLSTR(buf));
             r->mp3metadata = 1;
             r->on_demand = master->on_demand;
             r->enable = 1;
             if (master->send_auth)
             {
-                r->username = xmlStrdup (master->username);
-                r->password = xmlStrdup (master->password);
+                r->username = (char *)xmlStrdup (XMLSTR(master->username));
+                r->password = (char *)xmlStrdup (XMLSTR(master->password));
             }
             r->next = master->new_relays;
             master->new_relays = r;

Modified: icecast/branches/kh/icecast/src/source.c
===================================================================
--- icecast/branches/kh/icecast/src/source.c	2006-06-13 19:49:25 UTC (rev 11567)
+++ icecast/branches/kh/icecast/src/source.c	2006-06-13 22:37:58 UTC (rev 11568)
@@ -401,14 +401,14 @@
  */
 static void update_source_stats (source_t *source)
 {
+    int     incoming_rate = 8 * rate_avg (source->format->in_bitrate);
     int64_t kbytes_sent = source->bytes_sent_since_update/1024;
     source->format->sent_bytes += kbytes_sent*1024;
     source->bytes_sent_since_update %= 1024;
 
     stats_event_args (source->mount, "outgoing_bitrate", "%ld", 
             (8 * rate_avg (source->format->out_bitrate))/1000);
-    stats_event_args (source->mount, "incoming_bitrate", "%ld", 
-            (8 * rate_avg (source->format->in_bitrate))/1000);
+    stats_event_args (source->mount, "incoming_bitrate", "%ld", incoming_rate/1000);
     stats_event_args (source->mount, "total_bytes_read",
             FORMAT_UINT64, source->format->read_bytes);
     stats_event_args (source->mount, "total_bytes_sent",
@@ -417,6 +417,42 @@
         stats_event_args (source->mount, "connected", FORMAT_UINT64,
                 (uint64_t)(global.time - source->client->con->con_time));
     stats_event_add (NULL, "stream_kbytes_sent", kbytes_sent);
+
+    if (source->running && source->limit_rate)
+    {
+        if (incoming_rate >= source->limit_rate)
+        {
+            /* when throttling, we perform a sleep so that the input is not read as quickly, we
+             * don't do precise timing here as this just makes sure the incoming bitrate is not
+             * excessive. lower bitrate stream have higher sleep counts */
+            float kbits = incoming_rate/8.0;
+            if (kbits < 1200)
+                kbits = 1200;
+            source->throttle_stream = (int)(1000000 / kbits * 1000);
+
+            /* if bitrate is consistently excessive then terminate the stream */
+            if (source->throttle_termination == 0)
+            {
+                source->throttle_termination = global.time + source->avg_bitrate_duration/2;
+                /* DEBUG1 ("throttle termination set at %ld", source->throttle_termination); */
+            }
+            else
+            {
+                if (global.time >= source->throttle_termination)
+                {
+                    source->running = 0;
+                    WARN3 ("%s terminating, exceeding bitrate limits (%dk/%dk)",
+                            source->mount, incoming_rate/1024, source->limit_rate/1024);
+                }
+            }
+        }
+        else
+        {
+            source->throttle_stream = 0;
+            source->throttle_termination = 0;
+        }
+        source->stats_interval = 2;
+    }
 }
 
 
@@ -448,6 +484,9 @@
 
         thread_mutex_unlock (&source->lock);
 
+        if (source->throttle_stream > 0)
+            thread_sleep (source->throttle_stream);
+
         if (source->client)
             fds = util_timed_wait_for_fd (source->client->con->sock, delay);
         else
@@ -462,7 +501,7 @@
         if (source->client && current >= source->client_stats_update)
         {
             update_source_stats (source);
-            source->client_stats_update = current + 5;
+            source->client_stats_update = current + source->stats_interval;
         }
         if (fds < 0)
         {
@@ -496,6 +535,7 @@
         refbuf = source->format->get_buffer (source);
         if (refbuf)
         {
+            stats_event_add (NULL, "stream_kbytes_read", refbuf->len);
             /* append buffer to the in-flight data queue,  */
             if (source->stream_data == NULL)
             {
@@ -634,6 +674,7 @@
 
             source_free_client (source, to_go);
             source->listeners--;
+            stats_event_dec (NULL, "listeners");
             DEBUG0("Client removed");
             continue;
         }
@@ -711,7 +752,10 @@
     source->last_read = global.time;
     source->prev_listeners = -1;
     source->bytes_sent_since_update = 0;
+    source->stats_interval = 5;
     source->running = 1;
+    /* so the first set of average stats after 3 seconds */
+    source->client_stats_update = global.time + 3;
 
     source->fast_clients_p = &source->active_clients;
     source->audio_info = util_dict_new();
@@ -732,7 +776,7 @@
     {
         if (mountinfo->on_connect)
             source_run_script (mountinfo->on_connect, source->mount);
-        auth_stream_start (mountinfo, source);
+        auth_stream_start (mountinfo, source->mount);
     }
     config_release_config();
 
@@ -755,6 +799,10 @@
 
         avl_tree_unlock(global.source_tree);
     }
+
+    source->format->in_bitrate = rate_setup (source->avg_bitrate_duration);
+    source->format->out_bitrate = rate_setup (source->avg_bitrate_duration);
+
     thread_mutex_lock (&source->lock);
 }
 
@@ -822,7 +870,7 @@
     {
         if (mountinfo->on_disconnect)
             source_run_script (mountinfo->on_disconnect, source->mount);
-        auth_stream_end (mountinfo, source);
+        auth_stream_end (mountinfo, source->mount);
     }
     config_release_config();
 
@@ -847,6 +895,9 @@
         avl_tree_unlock (global.source_tree);
     }
 
+    if (source->listeners)
+        stats_event_sub (NULL, "listeners", source->listeners);
+
     /* delete this sources stats */
     stats_event(source->mount, NULL, NULL);
 
@@ -1097,6 +1148,13 @@
     if (mountinfo && mountinfo->charset)
         source->charset = strdup (mountinfo->charset);
 
+    source->limit_rate = 0;
+    if (mountinfo && mountinfo->limit_rate)
+        source->limit_rate = mountinfo->limit_rate;
+
+    if (mountinfo)
+        source->avg_bitrate_duration = mountinfo->avg_bitrate_duration;
+
     /* needs a better mechanism, probably via a client_t handle */
     if (mountinfo && mountinfo->dumpfile)
     {
@@ -1143,6 +1201,10 @@
     if (mountinfo && mountinfo->fallback_when_full)
         source->fallback_when_full = mountinfo->fallback_when_full;
 
+    source->wait_time = 0;
+    if (mountinfo && mountinfo->wait_time)
+        source->wait_time = (time_t)mountinfo->wait_time;
+
     if (source->format && source->format->apply_settings)
         source->format->apply_settings (source->client, source->format, mountinfo);
 }
@@ -1221,6 +1283,14 @@
 
     source_main (source);
 
+    if (source->wait_time)
+    {
+        INFO2 ("keeping %s reserved for %d seconds", source->mount, source->wait_time);
+        source->wait_time += global.time;
+        while (global.running && source->wait_time >= global.time)
+            thread_sleep (500000);
+    }
+
     source_free_source (source);
     source_recheck_mounts ();
 
@@ -1273,7 +1343,7 @@
                     break;
                 case 0:  /* child */
                     DEBUG1 ("Starting command %s", command);
-                    execl (command, command, mountpoint, (char*)NULL);
+                    execl (command, command, mountpoint, (char *)NULL);
                     ERROR2 ("Unable to run command %s (%s)", command, strerror (errno));
                     exit(0);
                 default: /* parent */
@@ -1339,6 +1409,7 @@
         source->yp_public = 0;
         source->intro_file = file;
         source->parser = parser;
+        source->avg_bitrate_duration = 20;
         file = NULL;
 
         if (connection_complete_source (source, 0) < 0)

Modified: icecast/branches/kh/icecast/src/source.h
===================================================================
--- icecast/branches/kh/icecast/src/source.h	2006-06-13 19:49:25 UTC (rev 11567)
+++ icecast/branches/kh/icecast/src/source.h	2006-06-13 22:37:58 UTC (rev 11568)
@@ -51,6 +51,12 @@
 
     char *charset;
 
+    int throttle_stream;
+    time_t throttle_termination;
+    int limit_rate;
+    int avg_bitrate_duration;
+    time_t wait_time;
+
     unsigned long peak_listeners;
     unsigned long listeners;
     unsigned long prev_listeners;
@@ -73,6 +79,7 @@
     int on_demand_req;
     int hidden;
     uint64_t bytes_sent_since_update;
+    int stats_interval;
 
     time_t last_read;
 

Modified: icecast/branches/kh/icecast/src/stats.c
===================================================================
--- icecast/branches/kh/icecast/src/stats.c	2006-06-13 19:49:25 UTC (rev 11567)
+++ icecast/branches/kh/icecast/src/stats.c	2006-06-13 22:37:58 UTC (rev 11568)
@@ -54,8 +54,9 @@
 #define STATS_EVENT_INC     1
 #define STATS_EVENT_DEC     2
 #define STATS_EVENT_ADD     3
-#define STATS_EVENT_REMOVE  4
-#define STATS_EVENT_HIDDEN  5
+#define STATS_EVENT_SUB     4
+#define STATS_EVENT_REMOVE  5
+#define STATS_EVENT_HIDDEN  6
 
 typedef struct _event_queue_tag
 {
@@ -69,6 +70,7 @@
 {
     event_queue_t queue;
     mutex_t mutex;
+    int master;
 
     struct _event_listener_tag *next;
 } event_listener_t;
@@ -219,14 +221,18 @@
 
     if (charset)
     {
-        xmlBufferPtr raw = xmlBufferCreate ();
         xmlCharEncodingHandlerPtr handle = xmlFindCharEncodingHandler (charset);
 
-        xmlBufferPtr conv = xmlBufferCreate ();
-        xmlBufferAdd (raw, (const xmlChar *)value, strlen (value));
-        if (xmlCharEncInFunc (handle, conv, raw) > 0)
-            metadata = xmlBufferContent (conv);
-        xmlFree (raw);
+        if (handle)
+        {
+            xmlBufferPtr raw = xmlBufferCreate ();
+            xmlBufferAdd (raw, (const xmlChar *)value, strlen (value));
+            if (xmlCharEncInFunc (handle, conv, raw) > 0)
+                metadata = (char *)xmlBufferContent (conv);
+            xmlFree (raw);
+        }
+        else
+            WARN1 ("No charset found for \"%s\"", charset);
     }
 
     stats_event (mount, name, metadata);
@@ -337,6 +343,19 @@
     }
 }
 
+void stats_event_sub(const char *source, const char *name, unsigned long value)
+{
+    stats_event_t *event = build_event (source, name, NULL);
+    /* DEBUG2("%s on %s", name, source==NULL?"global":source); */
+    if (event)
+    {
+        event->value = malloc (16);
+        snprintf (event->value, 16, "%ld", value);
+        event->action = STATS_EVENT_SUB;
+        queue_global_event (event);
+    }
+}
+
 /* decrease the value in the provided stat by 1 */
 void stats_event_dec(const char *source, const char *name)
 {
@@ -450,6 +469,9 @@
             case STATS_EVENT_ADD:
                 value = atoll (node->value) + atoll (event->value);
                 break;
+            case STATS_EVENT_SUB:
+                value = atoll (node->value) - atoll (event->value);
+                break;
             default:
                 break;
         }
@@ -584,7 +606,6 @@
 static void *_stats_thread(void *arg)
 {
     stats_event_t *event;
-    stats_event_t *copy;
     event_listener_t *listener;
     ice_config_t *config = config_get_config ();
 
@@ -597,6 +618,7 @@
     stats_event (NULL, "connections", "0");
     stats_event (NULL, "sources", "0");
     stats_event (NULL, "stats", "0");
+    stats_event (NULL, "listeners", "0");
 
     /* global accumulating stats */
     stats_event (NULL, "client_connections", "0");
@@ -627,12 +649,24 @@
             /* now we have an event that's been processed into the running stats */
             /* this event should get copied to event listeners' queues */
             listener = (event_listener_t *)_event_listeners;
-            while (listener) {
-                copy = _copy_event(event);
-                thread_mutex_lock (&listener->mutex);
-                _add_event_to_queue (copy, &listener->queue);
-                thread_mutex_unlock (&listener->mutex);
+            while (listener)
+            {
+                int send_it = 1;
+                if (listener->master && event->name)
+                {
+                    if (strcmp (event->name, "total_listeners") != 0 &&
+                            strcmp (event->name, "total_max_listeners") != 0)
+                        send_it = 0;
 
+                }
+                if (send_it)
+                {
+                    stats_event_t *copy = _copy_event(event);
+                    thread_mutex_lock (&listener->mutex);
+                    _add_event_to_queue (copy, &listener->queue);
+                    thread_mutex_unlock (&listener->mutex);
+                }
+
                 listener = listener->next;
             }
 
@@ -825,6 +859,9 @@
 
     thread_mutex_create("stats local event", &listener.mutex);
 
+    if (strcmp (httpp_getvar (client->parser, HTTPP_VAR_URI), "/admin/slave") == 0)
+        listener.master = 1;
+
     _register_listener (&listener);
 
     while (_stats_running) {
@@ -897,8 +934,8 @@
     /* build node */
     node = (source_xml_t *)malloc(sizeof(source_xml_t));
     node->mount = strdup(mount);
-    node->node = xmlNewChild(root, NULL, "source", NULL);
-    xmlSetProp(node->node, "mount", mount);
+    node->node = xmlNewChild(root, NULL, XMLSTR("source"), NULL);
+    xmlSetProp(node->node, XMLSTR("mount"), XMLSTR(mount));
     node->next = NULL;
 
     /* add node */
@@ -937,8 +974,8 @@
     event_queue_init (&queue);
     _dump_stats_to_queue (&queue);
 
-    *doc = xmlNewDoc("1.0");
-    node = xmlNewDocNode(*doc, NULL, "icestats", NULL);
+    *doc = xmlNewDoc (XMLSTR("1.0"));
+    node = xmlNewDocNode (*doc, NULL, XMLSTR("icestats"), NULL);
     xmlDocSetRootElement(*doc, node);
 
     event = _get_event_from_queue(&queue);
@@ -947,8 +984,8 @@
         if (event->hidden <= show_hidden)
         {
             xmlChar *name, *value;
-            name = xmlEncodeEntitiesReentrant (*doc, event->name);
-            value = xmlEncodeEntitiesReentrant (*doc, event->value);
+            name = xmlEncodeEntitiesReentrant (*doc, XMLSTR(event->name));
+            value = xmlEncodeEntitiesReentrant (*doc, XMLSTR(event->value));
             srcnode = node;
             if (event->source) {
                 srcnode = _find_xml_node(event->source, &src_nodes, node);

Modified: icecast/branches/kh/icecast/src/stats.h
===================================================================
--- icecast/branches/kh/icecast/src/stats.h	2006-06-13 19:49:25 UTC (rev 11567)
+++ icecast/branches/kh/icecast/src/stats.h	2006-06-13 22:37:58 UTC (rev 11568)
@@ -81,6 +81,7 @@
 void stats_event_args(const char *source, char *name, char *format, ...);
 void stats_event_inc(const char *source, const char *name);
 void stats_event_add(const char *source, const char *name, unsigned long value);
+void stats_event_sub(const char *source, const char *name, unsigned long value);
 void stats_event_dec(const char *source, const char *name);
 void stats_event_hidden (const char *source, const char *name, int hidden);
 void stats_event_time (const char *mount, const char *name);

Modified: icecast/branches/kh/icecast/src/util.c
===================================================================
--- icecast/branches/kh/icecast/src/util.c	2006-06-13 19:49:25 UTC (rev 11567)
+++ icecast/branches/kh/icecast/src/util.c	2006-06-13 22:37:58 UTC (rev 11568)
@@ -52,7 +52,7 @@
 {
     time_t time;
     long value;
-    struct rate_calc_node *next;
+    struct rate_calc_node *next, *prev;
 };
 
 struct rate_calc
@@ -667,12 +667,17 @@
     {
         struct rate_calc_node *node = calloc (1, sizeof (*node));
         if (calc->current)
+        {
             calc->current->next = node;
+            node->next = start;
+        }
         else
             start = node;
+        node->prev = calc->current;
         calc->current = node;
     }
     calc->current->next = start;
+    start->prev = calc->current;
     calc->seconds = seconds;
     return calc;
 }
@@ -715,7 +720,7 @@
     for (; i; i--)
     {
         total += node->value;
-        node = node->next;
+        node = node->prev;
     }
     return total / (calc->blocks - 1);
 }

Modified: icecast/branches/kh/icecast/src/xslt.c
===================================================================
--- icecast/branches/kh/icecast/src/xslt.c	2006-06-13 19:49:25 UTC (rev 11567)
+++ icecast/branches/kh/icecast/src/xslt.c	2006-06-13 22:37:58 UTC (rev 11568)
@@ -216,10 +216,10 @@
     else
     {
         /* check method for the default, a missing method assumes xml */
-        if (cur->method && xmlStrcmp (cur->method, "html") == 0)
+        if (cur->method && xmlStrcmp (cur->method, XMLSTR("html")) == 0)
             mediatype = "text/html";
         else
-            if (cur->method && xmlStrcmp (cur->method, "text") == 0)
+            if (cur->method && xmlStrcmp (cur->method, XMLSTR("text")) == 0)
                 mediatype = "text/plain";
             else
                 mediatype = "text/xml";
@@ -231,7 +231,7 @@
         refbuf_t *refbuf = refbuf_new (header_len);
 
         if (string == NULL)
-            string = xmlStrdup ("");
+            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);

Modified: icecast/branches/kh/icecast/src/yp.c
===================================================================
--- icecast/branches/kh/icecast/src/yp.c	2006-06-13 19:49:25 UTC (rev 11567)
+++ icecast/branches/kh/icecast/src/yp.c	2006-06-13 22:37:58 UTC (rev 11568)
@@ -218,7 +218,7 @@
         server = server->next;
     }
     client_limit = config->client_limit;
-    free (server_version);
+    free ((char*)server_version);
     server_version = strdup (config->server_id);
     /* for each yp url in config, check to see if one exists 
        if not, then add it. */
@@ -932,7 +932,7 @@
     if (yp_thread)
         thread_join (yp_thread);
     curl_global_cleanup();
-    free (server_version);
+    free ((char*)server_version);
     server_version = NULL;
     INFO0 ("YP thread down");
 }



More information about the commits mailing list