[xiph-cvs] cvs commit: icecast/src event.c event.h Makefile.am config.c config.h configtest.c connection.c connection.h fserve.c main.c sighandler.c slave.c source.c util.c yp.c
Michael Smith
msmith at xiph.org
Wed Mar 5 05:03:36 PST 2003
msmith 03/03/05 08:03:35
Modified: . TODO
src Makefile.am config.c config.h configtest.c
connection.c connection.h fserve.c main.c
sighandler.c slave.c source.c util.c yp.c
Added: . News
src event.c event.h
Removed: . ChangeLog
Log:
Allow rereading config files.
Lots of new locking happening so that it's safe to have the config file
disappear under the rest of the program
Does NOT affect currently-running sources at the moment
Revision Changes Path
1.11 +4 -2 icecast/TODO
Index: TODO
===================================================================
RCS file: /usr/local/cvsroot/icecast/TODO,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- TODO 24 Feb 2003 13:37:15 -0000 1.10
+++ TODO 5 Mar 2003 13:03:35 -0000 1.11
@@ -50,6 +50,8 @@
- option to use ipv6 (equiv to using <bind-address>::</bindaddress>, I think.
-- per-mountpoint listener maximums.
-
+- abstract all admin functionality to a set of commands, and command handlers.
+ Make /admin/* just parse according to a set of rules, and dispatch generic
+ commands through that.
+ Use this for alternative admin interfaces (GUI? telnet interface?)
<p><p>1.1 icecast/News
Index: News
===================================================================
2003-03-05
Implemented the ability to reread the config file on SIGHUP. For now, this
does not affect configuration for currently running sources (only new
sources and global parameters like max-listeners)
2003-03-02
More features:
-- per mountpoint listener maxima
-- static configuration of mountpoint fallbacks
-- stream dumping (write incoming stream to disk)
2003-02-27
Fix log buffering on win32 - previously, logs were never flushed, so they
only got output every few tens or hundreds of lines.
2003-02-27
Support new icy-audio-info header, to communicate various parameters to
clients and yp servers, including sample rate, quality, channels, bitrate
2003-02-25
Full support for relaying mp3 metadata (if turned on in config file)
2003-02-25
Allow configuration of maximum client queue length (in bytes)
2003-02-14
Finished full IPv6 support.
2003-02-12
Allow configuring local mountpoint seperately from remote mountpoint for
relays
2003-02-12
Per mountpoint usernames and passwords (for sources)
2003-02-11
Now that it's been officially assigned, use application/ogg instead of
application/x-ogg
2003-02-07
Allow relaying of mp3 streams from icecast 1.x and shoutcast
2003-02-07
Added ability to configure individual relays (rather than just all streams
from a single server).
2003-02-03
Added support for YP directory services listings
are only used by the yp listing routines
2003-02-03
Support command line parameter -b to run in the background (not supported
on win32)
2002-12-31
Implement configurable mountpoint fallbacks (on source exit, clients are
transferred to another mountpoint automatically, without disconnecting
them)
2002-12-31
Implemented full mp3 metadata support.
(older stuff is missing from here)
<p><p><p>1.13 +2 -2 icecast/src/Makefile.am
Index: Makefile.am
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/Makefile.am,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- Makefile.am 2 Feb 2003 14:24:12 -0000 1.12
+++ Makefile.am 5 Mar 2003 13:03:35 -0000 1.13
@@ -8,10 +8,10 @@
noinst_HEADERS = config.h os.h logging.h sighandler.h connection.h global.h\
util.h slave.h source.h stats.h refbuf.h client.h format.h format_vorbis.h\
- compat.h format_mp3.h fserve.h xslt.h geturl.h yp.h
+ compat.h format_mp3.h fserve.h xslt.h geturl.h yp.h event.h
icecast_SOURCES = config.c main.c logging.c sighandler.c connection.c global.c\
util.c slave.c source.c stats.c refbuf.c client.c format.c format_vorbis.c\
- format_mp3.c xslt.c fserve.c geturl.c yp.c
+ format_mp3.c xslt.c fserve.c geturl.c yp.c event.c
icecast_LDADD = net/libicenet.la thread/libicethread.la httpp/libicehttpp.la\
log/libicelog.la avl/libiceavl.la timing/libicetiming.la
<p><p>1.29 +228 -162 icecast/src/config.c
Index: config.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/config.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- config.c 2 Mar 2003 10:36:24 -0000 1.28
+++ config.c 5 Mar 2003 13:03:35 -0000 1.29
@@ -3,6 +3,8 @@
#include <string.h>
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
+
+#include "thread/thread.h"
#include "config.h"
#include "refbuf.h"
#include "client.h"
@@ -45,36 +47,59 @@
#define CONFIG_DEFAULT_WEBROOT_DIR ".\\webroot"
#endif
-ice_config_t _configuration;
-char *_config_filename;
+ice_config_t _current_configuration;
+ice_config_locks _locks;
+
+static void _set_defaults(ice_config_t *c);
+static void _parse_root(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
+static void _parse_limits(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
+static void _parse_directory(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
+static void _parse_paths(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
+static void _parse_logging(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
+static void _parse_security(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
+static void _parse_authentication(xmlDocPtr doc, xmlNodePtr node,
+ ice_config_t *c);
+static void _parse_relay(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
+static void _parse_mount(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
+static void _add_server(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
+
+static void create_locks() {
+ thread_mutex_create(&_locks.relay_lock);
+ thread_mutex_create(&_locks.mounts_lock);
+ thread_mutex_create(&_locks.config_lock);
+}
-static void _set_defaults(void);
-static void _parse_root(xmlDocPtr doc, xmlNodePtr node);
-static void _parse_limits(xmlDocPtr doc, xmlNodePtr node);
-static void _parse_directory(xmlDocPtr doc, xmlNodePtr node);
-static void _parse_paths(xmlDocPtr doc, xmlNodePtr node);
-static void _parse_logging(xmlDocPtr doc, xmlNodePtr node);
-static void _parse_security(xmlDocPtr doc, xmlNodePtr node);
-static void _parse_authentication(xmlDocPtr doc, xmlNodePtr node);
-static void _parse_relay(xmlDocPtr doc, xmlNodePtr node);
-static void _parse_mount(xmlDocPtr doc, xmlNodePtr node);
-static void _add_server(xmlDocPtr doc, xmlNodePtr node);
-
-void config_initialize(void)
-{
- memset(&_configuration, 0, sizeof(ice_config_t));
- _set_defaults();
- _config_filename = NULL;
+static void release_locks() {
+ thread_mutex_destroy(&_locks.relay_lock);
+ thread_mutex_destroy(&_locks.mounts_lock);
+ thread_mutex_destroy(&_locks.config_lock);
}
-void config_shutdown(void)
+void config_initialize(void) {
+ create_locks();
+}
+
+void config_shutdown(void) {
+ config_get_config();
+ config_clear(&_current_configuration);
+ config_release_config();
+ release_locks();
+}
+
+void config_init_configuration(ice_config_t *configuration)
+{
+ memset(configuration, 0, sizeof(ice_config_t));
+ _set_defaults(configuration);
+}
+
+void config_clear(ice_config_t *c)
{
ice_config_dir_t *dirnode, *nextdirnode;
- ice_config_t *c = &_configuration;
relay_server *relay, *nextrelay;
mount_proxy *mount, *nextmount;
- if (_config_filename) free(_config_filename);
+ if (c->config_filename)
+ free(c->config_filename);
if (c->location && c->location != CONFIG_DEFAULT_LOCATION)
xmlFree(c->location);
@@ -105,7 +130,9 @@
if (c->master_password) xmlFree(c->master_password);
if (c->user) xmlFree(c->user);
if (c->group) xmlFree(c->group);
- relay = _configuration.relay;
+
+ thread_mutex_lock(&(_locks.relay_lock));
+ relay = c->relay;
while(relay) {
nextrelay = relay->next;
xmlFree(relay->server);
@@ -115,7 +142,10 @@
free(relay);
relay = nextrelay;
}
- mount = _configuration.mounts;
+ thread_mutex_unlock(&(_locks.relay_lock));
+
+ thread_mutex_lock(&(_locks.mounts_lock));
+ mount = c->mounts;
while(mount) {
nextmount = mount->next;
xmlFree(mount->mountname);
@@ -126,7 +156,9 @@
free(mount);
mount = nextmount;
}
- dirnode = _configuration.dir_list;
+ thread_mutex_unlock(&(_locks.mounts_lock));
+
+ dirnode = c->dir_list;
while(dirnode) {
nextdirnode = dirnode->next;
xmlFree(dirnode->host);
@@ -137,17 +169,21 @@
memset(c, 0, sizeof(ice_config_t));
}
-int config_parse_file(const char *filename)
+int config_initial_parse_file(const char *filename)
+{
+ /* Since we're already pointing at it, we don't need to copy it in place */
+ return config_parse_file(filename, &_current_configuration);
+}
+
+int config_parse_file(const char *filename, ice_config_t *configuration)
{
xmlDocPtr doc;
xmlNodePtr node;
if (filename == NULL || strcmp(filename, "") == 0) return CONFIG_EINSANE;
- _config_filename = (char *)strdup(filename);
-
xmlInitParser();
- doc = xmlParseFile(_config_filename);
+ doc = xmlParseFile(filename);
if (doc == NULL) {
return CONFIG_EPARSE;
}
@@ -165,7 +201,11 @@
return CONFIG_EBADROOT;
}
- _parse_root(doc, node->xmlChildrenNode);
+ config_init_configuration(configuration);
+
+ configuration->config_filename = (char *)strdup(filename);
+
+ _parse_root(doc, node->xmlChildrenNode, configuration);
xmlFreeDoc(doc);
xmlCleanupParser();
@@ -178,54 +218,71 @@
return 0;
}
-int config_rehash(void)
+ice_config_locks *config_locks(void)
{
- return 0;
+ return &_locks;
}
-ice_config_t *config_get_config(void)
+void config_release_config(void)
{
- return &_configuration;
+ thread_mutex_unlock(&(_locks.config_lock));
}
-static void _set_defaults(void)
+ice_config_t *config_get_config(void)
{
- _configuration.location = CONFIG_DEFAULT_LOCATION;
- _configuration.admin = 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;
- _configuration.threadpool_size = CONFIG_DEFAULT_THREADPOOL_SIZE;
- _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.relay_password = CONFIG_DEFAULT_RELAY_PASSWORD;
- _configuration.ice_login = CONFIG_DEFAULT_ICE_LOGIN;
- _configuration.fileserve = CONFIG_DEFAULT_FILESERVE;
- _configuration.touch_interval = CONFIG_DEFAULT_TOUCH_FREQ;
- _configuration.dir_list = NULL;
- _configuration.hostname = CONFIG_DEFAULT_HOSTNAME;
- _configuration.port = CONFIG_DEFAULT_PORT;
- _configuration.bind_address = NULL;
- _configuration.master_server = NULL;
- _configuration.master_server_port = CONFIG_DEFAULT_PORT;
- _configuration.master_update_interval = CONFIG_MASTER_UPDATE_INTERVAL;
- _configuration.master_password = NULL;
- _configuration.base_dir = CONFIG_DEFAULT_BASE_DIR;
- _configuration.log_dir = CONFIG_DEFAULT_LOG_DIR;
- _configuration.webroot_dir = CONFIG_DEFAULT_WEBROOT_DIR;
- _configuration.access_log = CONFIG_DEFAULT_ACCESS_LOG;
- _configuration.error_log = 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.num_yp_directories = 0;
+ thread_mutex_lock(&(_locks.config_lock));
+ return &_current_configuration;
+}
+
+/* MUST be called with the lock held! */
+void config_set_config(ice_config_t *config) {
+ memcpy(&_current_configuration, config, sizeof(ice_config_t));
+}
+
+ice_config_t *config_get_config_unlocked(void)
+{
+ return &_current_configuration;
+}
+
+static void _set_defaults(ice_config_t *configuration)
+{
+ configuration->location = CONFIG_DEFAULT_LOCATION;
+ configuration->admin = 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;
+ configuration->threadpool_size = CONFIG_DEFAULT_THREADPOOL_SIZE;
+ 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->relay_password = CONFIG_DEFAULT_RELAY_PASSWORD;
+ configuration->ice_login = CONFIG_DEFAULT_ICE_LOGIN;
+ configuration->fileserve = CONFIG_DEFAULT_FILESERVE;
+ configuration->touch_interval = CONFIG_DEFAULT_TOUCH_FREQ;
+ configuration->dir_list = NULL;
+ configuration->hostname = CONFIG_DEFAULT_HOSTNAME;
+ configuration->port = CONFIG_DEFAULT_PORT;
+ configuration->bind_address = NULL;
+ configuration->master_server = NULL;
+ configuration->master_server_port = CONFIG_DEFAULT_PORT;
+ configuration->master_update_interval = CONFIG_MASTER_UPDATE_INTERVAL;
+ configuration->master_password = NULL;
+ configuration->base_dir = CONFIG_DEFAULT_BASE_DIR;
+ configuration->log_dir = CONFIG_DEFAULT_LOG_DIR;
+ configuration->webroot_dir = CONFIG_DEFAULT_WEBROOT_DIR;
+ configuration->access_log = CONFIG_DEFAULT_ACCESS_LOG;
+ configuration->error_log = 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->num_yp_directories = 0;
}
-static void _parse_root(xmlDocPtr doc, xmlNodePtr node)
+static void _parse_root(xmlDocPtr doc, xmlNodePtr node,
+ ice_config_t *configuration)
{
char *tmp;
@@ -234,13 +291,13 @@
if (xmlIsBlankNode(node)) continue;
if (strcmp(node->name, "location") == 0) {
- if (_configuration.location && _configuration.location != CONFIG_DEFAULT_LOCATION) xmlFree(_configuration.location);
- _configuration.location = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+ if (configuration->location && configuration->location != CONFIG_DEFAULT_LOCATION) xmlFree(configuration->location);
+ configuration->location = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (strcmp(node->name, "admin") == 0) {
- if (_configuration.admin && _configuration.admin != CONFIG_DEFAULT_ADMIN) xmlFree(_configuration.admin);
- _configuration.admin = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+ if (configuration->admin && configuration->admin != CONFIG_DEFAULT_ADMIN) xmlFree(configuration->admin);
+ configuration->admin = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if(strcmp(node->name, "authentication") == 0) {
- _parse_authentication(doc, node->xmlChildrenNode);
+ _parse_authentication(doc, node->xmlChildrenNode, configuration);
} else if (strcmp(node->name, "source-password") == 0) {
/* TODO: This is the backwards-compatibility location */
char *mount, *pass;
@@ -249,62 +306,63 @@
/* FIXME: This is a placeholder for per-mount passwords */
}
else {
- if (_configuration.source_password && _configuration.source_password != CONFIG_DEFAULT_SOURCE_PASSWORD) xmlFree(_configuration.source_password);
- _configuration.source_password = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+ if (configuration->source_password && configuration->source_password != CONFIG_DEFAULT_SOURCE_PASSWORD) xmlFree(configuration->source_password);
+ configuration->source_password = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
}
} else if (strcmp(node->name, "relay-password") == 0) {
/* TODO: This is the backwards-compatibility location */
- if (_configuration.relay_password && _configuration.relay_password != CONFIG_DEFAULT_RELAY_PASSWORD) xmlFree(_configuration.relay_password);
- _configuration.relay_password = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+ if (configuration->relay_password && configuration->relay_password != CONFIG_DEFAULT_RELAY_PASSWORD) xmlFree(configuration->relay_password);
+ configuration->relay_password = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (strcmp(node->name, "icelogin") == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- _configuration.ice_login = atoi(tmp);
+ configuration->ice_login = atoi(tmp);
if (tmp) xmlFree(tmp);
} else if (strcmp(node->name, "fileserve") == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- _configuration.fileserve = atoi(tmp);
+ configuration->fileserve = atoi(tmp);
if (tmp) xmlFree(tmp);
} else if (strcmp(node->name, "hostname") == 0) {
- if (_configuration.hostname && _configuration.hostname != CONFIG_DEFAULT_HOSTNAME) xmlFree(_configuration.hostname);
- _configuration.hostname = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+ if (configuration->hostname && configuration->hostname != CONFIG_DEFAULT_HOSTNAME) xmlFree(configuration->hostname);
+ configuration->hostname = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (strcmp(node->name, "port") == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- _configuration.port = atoi(tmp);
+ configuration->port = atoi(tmp);
if (tmp) xmlFree(tmp);
} else if (strcmp(node->name, "bind-address") == 0) {
- if (_configuration.bind_address) xmlFree(_configuration.bind_address);
- _configuration.bind_address = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+ if (configuration->bind_address) xmlFree(configuration->bind_address);
+ configuration->bind_address = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (strcmp(node->name, "master-server") == 0) {
- if (_configuration.master_server) xmlFree(_configuration.master_server);
- _configuration.master_server = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+ if (configuration->master_server) xmlFree(configuration->master_server);
+ configuration->master_server = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (strcmp(node->name, "master-password") == 0) {
- if (_configuration.master_password) xmlFree(_configuration.master_password);
- _configuration.master_password = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+ if (configuration->master_password) xmlFree(configuration->master_password);
+ configuration->master_password = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (strcmp(node->name, "master-server-port") == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- _configuration.master_server_port = atoi(tmp);
+ configuration->master_server_port = atoi(tmp);
} else if (strcmp(node->name, "master-update-interval") == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- _configuration.master_update_interval = atoi(tmp);
+ configuration->master_update_interval = atoi(tmp);
} else if (strcmp(node->name, "limits") == 0) {
- _parse_limits(doc, node->xmlChildrenNode);
+ _parse_limits(doc, node->xmlChildrenNode, configuration);
} else if (strcmp(node->name, "relay") == 0) {
- _parse_relay(doc, node->xmlChildrenNode);
+ _parse_relay(doc, node->xmlChildrenNode, configuration);
} else if (strcmp(node->name, "mount") == 0) {
- _parse_mount(doc, node->xmlChildrenNode);
+ _parse_mount(doc, node->xmlChildrenNode, configuration);
} else if (strcmp(node->name, "directory") == 0) {
- _parse_directory(doc, node->xmlChildrenNode);
+ _parse_directory(doc, node->xmlChildrenNode, configuration);
} else if (strcmp(node->name, "paths") == 0) {
- _parse_paths(doc, node->xmlChildrenNode);
+ _parse_paths(doc, node->xmlChildrenNode, configuration);
} else if (strcmp(node->name, "logging") == 0) {
- _parse_logging(doc, node->xmlChildrenNode);
+ _parse_logging(doc, node->xmlChildrenNode, configuration);
} else if (strcmp(node->name, "security") == 0) {
- _parse_security(doc, node->xmlChildrenNode);
+ _parse_security(doc, node->xmlChildrenNode, configuration);
}
} while ((node = node->next));
}
-static void _parse_limits(xmlDocPtr doc, xmlNodePtr node)
+static void _parse_limits(xmlDocPtr doc, xmlNodePtr node,
+ ice_config_t *configuration)
{
char *tmp;
@@ -314,41 +372,42 @@
if (strcmp(node->name, "clients") == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- _configuration.client_limit = atoi(tmp);
+ configuration->client_limit = atoi(tmp);
if (tmp) xmlFree(tmp);
} else if (strcmp(node->name, "sources") == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- _configuration.source_limit = atoi(tmp);
+ configuration->source_limit = atoi(tmp);
if (tmp) xmlFree(tmp);
} else if (strcmp(node->name, "queue-size") == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- _configuration.queue_size_limit = atoi(tmp);
+ configuration->queue_size_limit = atoi(tmp);
if (tmp) xmlFree(tmp);
} else if (strcmp(node->name, "threadpool") == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- _configuration.threadpool_size = atoi(tmp);
+ configuration->threadpool_size = atoi(tmp);
if (tmp) xmlFree(tmp);
} else if (strcmp(node->name, "client-timeout") == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- _configuration.client_timeout = atoi(tmp);
+ configuration->client_timeout = atoi(tmp);
if (tmp) xmlFree(tmp);
} else if (strcmp(node->name, "header-timeout") == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- _configuration.header_timeout = atoi(tmp);
+ configuration->header_timeout = atoi(tmp);
if (tmp) xmlFree(tmp);
} else if (strcmp(node->name, "source-timeout") == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- _configuration.source_timeout = atoi(tmp);
+ configuration->source_timeout = atoi(tmp);
if (tmp) xmlFree(tmp);
}
} while ((node = node->next));
}
-static void _parse_mount(xmlDocPtr doc, xmlNodePtr node)
+static void _parse_mount(xmlDocPtr doc, xmlNodePtr node,
+ ice_config_t *configuration)
{
char *tmp;
mount_proxy *mount = calloc(1, sizeof(mount_proxy));
- mount_proxy *current = _configuration.mounts;
+ mount_proxy *current = configuration->mounts;
mount_proxy *last=NULL;
while(current) {
@@ -359,7 +418,7 @@
if(last)
last->next = mount;
else
- _configuration.mounts = mount;
+ configuration->mounts = mount;
mount->max_listeners = -1;
@@ -395,11 +454,12 @@
} while ((node = node->next));
}
-static void _parse_relay(xmlDocPtr doc, xmlNodePtr node)
+static void _parse_relay(xmlDocPtr doc, xmlNodePtr node,
+ ice_config_t *configuration)
{
char *tmp;
relay_server *relay = calloc(1, sizeof(relay_server));
- relay_server *current = _configuration.relay;
+ relay_server *current = configuration->relay;
relay_server *last=NULL;
while(current) {
@@ -410,7 +470,7 @@
if(last)
last->next = relay;
else
- _configuration.relay = relay;
+ configuration->relay = relay;
do {
if (node == NULL) break;
@@ -441,7 +501,8 @@
} while ((node = node->next));
}
-static void _parse_authentication(xmlDocPtr doc, xmlNodePtr node)
+static void _parse_authentication(xmlDocPtr doc, xmlNodePtr node,
+ ice_config_t *configuration)
{
do {
if (node == NULL) break;
@@ -454,39 +515,40 @@
/* FIXME: This is a placeholder for per-mount passwords */
}
else {
- if (_configuration.source_password &&
- _configuration.source_password !=
+ if (configuration->source_password &&
+ configuration->source_password !=
CONFIG_DEFAULT_SOURCE_PASSWORD)
- xmlFree(_configuration.source_password);
- _configuration.source_password =
+ xmlFree(configuration->source_password);
+ configuration->source_password =
(char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
}
} else if (strcmp(node->name, "relay-password") == 0) {
- if (_configuration.relay_password &&
- _configuration.relay_password !=
+ if (configuration->relay_password &&
+ configuration->relay_password !=
CONFIG_DEFAULT_RELAY_PASSWORD)
- xmlFree(_configuration.relay_password);
- _configuration.relay_password =
+ xmlFree(configuration->relay_password);
+ configuration->relay_password =
(char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (strcmp(node->name, "admin-password") == 0) {
- if(_configuration.admin_password)
- xmlFree(_configuration.admin_password);
- _configuration.admin_password =
+ if(configuration->admin_password)
+ xmlFree(configuration->admin_password);
+ configuration->admin_password =
(char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (strcmp(node->name, "admin-user") == 0) {
- if(_configuration.admin_username)
- xmlFree(_configuration.admin_username);
- _configuration.admin_username =
+ if(configuration->admin_username)
+ xmlFree(configuration->admin_username);
+ configuration->admin_username =
(char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
}
} while ((node = node->next));
}
-static void _parse_directory(xmlDocPtr doc, xmlNodePtr node)
+static void _parse_directory(xmlDocPtr doc, xmlNodePtr node,
+ ice_config_t *configuration)
{
char *tmp;
- if (_configuration.num_yp_directories >= MAX_YP_DIRECTORIES) {
+ if (configuration->num_yp_directories >= MAX_YP_DIRECTORIES) {
ERROR0("Maximum number of yp directories exceeded!");
return;
}
@@ -495,68 +557,71 @@
if (xmlIsBlankNode(node)) continue;
if (strcmp(node->name, "yp-url") == 0) {
- if (_configuration.yp_url[_configuration.num_yp_directories])
- xmlFree(_configuration.yp_url[_configuration.num_yp_directories]);
- _configuration.yp_url[_configuration.num_yp_directories] =
+ if (configuration->yp_url[configuration->num_yp_directories])
+ xmlFree(configuration->yp_url[configuration->num_yp_directories]);
+ configuration->yp_url[configuration->num_yp_directories] =
(char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (strcmp(node->name, "yp-url-timeout") == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- _configuration.yp_url_timeout[_configuration.num_yp_directories] =
+ configuration->yp_url_timeout[configuration->num_yp_directories] =
atoi(tmp);
} else if (strcmp(node->name, "server") == 0) {
- _add_server(doc, node->xmlChildrenNode);
+ _add_server(doc, node->xmlChildrenNode, configuration);
} else if (strcmp(node->name, "touch-interval") == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- _configuration.touch_interval = atoi(tmp);
+ configuration->touch_interval = atoi(tmp);
if (tmp) xmlFree(tmp);
}
} while ((node = node->next));
- _configuration.num_yp_directories++;
+ configuration->num_yp_directories++;
}
-static void _parse_paths(xmlDocPtr doc, xmlNodePtr node)
+static void _parse_paths(xmlDocPtr doc, xmlNodePtr node,
+ ice_config_t *configuration)
{
do {
if (node == NULL) break;
if (xmlIsBlankNode(node)) continue;
if (strcmp(node->name, "basedir") == 0) {
- if (_configuration.base_dir && _configuration.base_dir != CONFIG_DEFAULT_BASE_DIR) xmlFree(_configuration.base_dir);
- _configuration.base_dir = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+ if (configuration->base_dir && configuration->base_dir != CONFIG_DEFAULT_BASE_DIR) xmlFree(configuration->base_dir);
+ configuration->base_dir = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (strcmp(node->name, "logdir") == 0) {
- if (_configuration.log_dir && _configuration.log_dir != CONFIG_DEFAULT_LOG_DIR) xmlFree(_configuration.log_dir);
- _configuration.log_dir = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+ if (configuration->log_dir && configuration->log_dir != CONFIG_DEFAULT_LOG_DIR) xmlFree(configuration->log_dir);
+ configuration->log_dir = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (strcmp(node->name, "webroot") == 0) {
- if (_configuration.webroot_dir && _configuration.webroot_dir != CONFIG_DEFAULT_WEBROOT_DIR) xmlFree(_configuration.webroot_dir);
- _configuration.webroot_dir = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- if(_configuration.webroot_dir[strlen(_configuration.webroot_dir)-1] == '/')
- _configuration.webroot_dir[strlen(_configuration.webroot_dir)-1] = 0;
+ if (configuration->webroot_dir && configuration->webroot_dir != CONFIG_DEFAULT_WEBROOT_DIR) xmlFree(configuration->webroot_dir);
+ configuration->webroot_dir = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+ if(configuration->webroot_dir[strlen(configuration->webroot_dir)-1] == '/')
+ configuration->webroot_dir[strlen(configuration->webroot_dir)-1] = 0;
}
} while ((node = node->next));
}
-static void _parse_logging(xmlDocPtr doc, xmlNodePtr node)
+static void _parse_logging(xmlDocPtr doc, xmlNodePtr node,
+ ice_config_t *configuration)
{
do {
if (node == NULL) break;
if (xmlIsBlankNode(node)) continue;
if (strcmp(node->name, "accesslog") == 0) {
- if (_configuration.access_log && _configuration.access_log != CONFIG_DEFAULT_ACCESS_LOG) xmlFree(_configuration.access_log);
- _configuration.access_log = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+ if (configuration->access_log && configuration->access_log != CONFIG_DEFAULT_ACCESS_LOG) xmlFree(configuration->access_log);
+ configuration->access_log = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (strcmp(node->name, "errorlog") == 0) {
- if (_configuration.error_log && _configuration.error_log != CONFIG_DEFAULT_ERROR_LOG) xmlFree(_configuration.error_log);
- _configuration.error_log = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+ if (configuration->error_log && configuration->error_log != CONFIG_DEFAULT_ERROR_LOG) xmlFree(configuration->error_log);
+ configuration->error_log = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (strcmp(node->name, "loglevel") == 0) {
char *tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- _configuration.loglevel = atoi(tmp);
+ configuration->loglevel = atoi(tmp);
if (tmp) xmlFree(tmp);
}
} while ((node = node->next));
}
-static void _parse_security(xmlDocPtr doc, xmlNodePtr node)
+static void _parse_security(xmlDocPtr doc, xmlNodePtr node,
+ ice_config_t *configuration)
{
char *tmp;
xmlNodePtr oldnode;
@@ -567,21 +632,21 @@
if (strcmp(node->name, "chroot") == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- _configuration.chroot = atoi(tmp);
+ configuration->chroot = atoi(tmp);
if (tmp) xmlFree(tmp);
} else if (strcmp(node->name, "changeowner") == 0) {
- _configuration.chuid = 1;
+ configuration->chuid = 1;
oldnode = node;
node = node->xmlChildrenNode;
do {
if(node == NULL) break;
if(xmlIsBlankNode(node)) continue;
if(strcmp(node->name, "user") == 0) {
- if(_configuration.user) xmlFree(_configuration.user);
- _configuration.user = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+ if(configuration->user) xmlFree(configuration->user);
+ configuration->user = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if(strcmp(node->name, "group") == 0) {
- if(_configuration.group) xmlFree(_configuration.group);
- _configuration.group = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+ if(configuration->group) xmlFree(configuration->group);
+ configuration->group = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
}
} while((node = node->next));
node = oldnode;
@@ -589,14 +654,15 @@
} while ((node = node->next));
}
-static void _add_server(xmlDocPtr doc, xmlNodePtr node)
+static void _add_server(xmlDocPtr doc, xmlNodePtr node,
+ ice_config_t *configuration)
{
ice_config_dir_t *dirnode, *server;
int addnode;
char *tmp;
server = (ice_config_dir_t *)malloc(sizeof(ice_config_dir_t));
- server->touch_interval = _configuration.touch_interval;
+ server->touch_interval = configuration->touch_interval;
server->host = NULL;
addnode = 0;
@@ -617,9 +683,9 @@
} while ((node = node->next));
if (addnode) {
- dirnode = _configuration.dir_list;
+ dirnode = configuration->dir_list;
if (dirnode == NULL) {
- _configuration.dir_list = server;
+ configuration->dir_list = server;
} else {
while (dirnode->next) dirnode = dirnode->next;
<p><p>1.17 +20 -1 icecast/src/config.h
Index: config.h
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/config.h,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- config.h 24 Feb 2003 13:37:15 -0000 1.16
+++ config.h 5 Mar 2003 13:03:35 -0000 1.17
@@ -8,6 +8,8 @@
#define MAX_YP_DIRECTORIES 25
+#include "thread/thread.h"
+
typedef struct ice_config_dir_tag
{
char *host;
@@ -40,6 +42,8 @@
typedef struct ice_config_tag
{
+ char *config_filename;
+
char *location;
char *admin;
@@ -90,15 +94,30 @@
int num_yp_directories;
} ice_config_t;
+typedef struct {
+ mutex_t config_lock;
+ mutex_t relay_lock;
+ mutex_t mounts_lock;
+} ice_config_locks;
+
void config_initialize(void);
void config_shutdown(void);
-int config_parse_file(const char *filename);
+int config_parse_file(const char *filename, ice_config_t *configuration);
+int config_initial_parse_file(const char *filename);
int config_parse_cmdline(int arg, char **argv);
+void config_set_config(ice_config_t *config);
+void config_clear(ice_config_t *config);
int config_rehash(void);
+ice_config_locks *config_locks(void);
+
ice_config_t *config_get_config(void);
+void config_release_config(void);
+
+/* To be used ONLY in one-time startup code */
+ice_config_t *config_get_config_unlocked(void);
#endif /* __CONFIG_H__ */
<p><p>1.4 +1 -1 icecast/src/configtest.c
Index: configtest.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/configtest.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- configtest.c 6 Feb 2003 13:10:48 -0000 1.3
+++ configtest.c 5 Mar 2003 13:03:35 -0000 1.4
@@ -11,7 +11,7 @@
config_parse_file("icecast.xml");
- config = config_get_config();
+ config = config_get_config_unlocked();
_dump_config(config);
<p><p>1.57 +88 -17 icecast/src/connection.c
Index: connection.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/connection.c,v
retrieving revision 1.56
retrieving revision 1.57
diff -u -r1.56 -r1.57
--- connection.c 2 Mar 2003 10:36:24 -0000 1.56
+++ connection.c 5 Mar 2003 13:03:35 -0000 1.57
@@ -40,6 +40,7 @@
#include "geturl.h"
#include "format.h"
#include "format_mp3.h"
+#include "event.h"
#define CATMODULE "connection"
@@ -112,6 +113,10 @@
con->con_time = time(NULL);
con->id = _next_connection_id();
con->ip = ip;
+
+ con->event_number = EVENT_NO_EVENT;
+ con->event = NULL;
+
return con;
}
@@ -209,10 +214,13 @@
int i;
thread_type *tid;
char buff[64];
+ int threadpool_size;
config = config_get_config();
+ threadpool_size = config->threadpool_size;
+ config_release_config();
- for (i = 0; i < config->threadpool_size; i++) {
+ for (i = 0; i < threadpool_size; i++) {
snprintf(buff, 64, "Connection Thread #%d", i);
tid = thread_create(buff, _handle_connection, NULL, THREAD_ATTACHED);
_push_thread(&_conhands, tid);
@@ -290,6 +298,16 @@
return con;
}
+void connection_inject_event(int eventnum, void *event_data) {
+ connection_t *con = calloc(1, sizeof(connection_t));
+
+ con->event_number = eventnum;
+ con->event = event_data;
+
+ _add_connection(con);
+ _signal_pool();
+}
+
/* TODO: Make this return an appropriate error code so that we can use HTTP
* codes where appropriate
*/
@@ -297,12 +315,18 @@
source_t *source;
char *contenttype;
mount_proxy *mountproxy, *mountinfo = NULL;
+ int source_limit;
+ ice_config_t *config;
+
+ config = config_get_config();
+ source_limit = config->source_limit;
+ config_release_config();
/* check to make sure this source wouldn't
** be over the limit
*/
global_lock();
- if (global.sources >= config_get_config()->source_limit) {
+ if (global.sources >= source_limit) {
INFO1("Source (%s) logged in, but there are too many sources", mount);
global_unlock();
return 0;
@@ -312,7 +336,11 @@
stats_event_inc(NULL, "sources");
- mountproxy = config_get_config()->mounts;
+ config = config_get_config();
+ mountproxy = config->mounts;
+ thread_mutex_lock(&(config_locks()->mounts_lock));
+ config_release_config();
+
while(mountproxy) {
if(!strcmp(mountproxy->mountname, mount)) {
mountinfo = mountproxy;
@@ -327,15 +355,18 @@
format_type_t format = format_get_type(contenttype);
if (format == FORMAT_ERROR) {
WARN1("Content-type \"%s\" not supported, dropping source", contenttype);
+ thread_mutex_unlock(&(config_locks()->mounts_lock));
goto fail;
} else {
source = source_create(client, con, parser, mount,
format, mountinfo);
+ thread_mutex_unlock(&(config_locks()->mounts_lock));
}
} else {
format_type_t format = FORMAT_TYPE_MP3;
ERROR0("No content-type header, falling back to backwards compatibility mode for icecast 1.x relays. Assuming content is mp3.");
source = source_create(client, con, parser, mount, format, mountinfo);
+ thread_mutex_unlock(&(config_locks()->mounts_lock));
}
source->send_return = 1;
@@ -408,17 +439,22 @@
static int _check_relay_pass(http_parser_t *parser)
{
- char *pass = config_get_config()->relay_password;
+ ice_config_t *config = config_get_config();
+ char *pass = config->relay_password;
if(!pass)
- pass = config_get_config()->source_password;
+ pass = config->source_password;
+ config_release_config();
return _check_pass_http(parser, "relay", pass);
}
static int _check_admin_pass(http_parser_t *parser)
{
- char *pass = config_get_config()->admin_password;
- char *user = config_get_config()->admin_username;
+ ice_config_t *config = config_get_config();
+ char *pass = config->admin_password;
+ char *user = config->admin_username;
+ config_release_config();
+
if(!pass || !user)
return 0;
@@ -427,11 +463,16 @@
static int _check_source_pass(http_parser_t *parser, char *mount)
{
- char *pass = config_get_config()->source_password;
+ ice_config_t *config = config_get_config();
+ char *pass = config->source_password;
char *user = "source";
int ret;
+ int ice_login = config->ice_login;
+
+ mount_proxy *mountinfo = config->mounts;
+ thread_mutex_lock(&(config_locks()->mounts_lock));
+ config_release_config();
- mount_proxy *mountinfo = config_get_config()->mounts;
while(mountinfo) {
if(!strcmp(mountinfo->mountname, mount)) {
if(mountinfo->password)
@@ -443,13 +484,15 @@
mountinfo = mountinfo->next;
}
+ thread_mutex_unlock(&(config_locks()->mounts_lock));
+
if(!pass) {
WARN0("No source password set, rejecting source");
return 0;
}
ret = _check_pass_http(parser, user, pass);
- if(!ret && config_get_config()->ice_login)
+ if(!ret && ice_login)
{
ret = _check_pass_ice(parser, pass);
if(ret)
@@ -627,6 +670,19 @@
int bytes;
struct stat statbuf;
source_t *source;
+ int fileserve;
+ char *host;
+ int port;
+ ice_config_t *config;
+ int client_limit;
+
+ config = config_get_config();
+ fileserve = config->fileserve;
+ host = config->hostname;
+ port = config->port;
+ client_limit = config->client_limit;
+ config_release_config();
+
DEBUG0("Client connected");
@@ -689,8 +745,8 @@
free(fullpath);
return;
}
- else if(config_get_config()->fileserve &&
- stat(fullpath, &statbuf) == 0) {
+ else if(fileserve && stat(fullpath, &statbuf) == 0)
+ {
fserve_client_create(client, fullpath);
free(fullpath);
return;
@@ -709,14 +765,14 @@
"HTTP/1.0 200 OK\r\n"
"Content-Type: audio/x-mpegurl\r\n\r\n"
"http://%s:%d%s",
- config_get_config()->hostname,
- config_get_config()->port,
+ host,
+ port,
sourceuri
);
if(bytes > 0) client->con->sent_bytes = bytes;
client_destroy(client);
}
- else if(config_get_config()->fileserve) {
+ else if(fileserve) {
fullpath = util_get_path_from_normalised_uri(sourceuri);
if(stat(fullpath, &statbuf) == 0) {
fserve_client_create(client, fullpath);
@@ -774,7 +830,7 @@
}
global_lock();
- if (global.clients >= config_get_config()->client_limit) {
+ if (global.clients >= client_limit) {
client_send_504(client,
"The server is already full. Try again later.");
global_unlock();
@@ -788,7 +844,7 @@
DEBUG0("Source found for client");
global_lock();
- if (global.clients >= config_get_config()->client_limit) {
+ if (global.clients >= client_limit) {
client_send_504(client,
"The server is already full. Try again later.");
global_unlock();
@@ -847,6 +903,21 @@
/* grab a connection and set the socket to blocking */
while ((con = _get_connection())) {
+
+ /* Handle meta-connections */
+ if(con->event_number > 0) {
+ switch(con->event_number) {
+ case EVENT_CONFIG_READ:
+ event_config_read(con->event);
+ break;
+ default:
+ ERROR1("Unknown event number: %d", con->event_number);
+ break;
+ }
+ free(con);
+ continue;
+ }
+
stats_event_inc(NULL, "connections");
sock_set_blocking(con->sock, SOCK_BLOCK);
<p><p>1.7 +6 -0 icecast/src/connection.h
Index: connection.h
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/connection.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- connection.h 16 Aug 2002 14:26:48 -0000 1.6
+++ connection.h 5 Mar 2003 13:03:35 -0000 1.7
@@ -21,6 +21,10 @@
char *ip;
char *host;
+
+ /* For 'fake' connections */
+ int event_number;
+ void *event;
} connection_t;
void connection_initialize(void);
@@ -30,6 +34,8 @@
connection_t *create_connection(sock_t sock, char *ip);
int connection_create_source(struct _client_tag *client, connection_t *con,
http_parser_t *parser, char *mount);
+
+void connection_inject_event(int eventnum, void *event_data);
extern rwlock_t _source_shutdown_rwlock;
<p><p>1.11 +18 -3 icecast/src/fserve.c
Index: fserve.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/fserve.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- fserve.c 11 Feb 2003 12:18:22 -0000 1.10
+++ fserve.c 5 Mar 2003 13:03:35 -0000 1.11
@@ -78,7 +78,12 @@
void fserve_initialize(void)
{
- if(!config_get_config()->fileserve)
+ ice_config_t *config = config_get_config();
+ int serve = config->fileserve;
+
+ config_release_config();
+
+ if(!serve)
return;
create_mime_mappings(MIMETYPESFILE);
@@ -95,7 +100,12 @@
void fserve_shutdown(void)
{
- if(!config_get_config()->fileserve)
+ ice_config_t *config = config_get_config();
+ int serve = config->fileserve;
+
+ config_release_config();
+
+ if(!serve)
return;
if(!run_fserv)
@@ -345,6 +355,11 @@
{
fserve_t *client = calloc(1, sizeof(fserve_t));
int bytes;
+ int client_limit;
+ ice_config_t *config = config_get_config();
+
+ client_limit = config->client_limit;
+ config_release_config();
client->file = fopen(path, "rb");
if(!client->file) {
@@ -358,7 +373,7 @@
client->buf = malloc(BUFSIZE);
global_lock();
- if(global.clients >= config_get_config()->client_limit) {
+ if(global.clients >= client_limit) {
httpclient->respcode = 504;
bytes = sock_write(httpclient->con->sock,
"HTTP/1.0 504 Server Full\r\n"
<p><p>1.22 +9 -5 icecast/src/main.c
Index: main.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/main.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- main.c 2 Feb 2003 14:26:54 -0000 1.21
+++ main.c 5 Mar 2003 13:03:35 -0000 1.22
@@ -125,7 +125,7 @@
{
char fn_error[FILENAME_MAX];
char fn_access[FILENAME_MAX];
- ice_config_t *config = config_get_config();
+ ice_config_t *config = config_get_config_unlocked();
if(strcmp(config->error_log, "-")) {
snprintf(fn_error, FILENAME_MAX, "%s%s%s", config->log_dir, PATH_SEPARATOR, config->error_log);
@@ -157,9 +157,10 @@
{
ice_config_t *config;
- config = config_get_config();
+ config = config_get_config_unlocked();
global.serversock = sock_get_server_socket(config->port, config->bind_address);
+
if (global.serversock == SOCK_ERROR)
return 0;
@@ -180,7 +181,8 @@
static int _server_proc_init(void)
{
if (!_setup_socket()) {
- fprintf(stderr, "Could not create listener socket on port %d\n", config_get_config()->port);
+ fprintf(stderr, "Could not create listener socket on port %d\n",
+ config_get_config_unlocked()->port);
return 0;
}
@@ -205,7 +207,7 @@
static void _ch_root_uid_setup(void)
{
- ice_config_t *conf = config_get_config();
+ ice_config_t *conf = config_get_config_unlocked();
#ifdef CHUID
struct passwd *user;
struct group *group;
@@ -291,7 +293,9 @@
_initialize_subsystems();
/* parse the config file */
- ret = config_parse_file(filename);
+ config_get_config();
+ ret = config_initial_parse_file(filename);
+ config_release_config();
if (ret < 0) {
fprintf(stderr, "FATAL: error parsing config file:");
switch (ret) {
<p><p>1.3 +12 -5 icecast/src/sighandler.c
Index: sighandler.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/sighandler.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- sighandler.c 22 Nov 2002 13:00:44 -0000 1.2
+++ sighandler.c 5 Mar 2003 13:03:35 -0000 1.3
@@ -10,6 +10,7 @@
#include "refbuf.h"
#include "client.h"
#include "logging.h"
+#include "event.h"
#include "sighandler.h"
@@ -34,16 +35,22 @@
void _sig_hup(int signo)
{
- INFO1("Caught signal %d, rehashing config and reopening logfiles (unimplemented)...", signo);
+ /* We do this elsewhere because it's a bad idea to hang around for too
+ * long re-reading an entire config file inside a signal handler. Bad
+ * practice.
+ */
+
+ INFO1("Caught signal %d, scheduling config reread ...",
+ signo);
/* reread config file */
- /* reopen logfiles */
+ connection_inject_event(EVENT_CONFIG_READ, NULL);
+
+ /* reopen logfiles (TODO: We don't do this currently) */
-#ifdef __linux__
- /* linux requires us to reattach the signal handler */
+ /* some OSes require us to reattach the signal handler */
signal(SIGHUP, _sig_hup);
-#endif
}
void _sig_die(int signo)
<p><p>1.21 +48 -15 icecast/src/slave.c
Index: slave.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/slave.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- slave.c 25 Feb 2003 09:40:34 -0000 1.20
+++ slave.c 5 Mar 2003 13:03:35 -0000 1.21
@@ -49,11 +49,18 @@
static int _initialized = 0;
void slave_initialize(void) {
+ ice_config_t *config;
if (_initialized) return;
+
+ config = config_get_config();
/* Don't create a slave thread if it isn't configured */
- if (config_get_config()->master_server == NULL &&
- config_get_config()->relay == NULL)
+ if (config->master_server == NULL &&
+ config->relay == NULL)
+ {
+ config_release_config();
return;
+ }
+ config_release_config();
_initialized = 1;
_slave_thread_id = thread_create("Slave Thread", _slave_thread, NULL, THREAD_ATTACHED);
@@ -131,28 +138,48 @@
static void *_slave_thread(void *arg) {
sock_t mastersock;
char buf[256];
- int interval = config_get_config()->master_update_interval;
+ int interval;
char *authheader, *data;
int len;
char *username = "relay";
- char *password = config_get_config()->master_password;
+ char *password;
+ int max_interval;
relay_server *relay;
+ ice_config_t *config;
+
+ config = config_get_config();
+
+ password = config->master_password;
+ interval = max_interval = config->master_update_interval;
if(password == NULL)
- password = config_get_config()->source_password;
+ password = config->source_password;
+
+ config_release_config();
while (_initialized) {
- if (config_get_config()->master_update_interval > ++interval) {
+ if (max_interval > ++interval) {
thread_sleep(1000000);
continue;
}
- else
+ else {
+ /* In case it's been reconfigured */
+ config = config_get_config();
+ max_interval = config->master_update_interval;
+ config_release_config();
+
interval = 0;
+ }
+
+ config = config_get_config();
+ if(config->master_server != NULL) {
+ char *server = config->master_server;
+ int port = config->master_server_port;
+ config_release_config();
+
+ mastersock = sock_connect_wto(server, port, 0);
- if(config_get_config()->master_server != NULL) {
- mastersock = sock_connect_wto(config_get_config()->master_server,
- config_get_config()->master_server_port, 0);
if (mastersock == SOCK_ERROR) {
WARN0("Relay slave failed to contact master server to fetch stream list");
continue;
@@ -180,19 +207,23 @@
if (!source_find_mount(buf)) {
avl_tree_unlock(global.source_tree);
- create_relay_stream(
- config_get_config()->master_server,
- config_get_config()->master_server_port,
- buf, NULL, 0);
+ create_relay_stream(server, port, buf, NULL, 0);
}
else
avl_tree_unlock(global.source_tree);
}
sock_close(mastersock);
}
+ else {
+ config_release_config();
+ }
/* And now, we process the individual mounts... */
- relay = config_get_config()->relay;
+ config = config_get_config();
+ relay = config->relay;
+ thread_mutex_lock(&(config_locks()->relay_lock));
+ config_release_config();
+
while(relay) {
avl_tree_rlock(global.source_tree);
if(!source_find_mount(relay->localmount)) {
@@ -205,6 +236,8 @@
avl_tree_unlock(global.source_tree);
relay = relay->next;
}
+
+ thread_mutex_unlock(&(config_locks()->relay_lock));
}
thread_exit(0);
return NULL;
<p><p>1.41 +29 -20 icecast/src/source.c
Index: source.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/source.c,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -r1.40 -r1.41
--- source.c 2 Mar 2003 10:36:24 -0000 1.40
+++ source.c 5 Mar 2003 13:03:35 -0000 1.41
@@ -59,7 +59,6 @@
http_parser_t *parser, const char *mount, format_type_t type,
mount_proxy *mountinfo)
{
- int i = 0;
source_t *src;
src = (source_t *)malloc(sizeof(source_t));
@@ -79,17 +78,6 @@
src->dumpfilename = NULL;
src->dumpfile = NULL;
src->audio_info = util_dict_new();
- for (i=0;i<config_get_config()->num_yp_directories;i++) {
- if (config_get_config()->yp_url[i]) {
- src->ypdata[src->num_yp_directories] = yp_create_ypdata();
- src->ypdata[src->num_yp_directories]->yp_url =
- config_get_config()->yp_url[i];
- src->ypdata[src->num_yp_directories]->yp_url_timeout =
- config_get_config()->yp_url_timeout[i];
- src->ypdata[src->num_yp_directories]->yp_touch_interval = 0;
- src->num_yp_directories++;
- }
- }
if(mountinfo != NULL) {
src->fallback_mount = mountinfo->fallback_mount;
@@ -191,9 +179,31 @@
int suppress_yp = 0;
char *ai;
- long queue_limit = config_get_config()->queue_size_limit;
+ long queue_limit;
+ ice_config_t *config;
+ char *hostname;
+ int port;
+
+ config = config_get_config();
+
+ queue_limit = config->queue_size_limit;
+ timeout = config->source_timeout;
+ hostname = config->hostname;
+ port = config->port;
+
+ for (i=0;i<config->num_yp_directories;i++) {
+ if (config->yp_url[i]) {
+ source->ypdata[source->num_yp_directories] = yp_create_ypdata();
+ source->ypdata[source->num_yp_directories]->yp_url =
+ config->yp_url[i];
+ source->ypdata[source->num_yp_directories]->yp_url_timeout =
+ config->yp_url_timeout[i];
+ source->ypdata[source->num_yp_directories]->yp_touch_interval = 0;
+ source->num_yp_directories++;
+ }
+ }
- timeout = config_get_config()->source_timeout;
+ config_release_config();
/* grab a read lock, to make sure we get a chance to cleanup */
thread_rwlock_rlock(source->shutdown_rwlock);
@@ -273,12 +283,11 @@
}
/* 6 for max size of port */
listen_url_size = strlen("http://") +
- strlen(config_get_config()->hostname) +
+ strlen(hostname) +
strlen(":") + 6 + strlen(source->mount) + 1;
source->ypdata[i]->listen_url = malloc(listen_url_size);
sprintf(source->ypdata[i]->listen_url, "http://%s:%d%s",
- config_get_config()->hostname, config_get_config()->port,
- source->mount);
+ hostname, port, source->mount);
}
if(!suppress_yp) {
@@ -609,15 +618,15 @@
global.sources--;
global_unlock();
+ if(source->dumpfile)
+ fclose(source->dumpfile);
+
/* release our hold on the lock so the main thread can continue cleaning up */
thread_rwlock_unlock(source->shutdown_rwlock);
avl_tree_wlock(global.source_tree);
avl_delete(global.source_tree, source, source_free_source);
avl_tree_unlock(global.source_tree);
-
- if(source->dumpfile)
- fclose(source->dumpfile);
thread_exit(0);
<p><p>1.19 +11 -3 icecast/src/util.c
Index: util.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/util.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- util.c 2 Mar 2003 10:13:59 -0000 1.18
+++ util.c 5 Mar 2003 13:03:35 -0000 1.19
@@ -74,8 +74,11 @@
unsigned long pos;
char c;
ice_config_t *config;
+ int header_timeout;
config = config_get_config();
+ header_timeout = config->header_timeout;
+ config_release_config();
read_bytes = 1;
pos = 0;
@@ -84,7 +87,7 @@
while ((read_bytes == 1) && (pos < (len - 1))) {
read_bytes = 0;
- if (util_timed_wait_for_fd(sock, config->header_timeout*1000) > 0) {
+ if (util_timed_wait_for_fd(sock, header_timeout*1000) > 0) {
if ((read_bytes = recv(sock, &c, 1, 0))) {
if (c != '\r') buff[pos++] = c;
@@ -199,9 +202,14 @@
char *util_get_path_from_normalised_uri(char *uri) {
char *fullpath;
+ char *webroot;
+ ice_config_t *config = config_get_config();
- fullpath = malloc(strlen(uri) + strlen(config_get_config()->webroot_dir) + 1);
- strcpy(fullpath, config_get_config()->webroot_dir);
+ webroot = config->webroot_dir;
+ config_release_config();
+
+ fullpath = malloc(strlen(uri) + strlen(webroot) + 1);
+ strcpy(fullpath, webroot);
strcat(fullpath, uri);
<p><p>1.6 +10 -6 icecast/src/yp.c
Index: yp.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/yp.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- yp.c 26 Feb 2003 23:52:23 -0000 1.5
+++ yp.c 5 Mar 2003 13:03:35 -0000 1.6
@@ -15,14 +15,18 @@
#define CATMODULE "yp"
-int yp_submit_url(int curl_con, char *yp_url, char *url, char *type)
+int yp_submit_url(int curl_con, char *yp_url, char *url, char *type, int i)
{
int ret = 0;
+ int *timeout;
+ ice_config_t *config = config_get_config();
+
+ timeout = config->yp_url_timeout + i;
+ config_release_config();
curl_easy_setopt(curl_get_handle(curl_con), CURLOPT_URL, yp_url);
curl_easy_setopt(curl_get_handle(curl_con), CURLOPT_POSTFIELDS, url);
- curl_easy_setopt(curl_get_handle(curl_con), CURLOPT_TIMEOUT,
- config_get_config()->yp_url_timeout);
+ curl_easy_setopt(curl_get_handle(curl_con), CURLOPT_TIMEOUT, timeout);
/* get it! */
memset(curl_get_result(curl_con), 0, sizeof(struct curl_memory_struct));
@@ -93,7 +97,7 @@
else {
/* specify URL to get */
ret = yp_submit_url(curl_con, source->ypdata[i]->yp_url,
- url, "yp_remove");
+ url, "yp_remove", i);
}
if (url) {
free(url);
@@ -159,7 +163,7 @@
else {
/* specify URL to get */
ret = yp_submit_url(curl_con, source->ypdata[i]->yp_url,
- url, "yp_touch");
+ url, "yp_touch", i);
if (!ret) {
source->ypdata[i]->sid[0] = 0;
}
@@ -291,7 +295,7 @@
else {
/* specify URL to get */
ret = yp_submit_url(curl_con, source->ypdata[i]->yp_url,
- url, "yp_add");
+ url, "yp_add", i);
if (ret) {
if (strlen(curl_get_header_result(curl_con)->sid) > 0) {
<p><p>1.1 icecast/src/event.c
Index: event.c
===================================================================
#include "event.h"
#include "config.h"
#include "refbuf.h"
#include "client.h"
#include "logging.h"
#define CATMODULE "event"
void event_config_read(void *arg)
{
int ret;
ice_config_t *config;
ice_config_t new_config;
/* reread config file */
config = config_get_config(); /* Both to get the lock, and to be able
to find out the config filename */
ret = config_parse_file(config->config_filename, &new_config);
if(ret < 0) {
ERROR0("Error parsing config, not replacing existing config");
switch(ret) {
case CONFIG_EINSANE:
ERROR0("Config filename null or blank");
break;
case CONFIG_ENOROOT:
ERROR1("Root element not found in %s", config->config_filename);
break;
case CONFIG_EBADROOT:
ERROR1("Not an icecast2 config file: %s",
config->config_filename);
break;
default:
ERROR1("Parse error in reading %s", config->config_filename);
break;
}
config_release_config();
}
else {
config_clear(config);
config_set_config(&new_config);
config_release_config();
}
}
<p><p><p>1.1 icecast/src/event.h
Index: event.h
===================================================================
#ifndef __EVENT_H__
#define __EVENT_H__
#define EVENT_NO_EVENT 0
#define EVENT_CONFIG_READ 1
void event_config_read(void *nothing);
#endif /* __EVENT_H__ */
<p><p>--- >8 ----
List archives: http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body. No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.
More information about the commits
mailing list