mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2024-12-04 14:46:30 -05:00
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 svn path=/trunk/icecast/; revision=4406
This commit is contained in:
parent
4c08a155c7
commit
d13ebde7a3
@ -1,5 +1,7 @@
|
||||
(Note: from here on, the changelog generally only includes new features, not
|
||||
bug fixes)
|
||||
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:
|
6
TODO
6
TODO
@ -50,6 +50,8 @@ FEATURES
|
||||
|
||||
- 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?)
|
||||
|
||||
|
@ -8,10 +8,10 @@ bin_PROGRAMS = icecast
|
||||
|
||||
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
|
||||
|
386
src/config.c
386
src/config.c
@ -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(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);
|
||||
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);
|
||||
|
||||
void config_initialize(void)
|
||||
{
|
||||
memset(&_configuration, 0, sizeof(ice_config_t));
|
||||
_set_defaults();
|
||||
_config_filename = NULL;
|
||||
static void create_locks() {
|
||||
thread_mutex_create(&_locks.relay_lock);
|
||||
thread_mutex_create(&_locks.mounts_lock);
|
||||
thread_mutex_create(&_locks.config_lock);
|
||||
}
|
||||
|
||||
void config_shutdown(void)
|
||||
static void release_locks() {
|
||||
thread_mutex_destroy(&_locks.relay_lock);
|
||||
thread_mutex_destroy(&_locks.mounts_lock);
|
||||
thread_mutex_destroy(&_locks.config_lock);
|
||||
}
|
||||
|
||||
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 @@ void config_shutdown(void)
|
||||
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 @@ void config_shutdown(void)
|
||||
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 @@ void config_shutdown(void)
|
||||
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 @@ void config_shutdown(void)
|
||||
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 @@ int config_parse_file(const char *filename)
|
||||
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 @@ int config_parse_cmdline(int arg, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_rehash(void)
|
||||
ice_config_locks *config_locks(void)
|
||||
{
|
||||
return 0;
|
||||
return &_locks;
|
||||
}
|
||||
|
||||
void config_release_config(void)
|
||||
{
|
||||
thread_mutex_unlock(&(_locks.config_lock));
|
||||
}
|
||||
|
||||
ice_config_t *config_get_config(void)
|
||||
{
|
||||
return &_configuration;
|
||||
thread_mutex_lock(&(_locks.config_lock));
|
||||
return &_current_configuration;
|
||||
}
|
||||
|
||||
static void _set_defaults(void)
|
||||
/* 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)
|
||||
{
|
||||
_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;
|
||||
return &_current_configuration;
|
||||
}
|
||||
|
||||
static void _parse_root(xmlDocPtr doc, xmlNodePtr node)
|
||||
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,
|
||||
ice_config_t *configuration)
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
@ -234,13 +291,13 @@ static void _parse_root(xmlDocPtr doc, xmlNodePtr node)
|
||||
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 @@ static void _parse_root(xmlDocPtr doc, xmlNodePtr node)
|
||||
/* 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 @@ static void _parse_limits(xmlDocPtr doc, xmlNodePtr node)
|
||||
|
||||
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 @@ static void _parse_mount(xmlDocPtr doc, xmlNodePtr node)
|
||||
if(last)
|
||||
last->next = mount;
|
||||
else
|
||||
_configuration.mounts = mount;
|
||||
configuration->mounts = mount;
|
||||
|
||||
mount->max_listeners = -1;
|
||||
|
||||
@ -395,11 +454,12 @@ static void _parse_mount(xmlDocPtr doc, xmlNodePtr node)
|
||||
} 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 @@ static void _parse_relay(xmlDocPtr doc, xmlNodePtr node)
|
||||
if(last)
|
||||
last->next = relay;
|
||||
else
|
||||
_configuration.relay = relay;
|
||||
configuration->relay = relay;
|
||||
|
||||
do {
|
||||
if (node == NULL) break;
|
||||
@ -441,7 +501,8 @@ static void _parse_relay(xmlDocPtr doc, xmlNodePtr node)
|
||||
} 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 @@ static void _parse_authentication(xmlDocPtr doc, xmlNodePtr node)
|
||||
/* 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 @@ static void _parse_directory(xmlDocPtr doc, xmlNodePtr node)
|
||||
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 @@ static void _parse_security(xmlDocPtr doc, xmlNodePtr node)
|
||||
|
||||
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 @@ static void _parse_security(xmlDocPtr doc, xmlNodePtr node)
|
||||
} 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 @@ static void _add_server(xmlDocPtr doc, xmlNodePtr node)
|
||||
} 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;
|
||||
|
||||
|
21
src/config.h
21
src/config.h
@ -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 _mount_proxy {
|
||||
|
||||
typedef struct ice_config_tag
|
||||
{
|
||||
char *config_filename;
|
||||
|
||||
char *location;
|
||||
char *admin;
|
||||
|
||||
@ -90,15 +94,30 @@ typedef struct ice_config_tag
|
||||
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__ */
|
||||
|
||||
|
@ -11,7 +11,7 @@ int main(void)
|
||||
|
||||
config_parse_file("icecast.xml");
|
||||
|
||||
config = config_get_config();
|
||||
config = config_get_config_unlocked();
|
||||
|
||||
_dump_config(config);
|
||||
|
||||
|
105
src/connection.c
105
src/connection.c
@ -40,6 +40,7 @@
|
||||
#include "geturl.h"
|
||||
#include "format.h"
|
||||
#include "format_mp3.h"
|
||||
#include "event.h"
|
||||
|
||||
#define CATMODULE "connection"
|
||||
|
||||
@ -112,6 +113,10 @@ connection_t *create_connection(sock_t sock, char *ip) {
|
||||
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 @@ static void _build_pool(void)
|
||||
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 @@ static connection_t *_get_connection(void)
|
||||
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 @@ int connection_create_source(client_t *client, connection_t *con, http_parser_t
|
||||
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 @@ int connection_create_source(client_t *client, connection_t *con, http_parser_t
|
||||
|
||||
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 @@ int connection_create_source(client_t *client, connection_t *con, http_parser_t
|
||||
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_pass_ice(http_parser_t *parser, char *correctpass)
|
||||
|
||||
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_admin_pass(http_parser_t *parser)
|
||||
|
||||
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 @@ static int _check_source_pass(http_parser_t *parser, char *mount)
|
||||
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 @@ static void _handle_get_request(connection_t *con,
|
||||
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 @@ static void _handle_get_request(connection_t *con,
|
||||
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 @@ static void _handle_get_request(connection_t *con,
|
||||
"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 @@ static void _handle_get_request(connection_t *con,
|
||||
}
|
||||
|
||||
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 @@ static void _handle_get_request(connection_t *con,
|
||||
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 @@ static void *_handle_connection(void *arg)
|
||||
|
||||
/* 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);
|
||||
|
@ -21,6 +21,10 @@ typedef struct connection_tag
|
||||
|
||||
char *ip;
|
||||
char *host;
|
||||
|
||||
/* For 'fake' connections */
|
||||
int event_number;
|
||||
void *event;
|
||||
} connection_t;
|
||||
|
||||
void connection_initialize(void);
|
||||
@ -31,6 +35,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;
|
||||
|
||||
#endif /* __CONNECTION_H__ */
|
||||
|
46
src/event.c
Normal file
46
src/event.c
Normal file
@ -0,0 +1,46 @@
|
||||
#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();
|
||||
}
|
||||
}
|
||||
|
9
src/event.h
Normal file
9
src/event.h
Normal file
@ -0,0 +1,9 @@
|
||||
#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__ */
|
21
src/fserve.c
21
src/fserve.c
@ -78,7 +78,12 @@ static void create_mime_mappings(char *fn);
|
||||
|
||||
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_initialize(void)
|
||||
|
||||
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 @@ int fserve_client_create(client_t *httpclient, char *path)
|
||||
{
|
||||
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 @@ int fserve_client_create(client_t *httpclient, char *path)
|
||||
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"
|
||||
|
14
src/main.c
14
src/main.c
@ -125,7 +125,7 @@ static int _start_logging(void)
|
||||
{
|
||||
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 @@ static int _setup_socket(void)
|
||||
{
|
||||
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 _start_listening(void)
|
||||
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 _server_proc(void)
|
||||
|
||||
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 @@ int main(int argc, char **argv)
|
||||
_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) {
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "refbuf.h"
|
||||
#include "client.h"
|
||||
#include "logging.h"
|
||||
#include "event.h"
|
||||
|
||||
#include "sighandler.h"
|
||||
|
||||
@ -34,16 +35,22 @@ void sighandler_initialize(void)
|
||||
|
||||
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)
|
||||
|
65
src/slave.c
65
src/slave.c
@ -49,11 +49,18 @@ thread_type *_slave_thread_id;
|
||||
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 create_relay_stream(char *server, int port,
|
||||
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
|
||||
interval = 0;
|
||||
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 @@ static void *_slave_thread(void *arg) {
|
||||
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 @@ static void *_slave_thread(void *arg) {
|
||||
avl_tree_unlock(global.source_tree);
|
||||
relay = relay->next;
|
||||
}
|
||||
|
||||
thread_mutex_unlock(&(config_locks()->relay_lock));
|
||||
}
|
||||
thread_exit(0);
|
||||
return NULL;
|
||||
|
49
src/source.c
49
src/source.c
@ -59,7 +59,6 @@ source_t *source_create(client_t *client, connection_t *con,
|
||||
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 @@ source_t *source_create(client_t *client, connection_t *con,
|
||||
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 @@ void *source_main(void *arg)
|
||||
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;
|
||||
|
||||
timeout = config_get_config()->source_timeout;
|
||||
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++;
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ void *source_main(void *arg)
|
||||
}
|
||||
/* 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,6 +618,9 @@ done:
|
||||
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);
|
||||
|
||||
@ -616,9 +628,6 @@ done:
|
||||
avl_delete(global.source_tree, source, source_free_source);
|
||||
avl_tree_unlock(global.source_tree);
|
||||
|
||||
if(source->dumpfile)
|
||||
fclose(source->dumpfile);
|
||||
|
||||
thread_exit(0);
|
||||
|
||||
return NULL;
|
||||
|
14
src/util.c
14
src/util.c
@ -74,8 +74,11 @@ int util_read_header(int sock, char *buff, unsigned long len)
|
||||
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 @@ int util_read_header(int sock, char *buff, unsigned long len)
|
||||
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_uri(char *uri) {
|
||||
|
||||
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);
|
||||
|
||||
|
16
src/yp.c
16
src/yp.c
@ -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 @@ int yp_remove(source_t *source)
|
||||
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 @@ int yp_touch(source_t *source)
|
||||
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 @@ int yp_add(source_t *source, int which)
|
||||
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) {
|
||||
|
Loading…
Reference in New Issue
Block a user