[xiph-commits] r15865 - in icecast/branches/kh/icecast: . admin src win32
karl at svn.xiph.org
karl at svn.xiph.org
Fri Mar 27 16:12:53 PDT 2009
Author: karl
Date: 2009-03-27 16:12:53 -0700 (Fri, 27 Mar 2009)
New Revision: 15865
Modified:
icecast/branches/kh/icecast/NEWS
icecast/branches/kh/icecast/admin/xspf.xsl
icecast/branches/kh/icecast/config.h.vc6
icecast/branches/kh/icecast/configure.in
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/auth_url.c
icecast/branches/kh/icecast/src/cfgfile.c
icecast/branches/kh/icecast/src/client.c
icecast/branches/kh/icecast/src/connection.c
icecast/branches/kh/icecast/src/connection.h
icecast/branches/kh/icecast/src/format_mp3.c
icecast/branches/kh/icecast/src/format_ogg.c
icecast/branches/kh/icecast/src/format_vorbis.c
icecast/branches/kh/icecast/src/fserve.c
icecast/branches/kh/icecast/src/global.c
icecast/branches/kh/icecast/src/global.h
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/util.c
icecast/branches/kh/icecast/src/util.h
icecast/branches/kh/icecast/src/xslt.c
icecast/branches/kh/icecast/src/yp.c
icecast/branches/kh/icecast/win32/icecast2.iss
Log:
bump to kh9, mainly internals cleanups to help sync with trunk
Modified: icecast/branches/kh/icecast/NEWS
===================================================================
--- icecast/branches/kh/icecast/NEWS 2009-03-27 23:09:45 UTC (rev 15864)
+++ icecast/branches/kh/icecast/NEWS 2009-03-27 23:12:53 UTC (rev 15865)
@@ -10,11 +10,24 @@
max-listener/bandwidth check. slaves can use a different auth to listeners
. mount can filter out theora content, useful for defining a local relay
of a theora+vorbis stream to have a vorbis only stream from the same source.
-. stream-auth/handlers options for url authenticator.
+. handlers options for url authenticator.
any extra tags are show in the conf/icecast.xml.dist file
+2.3.2-kh9
+. allow shoutcast source client auth work via stream_auth url
+. allow for a flash policy file.
+. internal cleanup to help merging into trunk
+. fix vorbis metadata update via url, broken in recent releases. cleanup some metadata
+ updating/logging
+. drop vorbis stream rebuilding back to flush evert half second, in sync with trunk
+. stop false reports of 'not null' in debug logging. no other effect on server
+. limit how often the relay mountpoint "already exists" logs.
+. minor tweaking to the average bitrate calculation
+. remove the internal global time caching, although prevent several time calls if in
+ succession.
+
2.3.2-kh8
. fix memory corruption which affected ogg streams.
. fix for unsupported FBSD/win32 spin locking options. abort on initialisation failure.
Modified: icecast/branches/kh/icecast/admin/xspf.xsl
===================================================================
--- icecast/branches/kh/icecast/admin/xspf.xsl 2009-03-27 23:09:45 UTC (rev 15864)
+++ icecast/branches/kh/icecast/admin/xspf.xsl 2009-03-27 23:12:53 UTC (rev 15865)
@@ -1,5 +1,5 @@
<!--
- XSPF xslt stylesheet for Icecast 2.3.1 and above
+ XSPF xslt stylesheet for Icecast 2.3.2 and above
Copyright (C) 2007 Thomas B. Ruecker, tbr at ruecker-itk.de
This program is free software; you can redistribute it and/or
Modified: icecast/branches/kh/icecast/config.h.vc6
===================================================================
--- icecast/branches/kh/icecast/config.h.vc6 2009-03-27 23:09:45 UTC (rev 15864)
+++ icecast/branches/kh/icecast/config.h.vc6 2009-03-27 23:12:53 UTC (rev 15865)
@@ -95,7 +95,7 @@
#define PACKAGE_NAME "Icecast"
/* Version number of package */
-#define VERSION "2.3.2-kh8"
+#define VERSION "2.3.2-kh9"
/* Define to the version of this package. */
#define PACKAGE_VERSION VERSION
Modified: icecast/branches/kh/icecast/configure.in
===================================================================
--- icecast/branches/kh/icecast/configure.in 2009-03-27 23:09:45 UTC (rev 15864)
+++ icecast/branches/kh/icecast/configure.in 2009-03-27 23:12:53 UTC (rev 15865)
@@ -1,4 +1,4 @@
-AC_INIT([Icecast], [2.3.2-kh8], [karl at xiph.org])
+AC_INIT([Icecast], [2.3.2-kh9], [karl at xiph.org])
AC_PREREQ(2.59)
AC_CONFIG_SRCDIR(src/main.c)
@@ -44,7 +44,7 @@
AC_TYPE_OFF_T
dnl Checks for library functions.
-AC_CHECK_FUNCS([localtime_r poll atoll strtoll getrlimit gettimeofday ftime])
+AC_CHECK_FUNCS([localtime_r poll atoll strtoll getrlimit gettimeofday ftime fstat])
AC_SEARCH_LIBS(nanosleep, rt posix4,
AC_DEFINE(HAVE_NANOSLEEP, 1, [Define if you have nanosleep]))
XIPH_NET
Modified: icecast/branches/kh/icecast/src/admin.c
===================================================================
--- icecast/branches/kh/icecast/src/admin.c 2009-03-27 23:09:45 UTC (rev 15864)
+++ icecast/branches/kh/icecast/src/admin.c 2009-03-27 23:12:53 UTC (rev 15865)
@@ -82,6 +82,7 @@
};
+static time_t now;
static struct admin_command admin_general[] =
{
@@ -365,7 +366,7 @@
/* This is a mount request, but admin user is allowed */
if (client->authenticated == 0)
{
- switch (connection_check_source_pass (client, mount))
+ switch (auth_check_source (client, mount))
{
case 0:
break;
@@ -649,7 +650,7 @@
xmlNewChild (node, NULL, XMLSTR("lag"), XMLSTR(buf));
snprintf (buf, sizeof (buf), "%lu",
- (unsigned long)(global.time - listener->con->con_time));
+ (unsigned long)(now - listener->con->con_time));
xmlNewChild (node, NULL, XMLSTR("connected"), XMLSTR(buf));
if (listener->username)
{
@@ -672,6 +673,7 @@
thread_mutex_lock (&source->lock);
+ now = time(NULL);
listener = source->active_clients;
while (listener)
{
@@ -752,6 +754,7 @@
client_t *listener;
thread_mutex_lock (&source->lock);
+ now = time(NULL);
listener = source->active_clients;
while (listener)
{
@@ -1028,18 +1031,18 @@
if (song)
{
plugin->set_tag (plugin, "song", song, charset);
- INFO2("Metadata on mountpoint %s changed to \"%s\"", source->mount, song);
+ INFO2("Metadata song on mountpoint %s changed to \"%s\"", source->mount, song);
}
- else
+ if (artist)
{
- if (artist && title)
- {
- plugin->set_tag (plugin, "title", title, charset);
- plugin->set_tag (plugin, "artist", artist, charset);
- INFO3("Metadata on mountpoint %s changed to \"%s - %s\"",
- source->mount, artist, title);
- }
+ plugin->set_tag (plugin, "artist", artist, charset);
+ INFO2 ("Metadata artist on mountpoint %s changed to \"%s\"", source->mount, artist);
}
+ if (title)
+ {
+ plugin->set_tag (plugin, "title", title, charset);
+ INFO2 ("Metadata title on mountpoint %s changed to \"%s\"", source->mount, title);
+ }
/* updates are now done, let them be pushed into the stream */
plugin->set_tag (plugin, NULL, NULL, NULL);
}
@@ -1092,7 +1095,7 @@
if (connection_check_admin_pass (client->parser) == 0)
same_ip = 0;
- if (source->format && source->format->set_tag)
+ if (same_ip && source->format && source->format->set_tag)
{
httpp_set_query_param (client->parser, "mount", client->server_conn->shoutcast_mount);
source->format->set_tag (source->format, "title", value, NULL);
Modified: icecast/branches/kh/icecast/src/auth.c
===================================================================
--- icecast/branches/kh/icecast/src/auth.c 2009-03-27 23:09:45 UTC (rev 15864)
+++ icecast/branches/kh/icecast/src/auth.c 2009-03-27 23:12:53 UTC (rev 15865)
@@ -39,11 +39,11 @@
#define CATMODULE "auth"
-static spin_t auth_lock;
static volatile int thread_id;
static void *auth_run_thread (void *arg);
-static int auth_postprocess_listener (auth_client *auth_user);
+static int auth_postprocess_listener (auth_client *auth_user);
+static void auth_postprocess_source (auth_client *auth_user);
void auth_check_http (client_t *client)
@@ -463,7 +463,7 @@
/* set a per-mount disconnect time if auth hasn't set one already */
if (mountinfo->max_listener_duration && client->con->discon_time == 0)
- client->con->discon_time = global.time + mountinfo->max_listener_duration;
+ client->con->discon_time = time(NULL) + mountinfo->max_listener_duration;
INFO3 ("max on %s is %ld (cur %lu)", source->mount,
mountinfo->max_listeners, source->listeners);
@@ -636,7 +636,7 @@
else
{
DEBUG1 ("on mountpoint %s", mount);
- source_startup (client, mount, 0);
+ source_startup (client, mount);
}
}
@@ -827,7 +827,7 @@
else
{
auth->tailp = &auth->head;
- thread_mutex_create ("auth_t", &auth->lock);
+ thread_mutex_create (&auth->lock);
/* allocate N threads */
auth->handles = calloc (auth->handlers, sizeof (auth_thread_t));
@@ -906,17 +906,46 @@
}
+/* return -1 for failed, 0 for authenticated, 1 for pending
+ */
+int auth_check_source (client_t *client, const char *mount)
+{
+ ice_config_t *config = config_get_config();
+ char *pass = config->source_password;
+ char *user = "source";
+ int ret = -1;
+ mount_proxy *mountinfo = config_find_mount (config, mount);
+
+ do
+ {
+ if (mountinfo)
+ {
+ ret = 1;
+ if (auth_stream_authenticate (client, mount, mountinfo) > 0)
+ break;
+ ret = -1;
+ if (mountinfo->password)
+ pass = mountinfo->password;
+ if (mountinfo->username)
+ user = mountinfo->username;
+ }
+ if (connection_check_pass (client->parser, user, pass) > 0)
+ ret = 0;
+ } while (0);
+ config_release_config();
+ return ret;
+}
+
+
/* these are called at server start and termination */
void auth_initialise (void)
{
- thread_spin_create ("auth lock", &auth_lock);
thread_id = 0;
}
void auth_shutdown (void)
{
- thread_spin_destroy (&auth_lock);
INFO0 ("Auth shutdown");
}
Modified: icecast/branches/kh/icecast/src/auth.h
===================================================================
--- icecast/branches/kh/icecast/src/auth.h 2009-03-27 23:09:45 UTC (rev 15864)
+++ icecast/branches/kh/icecast/src/auth.h 2009-03-27 23:12:53 UTC (rev 15865)
@@ -114,6 +114,7 @@
void auth_add_listener (const char *mount, client_t *client);
int auth_release_listener (client_t *client, const char *mount, struct _mount_proxy *mountinfo);
+int auth_check_source (client_t *client, const char *mount);
void auth_initialise (void);
void auth_shutdown (void);
@@ -121,19 +122,15 @@
int auth_get_authenticator (xmlNodePtr node, void *x);
void auth_release (auth_t *authenticator);
-/* call to send a url request when source starts */
+/* call to trigger an event when a stream starts */
void auth_stream_start (struct _mount_proxy *mountinfo, const char *mount);
-/* call to send a url request when source ends */
+/* call to trigger an event when a stream ends */
void auth_stream_end (struct _mount_proxy *mountinfo, const char *mount);
-/* */
-int auth_stream_authenticate (client_t *client, const char *mount,
- struct _mount_proxy *mountinfo);
+/* call to trigger an event to authenticate a source client */
+int auth_stream_authenticate (client_t *client, const char *mount, struct _mount_proxy *mountinfo);
-/* called from auth thread */
-void auth_postprocess_source (auth_client *auth_user);
-
void auth_check_http (client_t *client);
#endif
Modified: icecast/branches/kh/icecast/src/auth_htpasswd.c
===================================================================
--- icecast/branches/kh/icecast/src/auth_htpasswd.c 2009-03-27 23:09:45 UTC (rev 15864)
+++ icecast/branches/kh/icecast/src/auth_htpasswd.c 2009-03-27 23:12:53 UTC (rev 15865)
@@ -352,6 +352,10 @@
}
}
+#ifdef HAVE_FSYNC
+ fflush (tmp_passwdfile);
+ fsync (fileno (tmp_passwdfile));
+#endif
fclose(tmp_passwdfile);
fclose(passwdfile);
Modified: icecast/branches/kh/icecast/src/auth_url.c
===================================================================
--- icecast/branches/kh/icecast/src/auth_url.c 2009-03-27 23:09:45 UTC (rev 15864)
+++ icecast/branches/kh/icecast/src/auth_url.c 2009-03-27 23:12:53 UTC (rev 15865)
@@ -174,7 +174,7 @@
{
unsigned int limit = 0;
sscanf ((char *)ptr+url->timelimit_header_len, "%u\r\n", &limit);
- client->con->discon_time = global.time + limit;
+ client->con->discon_time = time(NULL) + limit;
}
if (strncasecmp (ptr, "icecast-slave: 1", 16) == 0)
client->is_slave =1;
@@ -218,7 +218,7 @@
client_t *client = auth_user->client;
auth_url *url = auth_user->auth->state;
auth_thread_data *atd = auth_user->thread_data;
- time_t duration = global.time - client->con->con_time;
+ time_t duration = time(NULL) - client->con->con_time;
char *username, *password, *mount, *server, *ipaddr;
const char *qargs;
char *userpwd = NULL, post [4096];
Modified: icecast/branches/kh/icecast/src/cfgfile.c
===================================================================
--- icecast/branches/kh/icecast/src/cfgfile.c 2009-03-27 23:09:45 UTC (rev 15864)
+++ icecast/branches/kh/icecast/src/cfgfile.c 2009-03-27 23:12:53 UTC (rev 15865)
@@ -76,7 +76,7 @@
static int _parse_root (xmlNodePtr node, ice_config_t *config);
static void create_locks(void) {
- thread_mutex_create("relay", &_locks.relay_lock);
+ thread_mutex_create(&_locks.relay_lock);
thread_rwlock_create(&_locks.config_lock);
}
Modified: icecast/branches/kh/icecast/src/client.c
===================================================================
--- icecast/branches/kh/icecast/src/client.c 2009-03-27 23:09:45 UTC (rev 15864)
+++ icecast/branches/kh/icecast/src/client.c 2009-03-27 23:12:53 UTC (rev 15865)
@@ -101,16 +101,6 @@
if (client->respcode && client->parser)
logging_access(client);
-#ifdef HAVE_AIO
- if (aio_cancel (client->con->sock, NULL) == AIO_NOTCANCELED)
- {
- const struct aiocb *list = &client->aio;
- INFO0 ("having to wait for aio cancellation");
- while (aio_suspend (&list, 1, NULL) < 0)
- ;
- }
-#endif
-
if (client->con)
connection_close(client->con);
if (client->parser)
Modified: icecast/branches/kh/icecast/src/connection.c
===================================================================
--- icecast/branches/kh/icecast/src/connection.c 2009-03-27 23:09:45 UTC (rev 15864)
+++ icecast/branches/kh/icecast/src/connection.c 2009-03-27 23:12:53 UTC (rev 15865)
@@ -76,8 +76,6 @@
Icecast auth style uses HTTP and Basic Authorization.
*/
-#define SHOUTCAST_SOURCE_AUTH 1
-#define ICECAST_SOURCE_AUTH 0
typedef struct client_queue_tag {
client_t *client;
@@ -100,7 +98,8 @@
avl_tree *contents;
} cache_file_contents;
-static spin_t _connection_mutex;
+static time_t now;
+static spin_t _connection_lock;
static volatile unsigned long _current_id = 0;
static volatile thread_type *conn_tid;
@@ -117,9 +116,9 @@
cache_file_contents useragents;
int connection_running = 0;
+rwlock_t _source_shutdown_rwlock;
static void _handle_connection(void);
-static int check_pass(http_parser_t *parser, const char *user, const char *pass);
static int compare_line (void *arg, void *a, void *b)
{
@@ -154,8 +153,9 @@
void connection_initialize(void)
{
- thread_spin_create("connection", &_connection_mutex);
- thread_mutex_create("move_clients", &move_clients_mutex);
+ thread_spin_create (&_connection_lock);
+ thread_mutex_create(&move_clients_mutex);
+ thread_rwlock_create(&_source_shutdown_rwlock);
thread_cond_create(&global.shutdown_cond);
_req_queue = NULL;
_req_queue_tail = &_req_queue;
@@ -183,7 +183,10 @@
if (useragents.contents) avl_tree_free (useragents.contents, free_filtered_line);
thread_cond_destroy(&global.shutdown_cond);
- thread_spin_destroy(&_connection_mutex);
+ thread_rwlock_wlock(&_source_shutdown_rwlock);
+ thread_rwlock_unlock(&_source_shutdown_rwlock);
+ thread_rwlock_destroy(&_source_shutdown_rwlock);
+ thread_spin_destroy (&_connection_lock);
thread_mutex_destroy(&move_clients_mutex);
}
@@ -191,9 +194,9 @@
{
unsigned long id;
- thread_spin_lock(&_connection_mutex);
+ thread_spin_lock (&_connection_lock);
id = _current_id++;
- thread_spin_unlock(&_connection_mutex);
+ thread_spin_unlock (&_connection_lock);
return id;
}
@@ -314,7 +317,7 @@
*/
static void recheck_cached_file (cache_file_contents *cache)
{
- if (global.time >= cache->file_recheck)
+ if (now >= cache->file_recheck)
{
struct stat file_stat;
FILE *file = NULL;
@@ -322,7 +325,7 @@
avl_tree *new_ips;
char line [MAX_LINE_LEN];
- cache->file_recheck = global.time + 10;
+ cache->file_recheck = now + 10;
if (cache->filename == NULL)
{
if (cache->contents)
@@ -413,7 +416,7 @@
con->serversock = serversock;
con->read = connection_read;
con->send = connection_send;
- con->con_time = global.time;
+ con->con_time = time(NULL);
con->id = _next_connection_id();
con->ip = ip;
}
@@ -525,6 +528,7 @@
if (serversock == SOCK_ERROR)
return NULL;
+ now = time(NULL);
/* malloc enough room for a full IP address (including ipv6) */
ip = (char *)malloc(MAX_ADDR_LEN);
@@ -603,7 +607,7 @@
if (len > 0)
{
- if (client->con->con_time + timeout <= global.time)
+ if (client->con->con_time + timeout <= now)
len = 0;
else
len = client_read_bytes (client, buf, len);
@@ -620,6 +624,10 @@
client->refbuf->data [node->offset] = '\000';
do
{
+ /* ugly hack for flash policy files */
+ if (node->offset == 23 && memcmp (client->refbuf->data, "<policy-file-request/>", 23) == 0)
+ break;
+
if (node->shoutcast == 1)
{
/* password line */
@@ -699,12 +707,6 @@
if (client->server_conn->shoutcast_compat)
node->shoutcast = 1;
- if (sock_set_blocking (client->con->sock, 0) || sock_set_nodelay (client->con->sock))
- {
- WARN0 ("failed to set tcp options on client connection, dropping");
- client->con->error = 1;
- }
-
return node;
}
@@ -743,6 +745,13 @@
/* setup client for reading incoming http */
client->refbuf->data [PER_CLIENT_REFBUF_SIZE-1] = '\000';
+ if (sock_set_blocking (client->con->sock, 0) || sock_set_nodelay (client->con->sock))
+ {
+ WARN0 ("failed to set tcp options on client connection, dropping");
+ client_destroy (client);
+ continue;
+ }
+
node = _create_req_node (client);
if (node == NULL)
{
@@ -858,6 +867,7 @@
config_release_config();
slave_rebuild_mounts();
+ source->shutdown_rwlock = &_source_shutdown_rwlock;
DEBUG0 ("source is ready to start");
return 0;
@@ -984,40 +994,10 @@
return ret;
}
-/* return -1 for failed, 0 for authenticated, 1 for pending
- */
-int connection_check_source_pass (client_t *client, const char *mount)
-{
- ice_config_t *config = config_get_config();
- mount_proxy *mountinfo;
- char *pass = config->source_password;
- char *user = "source";
- int ret = -1;
- mountinfo = config_find_mount (config, mount);
- do
- {
- if (mountinfo)
- {
- ret = 1;
- if (auth_stream_authenticate (client, mount, mountinfo) > 0)
- break;
- ret = -1;
- if (mountinfo->password)
- pass = mountinfo->password;
- if (mountinfo->username)
- user = mountinfo->username;
- }
- if (check_pass (client->parser, user, pass) > 0)
- ret = 0;
- } while (0);
- config_release_config();
- return ret;
-}
-
/* return 0 for failed, 1 for ok
*/
-static int check_pass (http_parser_t *parser, const char *user, const char *pass)
+int connection_check_pass (http_parser_t *parser, const char *user, const char *pass)
{
int ret;
const char *protocol;
@@ -1058,65 +1038,23 @@
client_send_401 (client, NULL);
return;
}
- switch (connection_check_source_pass (client, uri))
+ switch (auth_check_source (client, uri))
{
case 0: /* authenticated from config file */
- source_startup (client, uri, ICECAST_SOURCE_AUTH);
+ source_startup (client, uri);
break;
case 1: /* auth pending */
break;
default: /* failed */
- /* We commonly get this if the source client is using the wrong
- * protocol: attempt to diagnose this and return an error
- */
- /* TODO: Do what the above comment says */
INFO1("Source (%s) attempted to login with invalid or missing password", uri);
client_send_401 (client, NULL);
break;
}
}
-void source_startup (client_t *client, const char *uri, int auth_style)
-{
- source_t *source;
- source = source_reserve (uri);
-
- if (source)
- {
- source->client = client;
- source->parser = client->parser;
- if (connection_complete_source (source, 1) < 0)
- {
- source_clear_source (source);
- source_free_source (source);
- return;
- }
- client->respcode = 200;
- if (auth_style == SHOUTCAST_SOURCE_AUTH)
- {
- source->shoutcast_compat = 1;
- source_client_callback (client, source);
- }
- else
- {
- refbuf_t *ok = refbuf_new (PER_CLIENT_REFBUF_SIZE);
- snprintf (ok->data, PER_CLIENT_REFBUF_SIZE,
- "HTTP/1.0 200 OK\r\n\r\n");
- ok->len = strlen (ok->data);
- /* we may have unprocessed data read in, so don't overwrite it */
- ok->associated = client->refbuf;
- client->refbuf = ok;
- fserve_add_client_callback (client, source_client_callback, source);
- }
- return;
- }
- client_send_403 (client, "Mountpoint in use");
- WARN1 ("Mountpoint %s in use", uri);
-}
-
static void _handle_stats_request (client_t *client, char *uri)
{
if (connection_check_admin_pass (client->parser) == 0)
@@ -1219,104 +1157,40 @@
static void _handle_shoutcast_compatible (client_queue_t *node)
{
- char *http_compliant;
- int http_compliant_len = 0;
- http_parser_t *parser;
ice_config_t *config = config_get_config ();
client_t *client = node->client;
listener_t *server_conn = client->server_conn;
- if (node->shoutcast == 1)
- {
- char *source_password, *ptr, *headers;
- mount_proxy *mountinfo = config_find_mount (config, server_conn->shoutcast_mount);
+ char *user = "source", *ptr, *headers, *esc_header;
+ mount_proxy *mountinfo = config_find_mount (config, server_conn->shoutcast_mount);
+ refbuf_t *r;
+ int len;
+ char auth [256];
- if (mountinfo && mountinfo->password)
- source_password = strdup (mountinfo->password);
- else
- source_password = strdup (config->source_password);
- config_release_config();
+ if (mountinfo && mountinfo->username)
+ user = mountinfo->username;
- /* Get rid of trailing \r\n or \n after password */
- ptr = strstr (client->refbuf->data, "\r\r\n");
- if (ptr)
- headers = ptr+3;
- else
- {
- ptr = strstr (client->refbuf->data, "\r\n");
- if (ptr)
- headers = ptr+2;
- else
- {
- ptr = strstr (client->refbuf->data, "\n");
- if (ptr)
- headers = ptr+1;
- }
- }
-
- if (ptr == NULL)
- {
- client_destroy (client);
- free (source_password);
- free (node);
- return;
- }
- *ptr = '\0';
-
- if (strcmp (client->refbuf->data, source_password) == 0)
- {
- client->respcode = 200;
- /* send this non-blocking but if there is only a partial write
- * then leave to header timeout */
- sock_write (client->con->sock, "OK2\r\nicy-caps:11\r\n\r\n");
- node->offset -= (headers - client->refbuf->data);
- memmove (client->refbuf->data, headers, node->offset+1);
- node->shoutcast = 2;
- /* we've checked the password, now send it back for reading headers */
- _add_request_queue (node);
- free (source_password);
- return;
- }
- else
- INFO1 ("password does not match \"%s\"", client->refbuf->data);
- client_destroy (client);
- free (source_password);
- free (node);
- return;
- }
- /* actually make a copy as we are dropping the config lock */
+ ptr = client->refbuf->data;
+ len = strcspn (ptr, "\r\n");
+ snprintf (auth, sizeof auth, "%s:%.*s", user, len, ptr);
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
- means we can use some of our existing code to handle this case */
- http_compliant_len = 20 + strlen (server_conn->shoutcast_mount) + node->offset;
- http_compliant = (char *)calloc(1, http_compliant_len);
- snprintf (http_compliant, http_compliant_len,
- "SOURCE %s HTTP/1.0\r\n%s", server_conn->shoutcast_mount, client->refbuf->data);
- parser = httpp_create_parser();
- httpp_initialize (parser, NULL);
- if (httpp_parse (parser, http_compliant, strlen(http_compliant)))
- {
- /* we may have more than just headers, so prepare for it */
- if (node->stream_offset == node->offset)
- client->refbuf->len = 0;
- else
- {
- char *ptr = client->refbuf->data;
- client->refbuf->len = node->offset - node->stream_offset;
- memmove (ptr, ptr + node->stream_offset, client->refbuf->len);
- }
- client->parser = parser;
- source_startup (client, server_conn->shoutcast_mount, SHOUTCAST_SOURCE_AUTH);
- }
- else
- {
- httpp_destroy (parser);
- client_destroy (client);
- }
- free (http_compliant);
- free (node);
- return;
+ ptr += len;
+ headers = ptr + strspn (ptr, "\r\n");
+
+ esc_header = util_base64_encode (auth);
+ sock_write (client->con->sock, "OK2\r\nicy-caps:11\r\n\r\n");
+ /* build a buffer in a way that an icecast2 source client would present as */
+ r = refbuf_new (PER_CLIENT_REFBUF_SIZE);
+ snprintf (r->data, PER_CLIENT_REFBUF_SIZE,
+ "SOURCE %s HTTP/1.0\r\n" "Authorization: Basic %s\r\n%s",
+ server_conn->shoutcast_mount, esc_header, headers);
+ free (esc_header);
+ refbuf_release (client->refbuf);
+ client->refbuf = r;
+ r->len = 0;
+ node->shoutcast = 0;
+ node->offset = strlen (r->data);
+ _add_request_queue (node);
}
@@ -1337,6 +1211,13 @@
{
client_t *client = node->client;
+ if (node->offset == 23 && memcmp (client->refbuf->data, "<policy-file-request/>", 23) == 0)
+ {
+ client->respcode = 200;
+ fserve_client_create (client, "/flashpolicy");
+ free (node);
+ continue;
+ }
/* Check for special shoutcast compatability processing */
if (node->shoutcast)
{
Modified: icecast/branches/kh/icecast/src/connection.h
===================================================================
--- icecast/branches/kh/icecast/src/connection.h 2009-03-27 23:09:45 UTC (rev 15864)
+++ icecast/branches/kh/icecast/src/connection.h 2009-03-27 23:12:53 UTC (rev 15865)
@@ -24,7 +24,6 @@
typedef struct connection_tag connection_t;
#include "cfgfile.h"
-#include "client.h"
#include "compat.h"
#include "httpp/httpp.h"
#include "thread/thread.h"
@@ -68,7 +67,7 @@
void connection_uses_ssl (connection_t *con);
void connection_thread_shutdown_req (void);
-int connection_check_source_pass (client_t *client, const char *mount);
+int connection_check_pass (http_parser_t *parser, const char *user, const char *pass);
int connection_check_relay_pass(http_parser_t *parser);
int connection_check_admin_pass(http_parser_t *parser);
Modified: icecast/branches/kh/icecast/src/format_mp3.c
===================================================================
--- icecast/branches/kh/icecast/src/format_mp3.c 2009-03-27 23:09:45 UTC (rev 15864)
+++ icecast/branches/kh/icecast/src/format_mp3.c 2009-03-27 23:12:53 UTC (rev 15865)
@@ -76,6 +76,7 @@
plugin = (format_plugin_t *)calloc(1, sizeof(format_plugin_t));
+ plugin->mount = source->mount;
plugin->type = FORMAT_TYPE_GENERIC;
plugin->get_buffer = mp3_get_no_meta;
plugin->write_buf_to_client = format_mp3_write_buf_to_client;
@@ -112,7 +113,7 @@
}
}
source->format = plugin;
- thread_mutex_create ("mp3 url lock", &state->url_lock);
+ thread_mutex_create (&state->url_lock);
return 0;
}
@@ -142,13 +143,22 @@
if (strcmp (tag, "title") == 0 || strcmp (tag, "song") == 0)
{
+ if (*tag == 's')
+ {
+ /* song typically includes artist */
+ free (source_mp3->url_artist);
+ source_mp3->url_artist = NULL;
+ stats_event (plugin->mount, "artist", NULL);
+ }
free (source_mp3->url_title);
source_mp3->url_title = value;
+ stats_event (plugin->mount, "title", value);
}
else if (strcmp (tag, "artist") == 0)
{
free (source_mp3->url_artist);
source_mp3->url_artist = value;
+ stats_event (plugin->mount, "artist", value);
}
else if (strcmp (tag, "url") == 0)
{
@@ -161,33 +171,27 @@
}
-static void filter_shoutcast_metadata (source_t *source, char *metadata, size_t meta_len)
+static char *filter_shoutcast_metadata (source_t *source, char *metadata, size_t meta_len)
{
- if (metadata)
+ char *p = NULL;
+ char *end;
+ int len;
+
+ do
{
- char *end, *p;
- int len;
-
- do
- {
- metadata++;
- if (strncmp (metadata, "StreamTitle='", 13))
- break;
- if ((end = strstr (metadata+13, "\';")) == NULL)
- break;
- len = (end - metadata) - 13;
- p = calloc (1, len+1);
- if (p)
- {
- memcpy (p, metadata+13, len);
-
- stats_event_conv (source->mount, "title", p, source->format->charset);
-
- yp_touch (source->mount);
- free (p);
- }
- } while (0);
- }
+ if (metadata == NULL)
+ break;
+ metadata++;
+ if (strncmp (metadata, "StreamTitle='", 13))
+ break;
+ if ((end = strstr (metadata+13, "\';")) == NULL)
+ break;
+ len = (end - metadata) - 13;
+ p = calloc (1, len+1);
+ if (p)
+ memcpy (p, metadata+13, len);
+ } while (0);
+ return p;
}
@@ -277,6 +281,7 @@
{
mp3_state *source_mp3 = source->format->_state;
int r;
+ char *title;
memset (p->data, '\0', size);
if (source_mp3->url_artist && source_mp3->url_title)
@@ -299,7 +304,10 @@
snprintf (p->data+r, size-r, "StreamUrl='%s';", source_mp3->url);
}
DEBUG1 ("shoutcast metadata block setup with %s", p->data+1);
- filter_shoutcast_metadata (source, p->data, size);
+ title = filter_shoutcast_metadata (source, p->data, size);
+ logging_playlist (source->mount, title, source->listeners);
+ yp_touch (source->mount);
+ free (title);
refbuf_release (source_mp3->metadata);
source_mp3->metadata = p;
@@ -510,7 +518,7 @@
}
return 0;
}
- rate_add (format->in_bitrate, bytes, global.time);
+ rate_add (format->in_bitrate, bytes, time(NULL));
}
source_mp3->read_count += bytes;
refbuf = source_mp3->read_data;
@@ -644,8 +652,12 @@
DEBUG1("shoutcast metadata %.4080s", meta->data+1);
if (strncmp (meta->data+1, "StreamTitle=", 12) == 0)
{
- filter_shoutcast_metadata (source, source_mp3->build_metadata,
- source_mp3->build_metadata_len);
+ char *title = filter_shoutcast_metadata (source,
+ source_mp3->build_metadata, source_mp3->build_metadata_len);
+ logging_playlist (source->mount, title, source->listeners);
+ stats_event_conv (source->mount, "title", title, source->format->charset);
+ yp_touch (source->mount);
+ free (title);
refbuf_release (source_mp3->metadata);
source_mp3->metadata = meta;
source_mp3->inline_url = strstr (meta->data+1, "StreamUrl='");
Modified: icecast/branches/kh/icecast/src/format_ogg.c
===================================================================
--- icecast/branches/kh/icecast/src/format_ogg.c 2009-03-27 23:09:45 UTC (rev 15864)
+++ icecast/branches/kh/icecast/src/format_ogg.c 2009-03-27 23:12:53 UTC (rev 15865)
@@ -480,7 +480,7 @@
return NULL;
}
format->read_bytes += bytes;
- rate_add (format->in_bitrate, bytes, global.time);
+ rate_add (format->in_bitrate, bytes, time(NULL));
ogg_sync_wrote (&ogg_info->oy, bytes);
}
}
Modified: icecast/branches/kh/icecast/src/format_vorbis.c
===================================================================
--- icecast/branches/kh/icecast/src/format_vorbis.c 2009-03-27 23:09:45 UTC (rev 15864)
+++ icecast/branches/kh/icecast/src/format_vorbis.c 2009-03-27 23:12:53 UTC (rev 15865)
@@ -422,7 +422,6 @@
ogg_state_t *ogg_info = plugin->_state;
ogg_codec_t *codec = ogg_info->codecs;
vorbis_codec_t *source_vorbis;
- int change = 0;
char *value;
/* avoid url updates unless allowed to */
@@ -435,6 +434,13 @@
else
return;
+ if (tag == NULL)
+ {
+ source_vorbis->stream_notify = 1;
+ source_vorbis->rebuild_comment = 1;
+ return;
+ }
+
value = util_conv_string (in_value, charset, "UTF-8");
if (value == NULL)
value = strdup (in_value);
@@ -443,27 +449,17 @@
{
free (ogg_info->artist);
ogg_info->artist = value;
- change = 1;
}
else if (strcmp (tag, "title") == 0)
{
free (ogg_info->title);
ogg_info->title = value;
- change = 1;
}
else if (strcmp (tag, "song") == 0)
{
- free (ogg_info->artist);
free (ogg_info->title);
- ogg_info->artist = NULL;
ogg_info->title = value;
- change = 1;
}
- if (change)
- {
- source_vorbis->stream_notify = 1;
- source_vorbis->rebuild_comment = 1;
- }
else
free (value);
}
@@ -557,8 +553,8 @@
/* if vorbis is the only codec then allow rebuilding of the streams */
if (ogg_info->codecs->next == NULL && ogg_info->passthrough == 0)
{
- /* set queued vorbis pages to contain about 1 second worth of samples */
- source_vorbis->page_samples_trigger = (ogg_int64_t)(source_vorbis->vi.rate);
+ /* set queued vorbis pages to contain about 1/2 second worth of samples */
+ source_vorbis->page_samples_trigger = (ogg_int64_t)(source_vorbis->vi.rate/2);
if (ogg_info->admin_comments_only)
source_vorbis->rebuild_comment = 1;
source_vorbis->process_packet = process_vorbis_headers;
Modified: icecast/branches/kh/icecast/src/fserve.c
===================================================================
--- icecast/branches/kh/icecast/src/fserve.c 2009-03-27 23:09:45 UTC (rev 15864)
+++ icecast/branches/kh/icecast/src/fserve.c 2009-03-27 23:12:53 UTC (rev 15865)
@@ -94,7 +94,9 @@
ice_config_t *config = config_get_config();
mimetypes = NULL;
- thread_spin_create ("fserve pending", &pending_lock);
+ active_list = NULL;
+ pending_list = NULL;
+ thread_spin_create (&pending_lock);
fserve_recheck_mime_types (config);
config_release_config();
@@ -297,6 +299,7 @@
continue;
}
refbuf = refbuf->next;
+ client->refbuf->next = NULL;
refbuf_release (client->refbuf);
client->refbuf = refbuf;
bytes = refbuf->len;
@@ -323,7 +326,6 @@
fclient = fclient->next;
}
}
-
DEBUG0 ("fserve handler exit");
return NULL;
}
@@ -409,14 +411,17 @@
const char *range = NULL;
off_t new_content_len = 0;
off_t rangenumber = 0, content_length;
- int ret = 0;
+ int ret = 0, use_admin = 0;
char *fullpath;
int m3u_requested = 0, m3u_file_available = 1;
int xspf_requested = 0, xspf_file_available = 1;
ice_config_t *config;
FILE *file;
- fullpath = util_get_path_from_normalised_uri (path);
+ if (httpclient->parser == NULL) /* special case for specific non-http content */
+ use_admin = 1;
+
+ fullpath = util_get_path_from_normalised_uri (path, use_admin);
INFO2 ("checking for file %s (%s)", path, fullpath);
if (strcmp (util_get_extension (fullpath), "m3u") == 0)
@@ -595,7 +600,7 @@
else
break;
}
- else
+ else if (httpclient->parser)
{
char *type = fserve_content_type (path);
httpclient->respcode = 200;
@@ -644,6 +649,7 @@
thread_spin_unlock (&pending_lock);
}
+
/* Add client to fserve thread, client needs to have refbuf set and filled
* but may provide a NULL file if no data needs to be read
*/
@@ -654,7 +660,7 @@
DEBUG0 ("Adding client to file serving engine");
if (fclient == NULL)
{
- client_send_404 (client, "memory exhausted");
+ client_destroy (client);
return -1;
}
fclient->file = file;
Modified: icecast/branches/kh/icecast/src/global.c
===================================================================
--- icecast/branches/kh/icecast/src/global.c 2009-03-27 23:09:45 UTC (rev 15864)
+++ icecast/branches/kh/icecast/src/global.c 2009-03-27 23:12:53 UTC (rev 15865)
@@ -41,10 +41,9 @@
global.running = 0;
global.clients = 0;
global.sources = 0;
- global.time = time(NULL);
global.source_tree = avl_tree_new(source_compare_sources, NULL);
- thread_mutex_create("global", &_global_mutex);
- thread_spin_create ("xyz", &global.spinlock);
+ thread_mutex_create(&_global_mutex);
+ thread_spin_create (&global.spinlock);
global.out_bitrate = rate_setup (151, 1000);
}
@@ -70,7 +69,7 @@
void global_add_bitrates (struct rate_calc *rate, unsigned long value)
{
thread_spin_lock (&global.spinlock);
- rate_add (rate, value, global.time_ms);
+ rate_add (rate, value, timing_get_time());
thread_spin_unlock (&global.spinlock);
}
Modified: icecast/branches/kh/icecast/src/global.h
===================================================================
--- icecast/branches/kh/icecast/src/global.h 2009-03-27 23:09:45 UTC (rev 15864)
+++ icecast/branches/kh/icecast/src/global.h 2009-03-27 23:12:53 UTC (rev 15865)
@@ -39,9 +39,6 @@
int clients;
int schedule_config_reread;
- time_t time;
- uint64_t time_ms;
-
avl_tree *source_tree;
/* for locally defined relays */
struct _relay_server *relays;
Modified: icecast/branches/kh/icecast/src/logging.c
===================================================================
--- icecast/branches/kh/icecast/src/logging.c 2009-03-27 23:09:45 UTC (rev 15864)
+++ icecast/branches/kh/icecast/src/logging.c 2009-03-27 23:12:53 UTC (rev 15865)
@@ -44,7 +44,7 @@
char sign;
char *timezone_string;
struct tm gmt;
- time_t time1 = global.time;
+ time_t time1 = time(NULL);
int time_days, time_hours, time_tz;
int tempnum1, tempnum2;
struct tm *thetime;
@@ -81,7 +81,7 @@
timezone_string = calloc(1, 7);
snprintf(timezone_string, 7, " %c%.2d%.2d", sign, time_tz / 60, time_tz % 60);
- now = global.time;
+ now = time(NULL);
thetime = localtime(&now);
strftime (buffer, len-7, "%d/%b/%Y:%H:%M:%S", thetime);
@@ -117,7 +117,7 @@
if (httpp_getvar (client->parser, "__avoid_access_log"))
return;
- now = global.time;
+ now = time(NULL);
localtime_r (&now, &thetime);
/* build the data */
@@ -174,7 +174,7 @@
return;
}
- now = global.time;
+ now = time(NULL);
localtime_r (&now, &thetime);
/* build the data */
Modified: icecast/branches/kh/icecast/src/slave.c
===================================================================
--- icecast/branches/kh/icecast/src/slave.c 2009-03-27 23:09:45 UTC (rev 15864)
+++ icecast/branches/kh/icecast/src/slave.c 2009-03-27 23:12:53 UTC (rev 15865)
@@ -224,7 +224,7 @@
while (checking)
{
DEBUG2 ("...%s:%d", checking->server, checking->port);
- if (checking->next_update && checking->next_update+10 < global.time)
+ if (checking->next_update && checking->next_update+10 < time(NULL))
{
/* no streamist request, expire slave for now */
*trail = checking->next;
@@ -469,7 +469,7 @@
/* only keep refreshing YP entries for inactive on-demand relays */
yp_remove (relay->localmount);
relay->source->yp_public = -1;
- relay->start = global.time + 10; /* prevent busy looping if failing */
+ relay->start = time(NULL) + 10; /* prevent busy looping if failing */
slave_update_all_mounts();
}
@@ -506,7 +506,7 @@
/* cleanup relay, but prevent this relay from starting up again too soon */
relay->source->on_demand = 0;
- relay->start = global.time + relay->interval;
+ relay->start = time(NULL) + relay->interval;
relay->cleanup = 1;
return NULL;
@@ -531,18 +531,25 @@
DEBUG1("Adding relay source at mountpoint \"%s\"", relay->localmount);
if (relay->on_demand)
{
- relay->start = global.time;
+ relay->start = time(NULL);
slave_update_all_mounts();
}
}
else
- WARN1 ("new relay but source \"%s\" already exists", relay->localmount);
+ {
+ if (relay->start == 0)
+ {
+ WARN1 ("new relay but source \"%s\" already exists", relay->localmount);
+ relay->start = 1;
+ }
+ return;
+ }
}
do
{
source_t *source = relay->source;
/* skip relay if active, not configured or just not time yet */
- if (relay->source == NULL || relay->running || relay->start > global.time)
+ if (relay->source == NULL || relay->running || relay->start > time(NULL))
break;
if (relay->enable == 0)
{
@@ -587,7 +594,7 @@
break;
}
- relay->start = global.time + 5;
+ relay->start = time(NULL) + 5;
relay->running = 1;
relay->thread = thread_create ("Relay Thread", start_relay_stream,
relay, THREAD_ATTACHED);
@@ -620,7 +627,7 @@
thread_mutex_unlock (&relay->source->lock);
config_release_config ();
stats_event (relay->localmount, "listeners", "0");
- relay->start = global.time;
+ relay->start = time(NULL);
}
}
}
@@ -1039,33 +1046,22 @@
{
relay_server *cleanup_relays = NULL;
int skip_timer = 0;
- uint64_t prev_time_ms = timing_get_time();
- do
+ /* re-read xml file if requested */
+ if (global . schedule_config_reread)
{
- /* re-read xml file if requested */
- if (global . schedule_config_reread)
- {
- event_config_read ();
- global . schedule_config_reread = 0;
- }
+ event_config_read ();
+ global . schedule_config_reread = 0;
+ }
- if (global.running != ICE_RUNNING)
- break;
+ thread_sleep (1000000);
+ global_add_bitrates (global.out_bitrate, 0L);
- thread_sleep (100000);
- global.time_ms = timing_get_time ();
- global.time = (long)(global.time_ms/(uint64_t)1000);
-
- global_add_bitrates (global.out_bitrate, 0L);
- } while (global.time_ms - prev_time_ms < 1000);
- prev_time_ms = global.time_ms;
-
if (global.running != ICE_RUNNING)
break;
/* only update relays lists from master when required */
- if (streamlist_check <= global.time)
+ if (streamlist_check <= time(NULL))
{
ice_config_t *config;
@@ -1075,7 +1071,7 @@
thread_mutex_lock (&(config_locks()->relay_lock));
config = config_get_config();
- streamlist_check = global.time + config->master_update_interval;
+ streamlist_check = time(NULL) + config->master_update_interval;
update_master_as_slave (config);
update_from_master (config);
@@ -1179,7 +1175,7 @@
else
{
DEBUG2 ("touch update on %s:%d", redirect->server, redirect->port);
- redirect->next_update = global.time + interval;
+ redirect->next_update = time(NULL) + interval;
}
thread_rwlock_unlock (&slaves_lock);
}
@@ -1223,7 +1219,7 @@
if (interval == 0)
redirect->next_update = (time_t)0;
else
- redirect->next_update = global.time + interval;
+ redirect->next_update = time(NULL) + interval;
redirect->next = redirectors;
redirectors = redirect;
global.redirect_count++;
Modified: icecast/branches/kh/icecast/src/source.c
===================================================================
--- icecast/branches/kh/icecast/src/source.c 2009-03-27 23:09:45 UTC (rev 15864)
+++ icecast/branches/kh/icecast/src/source.c 2009-03-27 23:12:53 UTC (rev 15865)
@@ -99,7 +99,7 @@
src->avg_bitrate_duration = 60;
src->listener_send_trigger = 10000;
- thread_mutex_create (src->mount, &src->lock);
+ thread_mutex_create (&src->lock);
avl_insert (global.source_tree, src);
@@ -248,6 +248,7 @@
{
refbuf_t *to_go = p;
p = to_go->next;
+ to_go->next = NULL;
refbuf_release (to_go);
}
source->burst_point = NULL;
@@ -257,6 +258,7 @@
{
refbuf_t *to_go = p;
p = to_go->next;
+ to_go->next = NULL;
if (to_go->_count > 1)
WARN1 ("buffer is %d", to_go->_count);
refbuf_release (to_go);
@@ -435,6 +437,7 @@
unsigned long incoming_rate = 8 * rate_avg (source->format->in_bitrate);
unsigned long kbytes_sent = source->bytes_sent_since_update/1024;
unsigned long kbytes_read = source->bytes_read_since_update/1024;
+ time_t now = time(NULL);
source->format->sent_bytes += kbytes_sent*1024;
stats_event_args (source->mount, "outgoing_kbitrate", "%ld",
@@ -448,7 +451,7 @@
"%"PRIu64, source->format->sent_bytes/(1024*1024));
if (source->client)
stats_event_args (source->mount, "connected", "%"PRIu64,
- (uint64_t)(global.time - source->client->con->con_time));
+ (uint64_t)(now - source->client->con->con_time));
stats_event_add (NULL, "stream_kbytes_sent", kbytes_sent);
stats_event_add (NULL, "stream_kbytes_read", kbytes_read);
@@ -470,12 +473,12 @@
/* if bitrate is consistently excessive then terminate the stream */
if (source->throttle_termination == 0)
{
- source->throttle_termination = global.time + source->avg_bitrate_duration/2;
+ source->throttle_termination = now + source->avg_bitrate_duration/2;
/* DEBUG1 ("throttle termination set at %ld", source->throttle_termination); */
}
else
{
- if (global.time >= source->throttle_termination)
+ if (now >= source->throttle_termination)
{
source->running = 0;
WARN3 ("%s terminating, exceeding bitrate limits (%dk/%dk)",
@@ -504,7 +507,7 @@
while (global.running == ICE_RUNNING && source->running)
{
int fds = 0;
- time_t current = global.time;
+ time_t current = time(NULL);
int delay = 200;
source->amount_added_to_queue = 0;
@@ -566,7 +569,7 @@
process_listeners (source, 1, 0);
continue;
}
- rate_add (source->format->in_bitrate, 0, global.time);
+ rate_add (source->format->in_bitrate, 0, current);
break;
}
source->last_read = current;
@@ -645,7 +648,7 @@
int ret = 0;
/* check for limited listener time */
- if (client->con->discon_time && global.time >= client->con->discon_time)
+ if (client->con->discon_time && time(NULL) >= client->con->discon_time)
{
INFO1 ("time limit reached for client #%lu", client->con->id);
client->con->error = 1;
@@ -685,7 +688,7 @@
total_written += bytes;
}
- rate_add (source->format->out_bitrate, total_written, global.time_ms);
+ rate_add (source->format->out_bitrate, total_written, timing_get_time());
source->bytes_sent_since_update += total_written;
global_add_bitrates (global.out_bitrate, total_written);
@@ -809,6 +812,9 @@
}
}
+ /* grab a read lock, to make sure we get a chance to cleanup */
+ thread_rwlock_rlock (source->shutdown_rwlock);
+
/* start off the statistics */
stats_event_inc (NULL, "source_total_connections");
stats_event_hidden (source->mount, "slow_listeners", "0", STATS_COUNTERS);
@@ -822,12 +828,12 @@
stats_event_hidden (source->mount, "total_bytes_read", "0", STATS_COUNTERS);
DEBUG0("Source creation complete");
- source->last_read = global.time;
+ source->last_read = time(NULL);
source->prev_listeners = -1;
source->bytes_sent_since_update = 0;
source->stats_interval = 5;
/* so the first set of average stats after 3 seconds */
- source->client_stats_update = global.time + 3;
+ source->client_stats_update = source->last_read + 3;
source->fast_clients_p = &source->active_clients;
source->audio_info = util_dict_new();
@@ -932,6 +938,7 @@
}
source->stream_data = to_go->next;
source->queue_size -= to_go->len;
+ to_go->next = NULL;
refbuf_release (to_go);
}
}
@@ -998,6 +1005,9 @@
global.sources--;
stats_event_args (NULL, "sources", "%d", global.sources);
global_unlock();
+
+ /* release our hold on the lock so the main thread can continue cleaning up */
+ thread_rwlock_unlock(source->shutdown_rwlock);
}
@@ -1077,6 +1087,10 @@
if (source->format && source->format->apply_settings)
source->format->apply_settings (source->client, source->format, mountinfo);
+ str = httpp_getvar (parser, "user-agent");
+ if (str && source->format)
+ stats_event_conv (source->mount, "user_agent", str, source->format->charset);
+
/* public */
if (mountinfo && mountinfo->yp_public >= 0)
val = mountinfo->yp_public;
@@ -1348,11 +1362,11 @@
if (source->wait_time)
{
- time_t release = source->wait_time + global.time;
+ time_t release = source->wait_time + time(NULL);
INFO2 ("keeping %s reserved for %d seconds", source->mount, source->wait_time);
thread_mutex_unlock (&source->lock);
- while (global.running && release >= global.time)
- thread_sleep (300000);
+ while (global.running && release >= time(NULL))
+ thread_sleep (1000000);
}
else
thread_mutex_unlock (&source->lock);
@@ -1366,7 +1380,6 @@
void source_client_callback (client_t *client, void *arg)
{
- const char *agent;
source_t *source = arg;
refbuf_t *old_data = client->refbuf;
@@ -1383,9 +1396,6 @@
old_data->associated = NULL;
refbuf_release (old_data);
stats_event (source->mount, "source_ip", source->client->con->ip);
- agent = httpp_getvar (source->client->parser, "user-agent");
- if (agent)
- stats_event (source->mount, "user_agent", agent);
thread_create ("Source Thread", source_client_thread,
source, THREAD_DETACHED);
@@ -1566,3 +1576,45 @@
config_release_config();
}
+
+void source_startup (client_t *client, const char *uri)
+{
+ source_t *source;
+ source = source_reserve (uri);
+
+ if (source)
+ {
+ source->client = client;
+ source->parser = client->parser;
+ if (connection_complete_source (source, 1) < 0)
+ {
+ source_clear_source (source);
+ source_free_source (source);
+ return;
+ }
+ client->respcode = 200;
+ if (client->server_conn->shoutcast_compat)
+ {
+ source->shoutcast_compat = 1;
+ source_client_callback (client, source);
+ }
+ else
+ {
+ refbuf_t *ok = refbuf_new (PER_CLIENT_REFBUF_SIZE);
+ snprintf (ok->data, PER_CLIENT_REFBUF_SIZE,
+ "HTTP/1.0 200 OK\r\n\r\n");
+ ok->len = strlen (ok->data);
+ /* we may have unprocessed data read in, so don't overwrite it */
+ ok->associated = client->refbuf;
+ client->refbuf = ok;
+ fserve_add_client_callback (client, source_client_callback, source);
+ }
+ }
+ else
+ {
+ client_send_403 (client, "Mountpoint in use");
+ WARN1 ("Mountpoint %s in use", uri);
+ }
+}
+
+
Modified: icecast/branches/kh/icecast/src/source.h
===================================================================
--- icecast/branches/kh/icecast/src/source.h 2009-03-27 23:09:45 UTC (rev 15864)
+++ icecast/branches/kh/icecast/src/source.h 2009-03-27 23:12:53 UTC (rev 15865)
@@ -37,6 +37,7 @@
client_t *active_clients;
client_t **fast_clients_p;
+ rwlock_t *shutdown_rwlock;
util_dict *audio_info;
/* name of a file, whose contents are sent at listener connection */
@@ -87,7 +88,7 @@
source_t *source_reserve (const char *mount);
void *source_client_thread (void *arg);
-void source_startup (client_t *client, const char *uri, int auth_style);
+void source_startup (client_t *client, const char *uri);
void source_client_callback (client_t *client, void *source);
void source_update_settings (ice_config_t *config, source_t *source, mount_proxy *mountinfo);
void source_clear_source (source_t *source);
Modified: icecast/branches/kh/icecast/src/stats.c
===================================================================
--- icecast/branches/kh/icecast/src/stats.c 2009-03-27 23:09:45 UTC (rev 15864)
+++ icecast/branches/kh/icecast/src/stats.c 2009-03-27 23:12:53 UTC (rev 15865)
@@ -152,7 +152,7 @@
_stats.listeners_removed = NULL;
/* set up global mutex */
- thread_mutex_create("stats", &_stats_mutex);
+ thread_mutex_create(&_stats_mutex);
_stats_running = 1;
@@ -229,17 +229,6 @@
}
stats_event (mount, name, metadata);
-
- /* special case for title updates, log converted title */
- if (mount && strcmp (name, "title") == 0)
- {
- char *s = stats_get_value ((char*)mount, "listeners");
- int listeners = 0;
- if (s)
- listeners = atoi (s);
- free (s);
- logging_playlist (mount, metadata, listeners);
- }
xmlBufferFree (conv);
}
@@ -582,7 +571,7 @@
void stats_event_time (const char *mount, const char *name)
{
- time_t now = global.time;
+ time_t now = time(NULL);
struct tm local;
char buffer[100];
@@ -916,7 +905,7 @@
void stats_transform_xslt(client_t *client, const char *uri)
{
xmlDocPtr doc;
- char *xslpath = util_get_path_from_normalised_uri (uri);
+ char *xslpath = util_get_path_from_normalised_uri (uri, 0);
const char *mount = httpp_get_query_param (client->parser, "mount");
doc = stats_get_xml (STATS_PUBLIC, mount);
@@ -1074,14 +1063,9 @@
void stats_global_calc (void)
{
event_listener_t *listener;
- static time_t next_update = 0;
stats_event_t event;
char buffer [VAL_BUFSIZE];
- if (global.time < next_update)
- return;
-
- next_update = global.time + 2;
build_event (&event, NULL, "outgoing_kbitrate", buffer);
event.hidden = STATS_COUNTERS|STATS_HIDDEN;
Modified: icecast/branches/kh/icecast/src/util.c
===================================================================
--- icecast/branches/kh/icecast/src/util.c 2009-03-27 23:09:45 UTC (rev 15864)
+++ icecast/branches/kh/icecast/src/util.c 2009-03-27 23:12:53 UTC (rev 15865)
@@ -97,7 +97,7 @@
#endif
}
-int util_read_header(int sock, char *buff, unsigned long len, int entire)
+int util_read_header(sock_t sock, char *buff, unsigned long len, int entire)
{
int read_bytes, ret;
unsigned long pos;
@@ -232,22 +232,26 @@
if(!path)
return NULL;
else {
- fullpath = util_get_path_from_normalised_uri(path);
+ fullpath = util_get_path_from_normalised_uri(path, 0);
free(path);
return fullpath;
}
}
-char *util_get_path_from_normalised_uri(const char *uri) {
+char *util_get_path_from_normalised_uri(const char *uri, int use_admin)
+{
char *fullpath;
- char *webroot;
+ char *root;
ice_config_t *config = config_get_config();
- webroot = config->webroot_dir;
+ if (use_admin)
+ root = config->adminroot_dir;
+ else
+ root = config->webroot_dir;
- fullpath = malloc(strlen(uri) + strlen(webroot) + 1);
+ fullpath = malloc(strlen(uri) + strlen(root) + 1);
if (fullpath)
- sprintf (fullpath, "%s%s", webroot, uri);
+ sprintf (fullpath, "%s%s", root, uri);
config_release_config();
return fullpath;
@@ -715,11 +719,11 @@
*/
void rate_add (struct rate_calc *calc, long value, uint64_t sid)
{
+ calc->total += value;
if (calc->current == NULL || sid != calc->current->index)
{
if (calc->blocks == calc->samples)
{
- calc->total += calc->current->value;
calc->current = calc->current->next;
calc->total -= calc->current->value;
calc->current->value = value;
@@ -735,7 +739,6 @@
{
node->next = calc->current->next;
calc->current->next = node;
- calc->total += calc->current->value;
}
else
{
@@ -756,10 +759,10 @@
if (calc == NULL || calc->blocks < 2)
return 0;
- range = (calc->current->index - calc->current->next->index) / calc->ssec;
+ range = (calc->current->index - calc->current->next->index);
if (range < 1)
range = 1;
- return (long)(calc->total / range);
+ return (long)(calc->total / range * calc->ssec);
}
/* reduce the samples used to calculate average */
Modified: icecast/branches/kh/icecast/src/util.h
===================================================================
--- icecast/branches/kh/icecast/src/util.h 2009-03-27 23:09:45 UTC (rev 15864)
+++ icecast/branches/kh/icecast/src/util.h 2009-03-27 23:12:53 UTC (rev 15865)
@@ -23,13 +23,12 @@
#define MAX_LINE_LEN 512
-
int util_timed_wait_for_fd(sock_t fd, int timeout);
-int util_read_header(int sock, char *buff, unsigned long len, int entire);
+int util_read_header(sock_t sock, char *buff, unsigned long len, int entire);
int util_check_valid_extension(const char *uri);
char *util_get_extension(const char *path);
char *util_get_path_from_uri(char *uri);
-char *util_get_path_from_normalised_uri(const char *uri);
+char *util_get_path_from_normalised_uri(const char *uri, int use_admin);
char *util_normalise_uri(const char *uri);
char *util_base64_encode(const char *data);
char *util_base64_decode(const char *input);
Modified: icecast/branches/kh/icecast/src/xslt.c
===================================================================
--- icecast/branches/kh/icecast/src/xslt.c 2009-03-27 23:09:45 UTC (rev 15864)
+++ icecast/branches/kh/icecast/src/xslt.c 2009-03-27 23:12:53 UTC (rev 15865)
@@ -93,7 +93,7 @@
void xslt_initialize(void)
{
memset(cache, 0, sizeof(stylesheet_cache_t)*CACHESIZE);
- thread_mutex_create("xslt", &xsltlock);
+ thread_mutex_create(&xsltlock);
xmlInitParser();
LIBXML_TEST_VERSION
xmlSubstituteEntitiesDefault(1);
Modified: icecast/branches/kh/icecast/src/yp.c
===================================================================
--- icecast/branches/kh/icecast/src/yp.c 2009-03-27 23:09:45 UTC (rev 15864)
+++ icecast/branches/kh/icecast/src/yp.c 2009-03-27 23:12:53 UTC (rev 15865)
@@ -272,7 +272,7 @@
{
ice_config_t *config = config_get_config();
thread_rwlock_create (&yp_lock);
- thread_mutex_create ("yp", &yp_pending_lock);
+ thread_mutex_create (&yp_pending_lock);
yp_recheck_config (config);
config_release_config ();
}
@@ -408,7 +408,7 @@
{
yp->process = do_yp_touch;
/* force first touch in 5 secs */
- yp->next_update = global.time + 5;
+ yp->next_update = time(NULL) + 5;
}
return ret;
}
@@ -524,7 +524,7 @@
yp = server->mounts;
while (yp)
{
- now = global.time;
+ now = time(NULL);
/* if one of the streams shows that the server cannot be contacted then mark the
* other entries for an update later. Assume YP server is dead and skip it for now
*/
@@ -875,7 +875,7 @@
yp->server = server;
yp->touch_interval = server->touch_interval;
yp->next = server->pending_mounts;
- yp->next_update = global.time + 60;
+ yp->next_update = time(NULL) + 60;
server->pending_mounts = yp;
yp_update = 1;
}
Modified: icecast/branches/kh/icecast/win32/icecast2.iss
===================================================================
--- icecast/branches/kh/icecast/win32/icecast2.iss 2009-03-27 23:09:45 UTC (rev 15864)
+++ icecast/branches/kh/icecast/win32/icecast2.iss 2009-03-27 23:12:53 UTC (rev 15865)
@@ -3,7 +3,7 @@
[Setup]
AppName=Icecast2-KH
-AppVerName=Icecast v2.3.2-kh8
+AppVerName=Icecast v2.3.2-kh9
AppPublisherURL=http://www.icecast.org
AppSupportURL=http://www.icecast.org
AppUpdatesURL=http://www.icecast.org
@@ -13,7 +13,7 @@
LicenseFile=..\COPYING
InfoAfterFile=..\README
OutputDir=.
-OutputBaseFilename=icecast2_win32_v2.3.2-kh8_setup
+OutputBaseFilename=icecast2_win32_v2.3.2-kh9_setup
WizardImageFile=icecast2logo2.bmp
WizardImageStretch=no
; uncomment the following line if you want your installation to run on NT 3.51 too.
@@ -42,6 +42,7 @@
Source: "..\web\images\*.jpg"; DestDir: "{app}\web\images"; Flags: ignoreversion
Source: "..\web\*.css"; DestDir: "{app}\web"; Flags: ignoreversion
Source: "..\admin\*.xsl"; DestDir: "{app}\admin"; Flags: ignoreversion
+Source: "..\admin\flashpolicy"; DestDir: "{app}\admin"; Flags: ignoreversion
Source: "c:\xiph\lib\pthreadVSE.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "..\conf\*.dist"; DestDir: "{app}"; Flags: ignoreversion
Source: "..\examples\icecast_shoutcast_compat.xml"; DestDir: "{app}"; DestName: "icecast.xml"; Flags: ignoreversion
More information about the commits
mailing list