diff --git a/TODO b/TODO
index 0ab9cfaa..a3d97ff5 100644
--- a/TODO
+++ b/TODO
@@ -8,6 +8,8 @@ BUGS
- make install - doesn't install configs?
+- pthread/bsd: -pthread instead of -lpthread (autoconf)
+
FEATURES
--------
@@ -30,4 +32,24 @@ FEATURES
- stats to list currently connected clients: ip and hostname
+- stream switching (drop clients to another stream on disconnect of source)
+ - a) fallbacks from named location to new mountpoint
+ - OR b) fallbacks for connected clients to new mountpoint (so newly-connecting
+ clients just get a 404 on the old path)
+ - OR c) combination - first one, plus generic alias ability?
+
+- /admin/* for all admin functionality
+ - configuring fallbacks
+ - mp3 metadata injection
+ - remote shutdown?
+
+- general registerable url-handlers in connection.c rather than hard-coded list
+ (already getting unmaintainable)
+
+- httpp - split out query string for further processing
+
+- finish mp3 metadata: http://server:ip/admin.cgi?pass=%s&mode=updinfo&mount=%s&song=%s
+
+
+
diff --git a/conf/icecast.xml b/conf/icecast.xml
index e9eafaf3..a6fb5c8b 100644
--- a/conf/icecast.xml
+++ b/conf/icecast.xml
@@ -11,12 +11,23 @@
10
- hackme
- hackme
+
+
+ hackme
+
+ hackme
-
- http://www.oddsock.org/cgi-bin/yp-cgi
-
+
+ admin
+ hackme
+
+
+
+
localhost
8000
@@ -30,15 +41,15 @@
1
- /usr/local/icecast2
- /usr/local/icecast2/logs
- /usr/local/icecast2/web
+ /usr/local/icecast
+ /usr/local/icecast/logs
+ /usr/local/icecast/web
access.log
error.log
- 4
+ 4
diff --git a/src/config.c b/src/config.c
index 0681b96b..4bbe1d61 100644
--- a/src/config.c
+++ b/src/config.c
@@ -54,6 +54,7 @@ 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 _add_server(xmlDocPtr doc, xmlNodePtr node);
void config_initialize(void)
@@ -171,7 +172,7 @@ static void _set_defaults(void)
_configuration.relay_password = CONFIG_DEFAULT_RELAY_PASSWORD;
_configuration.ice_login = CONFIG_DEFAULT_ICE_LOGIN;
_configuration.fileserve = CONFIG_DEFAULT_FILESERVE;
- _configuration.touch_freq = CONFIG_DEFAULT_TOUCH_FREQ;
+ _configuration.touch_interval = CONFIG_DEFAULT_TOUCH_FREQ;
_configuration.dir_list = NULL;
_configuration.hostname = CONFIG_DEFAULT_HOSTNAME;
_configuration.port = CONFIG_DEFAULT_PORT;
@@ -207,7 +208,10 @@ static void _parse_root(xmlDocPtr doc, xmlNodePtr node)
} 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);
- } else if (strcmp(node->name, "source-password") == 0) {
+ } else if(strcmp(node->name, "authentication") == 0) {
+ _parse_authentication(doc, node->xmlChildrenNode);
+ } else if (strcmp(node->name, "source-password") == 0) {
+ /* TODO: This is the backwards-compatibility location */
char *mount, *pass;
if ((mount = (char *)xmlGetProp(node, "mount")) != NULL) {
pass = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
@@ -218,8 +222,9 @@ static void _parse_root(xmlDocPtr doc, xmlNodePtr node)
_configuration.source_password = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
}
} else if (strcmp(node->name, "relay-password") == 0) {
- if (_configuration.relay_password && _configuration.relay_password != CONFIG_DEFAULT_RELAY_PASSWORD) xmlFree(_configuration.relay_password);
- _configuration.relay_password = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+ /* 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);
} else if (strcmp(node->name, "icelogin") == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
_configuration.ice_login = atoi(tmp);
@@ -300,6 +305,47 @@ static void _parse_limits(xmlDocPtr doc, xmlNodePtr node)
} while ((node = node->next));
}
+static void _parse_authentication(xmlDocPtr doc, xmlNodePtr node)
+{
+ do {
+ if (node == NULL) break;
+ if (xmlIsBlankNode(node)) continue;
+
+ if (strcmp(node->name, "source-password") == 0) {
+ char *mount, *pass;
+ if ((mount = (char *)xmlGetProp(node, "mount")) != NULL) {
+ pass = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+ /* FIXME: This is a placeholder for per-mount passwords */
+ }
+ else {
+ if (_configuration.source_password &&
+ _configuration.source_password !=
+ CONFIG_DEFAULT_SOURCE_PASSWORD)
+ xmlFree(_configuration.source_password);
+ _configuration.source_password =
+ (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+ }
+ } else if (strcmp(node->name, "relay-password") == 0) {
+ 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, "admin-password") == 0) {
+ 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 =
+ (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+ }
+ } while ((node = node->next));
+}
+
static void _parse_directory(xmlDocPtr doc, xmlNodePtr node)
{
char *tmp;
@@ -313,16 +359,19 @@ 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] = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+ 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] = atoi(tmp);
+ _configuration.yp_url_timeout[_configuration.num_yp_directories] =
+ atoi(tmp);
} else if (strcmp(node->name, "server") == 0) {
_add_server(doc, node->xmlChildrenNode);
- } else if (strcmp(node->name, "touch-freq") == 0) {
+ } else if (strcmp(node->name, "touch-interval") == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- _configuration.touch_freq = atoi(tmp);
+ _configuration.touch_interval = atoi(tmp);
if (tmp) xmlFree(tmp);
}
} while ((node = node->next));
@@ -411,7 +460,7 @@ static void _add_server(xmlDocPtr doc, xmlNodePtr node)
char *tmp;
server = (ice_config_dir_t *)malloc(sizeof(ice_config_dir_t));
- server->touch_freq = _configuration.touch_freq;
+ server->touch_interval = _configuration.touch_interval;
server->host = NULL;
addnode = 0;
@@ -420,11 +469,12 @@ static void _add_server(xmlDocPtr doc, xmlNodePtr node)
if (xmlIsBlankNode(node)) continue;
if (strcmp(node->name, "host") == 0) {
- server->host = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+ server->host = (char *)xmlNodeListGetString(doc,
+ node->xmlChildrenNode, 1);
addnode = 1;
- } else if (strcmp(node->name, "touch-freq") == 0) {
+ } else if (strcmp(node->name, "touch-interval") == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
- server->touch_freq = atoi(tmp);
+ server->touch_interval = atoi(tmp);
if (tmp) xmlFree(tmp);
}
server->next = NULL;
diff --git a/src/config.h b/src/config.h
index a91f9400..ee620335 100644
--- a/src/config.h
+++ b/src/config.h
@@ -11,7 +11,7 @@
typedef struct ice_config_dir_tag
{
char *host;
- int touch_freq;
+ int touch_interval;
struct ice_config_dir_tag *next;
} ice_config_dir_t;
@@ -31,8 +31,10 @@ typedef struct ice_config_tag
char *source_password;
char *relay_password;
+ char *admin_username;
+ char *admin_password;
- int touch_freq;
+ int touch_interval;
ice_config_dir_t *dir_list;
char *hostname;
diff --git a/src/configtest.c b/src/configtest.c
index fa17d3dc..e98f8885 100644
--- a/src/configtest.c
+++ b/src/configtest.c
@@ -32,11 +32,11 @@ void _dump_config(ice_config_t *config)
printf("threadpool_size = %d\n", config->threadpool_size);
printf("client_timeout = %d\n", config->client_timeout);
printf("source_password = %s\n", config->source_password);
- printf("touch_freq = %d\n", config->touch_freq);
+ printf("touch_interval = %d\n", config->touch_interval);
node = config->dir_list;
while (node) {
- printf("directory.touch_freq = %d\n", node->touch_freq);
+ printf("directory.touch_interval = %d\n", node->touch_interval);
printf("directory.host = %s\n", node->host);
node = node->next;
diff --git a/src/connection.c b/src/connection.c
index ec123f15..553913da 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -404,7 +404,17 @@ static int _check_relay_pass(http_parser_t *parser)
return _check_pass_http(parser, "relay", pass);
}
-static int _check_source_pass(http_parser_t *parser)
+static int _check_admin_pass(http_parser_t *parser)
+{
+ char *pass = config_get_config()->admin_password;
+ char *user = config_get_config()->admin_username;
+ if(!pass || !user)
+ return 0;
+
+ return _check_pass_http(parser, "admin", pass);
+}
+
+static int _check_source_pass(http_parser_t *parser, char *mount)
{
char *pass = config_get_config()->source_password;
int ret;
@@ -428,15 +438,15 @@ static void handle_fallback_request(client_t *client)
char *mount, *value, *old;
int bytes;
- if(!_check_source_pass(client->parser)) {
+ mount = httpp_get_query_param(client->parser, "mount");
+ value = httpp_get_query_param(client->parser, "fallback");
+
+ if(!_check_source_pass(client->parser, mount)) {
INFO0("Bad or missing password on fallback configuration request");
client_send_401(client);
return;
}
- mount = httpp_get_query_param(client->parser, "mount");
- value = httpp_get_query_param(client->parser, "fallback");
-
if(value == NULL || mount == NULL) {
client_send_400(client, "Missing parameter");
return;
@@ -472,16 +482,16 @@ static void handle_metadata_request(client_t *client)
mp3_state *state;
int bytes;
- if(!_check_source_pass(client->parser)) {
+ action = httpp_get_query_param(client->parser, "mode");
+ mount = httpp_get_query_param(client->parser, "mount");
+ value = httpp_get_query_param(client->parser, "song");
+
+ if(!_check_source_pass(client->parser, mount)) {
INFO0("Metadata request with wrong or missing password");
client_send_401(client);
return;
}
- action = httpp_get_query_param(client->parser, "mode");
- mount = httpp_get_query_param(client->parser, "mount");
- value = httpp_get_query_param(client->parser, "song");
-
if(value == NULL || action == NULL || mount == NULL) {
client_send_400(client, "Missing parameter");
return;
@@ -533,7 +543,7 @@ static void _handle_source_request(connection_t *con,
INFO1("Source logging in at mountpoint \"%s\"", uri);
stats_event_inc(NULL, "source_connections");
- if (!_check_source_pass(parser)) {
+ if (!_check_source_pass(parser, uri)) {
INFO1("Source (%s) attempted to login with invalid or missing password", uri);
client_send_401(client);
return;
@@ -564,7 +574,7 @@ static void _handle_stats_request(connection_t *con,
stats_event_inc(NULL, "stats_connections");
- if (!_check_source_pass(parser)) {
+ if (!_check_admin_pass(parser)) {
ERROR0("Bad password for stats connection");
connection_close(con);
httpp_destroy(parser);
@@ -606,7 +616,7 @@ static void _handle_get_request(connection_t *con,
*/
/* TODO: add GUID-xxxxxx */
if (strcmp(uri, "/admin/stats.xml") == 0) {
- if (!_check_source_pass(parser)) {
+ if (!_check_admin_pass(parser)) {
INFO0("Request for /admin/stats.xml with incorrect or no password");
client_send_401(client);
return;
diff --git a/src/fserve.c b/src/fserve.c
index 41b439b5..35b5d84c 100644
--- a/src/fserve.c
+++ b/src/fserve.c
@@ -226,7 +226,7 @@ static void *fserv_thread_function(void *arg)
&client->buf[client->offset],
client->datasize - client->offset);
- // TODO: remove clients if they take too long.
+ /* TODO: remove clients if they take too long. */
if(sbytes >= 0) {
client->offset += sbytes;
client->client->con->sent_bytes += sbytes;
diff --git a/src/geturl.c b/src/geturl.c
index afc47552..76fbc5e3 100644
--- a/src/geturl.c
+++ b/src/geturl.c
@@ -1,5 +1,6 @@
#include
#include
+#include
#include
@@ -20,10 +21,10 @@
#define CATMODULE "geturl"
static curl_connection curl_connections[NUM_CONNECTIONS];
-mutex_t _curl_mutex;
+static mutex_t _curl_mutex;
-size_t
-curl_write_memory_callback(void *ptr, size_t size, size_t nmemb, void *data)
+size_t curl_write_memory_callback(void *ptr, size_t size,
+ size_t nmemb, void *data)
{
register int realsize = size * nmemb;
@@ -35,8 +36,9 @@ curl_write_memory_callback(void *ptr, size_t size, size_t nmemb, void *data)
return realsize;
}
-size_t
-curl_header_memory_callback(void *ptr, size_t size, size_t nmemb, void *data)
+
+size_t curl_header_memory_callback(void *ptr, size_t size,
+ size_t nmemb, void *data)
{
char *p1 = 0;
char *p2 = 0;
@@ -48,19 +50,18 @@ curl_header_memory_callback(void *ptr, size_t size, size_t nmemb, void *data)
p1 = (char *)ptr + strlen("SID: ");
p2 = strchr((const char *)p1, '\r');
memset(mem->sid, '\000', sizeof(mem->sid));
- if (p2) {
- if (p2-p1 > sizeof(mem->sid)-1) {
- copylen = sizeof(mem->sid)-1;
- }
- else {
- copylen = p2-p1;
- }
- strncpy(mem->sid, p1, copylen);
+ if (p2) {
+ if (p2-p1 > sizeof(mem->sid)-1) {
+ copylen = sizeof(mem->sid)-1;
}
else {
- strncpy(mem->sid, p1, sizeof(mem->sid)-1);
- strcpy(mem->sid, p1);
+ copylen = p2-p1;
}
+ strncpy(mem->sid, p1, copylen);
+ }
+ else {
+ strncpy(mem->sid, p1, sizeof(mem->sid)-1);
+ }
}
if (!strncmp(ptr, "YPMessage: ", strlen("YPMessage: "))) {
p1 = (char *)ptr + strlen("YPMessage: ");
@@ -77,12 +78,11 @@ curl_header_memory_callback(void *ptr, size_t size, size_t nmemb, void *data)
}
else {
strncpy(mem->message, p1, sizeof(mem->message)-1);
- strcpy(mem->message, p1);
}
}
if (!strncmp(ptr, "TouchFreq: ", strlen("TouchFreq: "))) {
p1 = (char *)ptr + strlen("TouchFreq: ");
- mem->touch_freq = atoi(p1);
+ mem->touch_interval = atoi(p1);
}
if (!strncmp(ptr, "YPResponse: ", strlen("YPResponse: "))) {
p1 = (char *)ptr + strlen("YPResponse: ");
@@ -95,13 +95,14 @@ int curl_initialize()
int i = 0;
thread_mutex_create(&_curl_mutex);
- memset(&curl_connections, '\000', sizeof(curl_connections));
+ memset(&curl_connections, 0, sizeof(curl_connections));
for (i=0; i (%s)", mem->sid);
DEBUG1("Message -> (%s)", mem->message);
- DEBUG1("Touch Freq -> (%d)", mem->touch_freq);
+ DEBUG1("Touch Freq -> (%d)", mem->touch_interval);
DEBUG1("Response -> (%d)", mem->response);
}
@@ -164,6 +165,7 @@ CURL *curl_get_handle(int which)
{
return curl_connections[which].curl_handle;
}
+
struct curl_memory_struct *curl_get_result(int which)
{
return &(curl_connections[which].result);
@@ -173,3 +175,4 @@ struct curl_memory_struct2 *curl_get_header_result(int which)
{
return &(curl_connections[which].header_result);
}
+
diff --git a/src/geturl.h b/src/geturl.h
index 396773f3..51606639 100644
--- a/src/geturl.h
+++ b/src/geturl.h
@@ -20,7 +20,7 @@ struct curl_memory_struct {
struct curl_memory_struct2 {
char sid[YP_SID_SIZE];
char message[YP_RESPONSE_SIZE];
- int touch_freq;
+ int touch_interval;
int response;
size_t size;
};
@@ -41,5 +41,6 @@ struct curl_memory_struct2 *curl_get_header_result(int which);
void curl_print_header_result(struct curl_memory_struct2 *mem);
int curl_get_connection();
int curl_release_connection(int which);
+
#endif
diff --git a/src/net/sock.c b/src/net/sock.c
index ab5dbec1..6b8feee3 100644
--- a/src/net/sock.c
+++ b/src/net/sock.c
@@ -665,7 +665,7 @@ int sock_accept(sock_t serversock, char *ip, int len)
ret = accept(serversock, (struct sockaddr *)&sin, &slen);
if (ret >= 0 && ip != NULL) {
- // inet_ntoa is not reentrant, we should protect this
+ /* inet_ntoa is not reentrant, we should protect this */
strncpy(ip, inet_ntoa(sin.sin_addr), len);
sock_set_nolinger(ret);
sock_set_keepalive(ret);
diff --git a/src/net/sock.h b/src/net/sock.h
index 42cf278a..fa0d261c 100644
--- a/src/net/sock.h
+++ b/src/net/sock.h
@@ -42,6 +42,10 @@ struct iovec
#endif
#endif
+#ifdef HAVE_INET_PTON
+#define inet_aton(a,b) inet_pton(AF_INET, (a), (b))
+#endif
+
typedef int sock_t;
/* The following values are based on unix avoiding errno value clashes */
diff --git a/src/source.c b/src/source.c
index cc82c955..f4f799f3 100644
--- a/src/source.c
+++ b/src/source.c
@@ -53,14 +53,17 @@ source_t *source_create(client_t *client, connection_t *con, http_parser_t *pars
src->parser = parser;
src->client_tree = avl_tree_new(_compare_clients, NULL);
src->pending_tree = avl_tree_new(_compare_clients, NULL);
+ src->running = 1;
src->num_yp_directories = 0;
src->listeners = 0;
for (i=0;inum_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_freq = 0;
+ 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++;
}
}
@@ -136,17 +139,15 @@ void *source_main(void *arg)
client_t *client;
avl_node *client_node;
char *s;
- long currentTime = 0;
- char current_song[256];
- char prev_current_song[256];
+ long current_time;
+ char current_song[256];
refbuf_t *refbuf, *abuf;
int data_done;
int listeners = 0;
- int listen_url_size = 0;
int i=0;
- int list_on_yp = 0;
+ int suppress_yp = 0;
timeout = config_get_config()->source_timeout;
@@ -169,8 +170,7 @@ void *source_main(void *arg)
if (source->ypdata[i]->server_name) {
free(source->ypdata[i]->server_name);
}
- source->ypdata[i]->server_name = (char *)malloc(strlen(s) +1);
- memset(source->ypdata[i]->server_name, '\000', strlen(s) + 1);
+ source->ypdata[i]->server_name = malloc(strlen(s) +1);
strcpy(source->ypdata[i]->server_name, s);
}
stats_event(source->mount, "name", s);
@@ -180,8 +180,7 @@ void *source_main(void *arg)
if (source->ypdata[i]->server_url) {
free(source->ypdata[i]->server_url);
}
- source->ypdata[i]->server_url = (char *)malloc(strlen(s) +1);
- memset(source->ypdata[i]->server_url, '\000', strlen(s) + 1);
+ source->ypdata[i]->server_url = malloc(strlen(s) +1);
strcpy(source->ypdata[i]->server_url, s);
}
stats_event(source->mount, "url", s);
@@ -191,8 +190,7 @@ void *source_main(void *arg)
if (source->ypdata[i]->server_genre) {
free(source->ypdata[i]->server_genre);
}
- source->ypdata[i]->server_genre = (char *)malloc(strlen(s) +1);
- memset(source->ypdata[i]->server_genre, '\000', strlen(s) + 1);
+ source->ypdata[i]->server_genre = malloc(strlen(s) +1);
strcpy(source->ypdata[i]->server_genre, s);
}
stats_event(source->mount, "genre", s);
@@ -202,8 +200,7 @@ void *source_main(void *arg)
if (source->ypdata[i]->bitrate) {
free(source->ypdata[i]->bitrate);
}
- source->ypdata[i]->bitrate = (char *)malloc(strlen(s) +1);
- memset(source->ypdata[i]->bitrate, '\000', strlen(s) + 1);
+ source->ypdata[i]->bitrate = malloc(strlen(s) +1);
strcpy(source->ypdata[i]->bitrate, s);
}
stats_event(source->mount, "bitrate", s);
@@ -213,78 +210,97 @@ void *source_main(void *arg)
if (source->ypdata[i]->server_desc) {
free(source->ypdata[i]->server_desc);
}
- source->ypdata[i]->server_desc = (char *)malloc(strlen(s) +1);
- memset(source->ypdata[i]->server_desc, '\000', strlen(s) + 1);
+ source->ypdata[i]->server_desc = malloc(strlen(s) +1);
strcpy(source->ypdata[i]->server_desc, s);
}
stats_event(source->mount, "description", s);
}
- if ((s = httpp_getvar(source->parser, "ice-public"))) {
+ if ((s = httpp_getvar(source->parser, "ice-private"))) {
stats_event(source->mount, "public", s);
- list_on_yp = atoi(s);
+ suppress_yp = atoi(s);
}
for (i=0;inum_yp_directories;i++) {
if (source->ypdata[i]->server_type) {
free(source->ypdata[i]->server_type);
}
- source->ypdata[i]->server_type = (char *)malloc(strlen(source->format->format_description) +1);
- memset(source->ypdata[i]->server_type, '\000', strlen(source->format->format_description) + 1);
- strcpy(source->ypdata[i]->server_type, source->format->format_description);
+ source->ypdata[i]->server_type = malloc(
+ strlen(source->format->format_description) + 1);
+ strcpy(source->ypdata[i]->server_type,
+ source->format->format_description);
}
stats_event(source->mount, "type", source->format->format_description);
for (i=0;inum_yp_directories;i++) {
+ int listen_url_size;
if (source->ypdata[i]->listen_url) {
free(source->ypdata[i]->listen_url);
}
- // 6 for max size of port
- listen_url_size = strlen("http://") + strlen(config_get_config()->hostname) + strlen(":") + 6 + strlen(source->mount) + 1;
- source->ypdata[i]->listen_url = (char *)malloc(listen_url_size);
- memset(source->ypdata[i]->listen_url, '\000', listen_url_size);
- sprintf(source->ypdata[i]->listen_url, "http://%s:%d%s", config_get_config()->hostname, config_get_config()->port, source->mount);
+ /* 6 for max size of port */
+ listen_url_size = strlen("http://") +
+ strlen(config_get_config()->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);
}
- if (list_on_yp) {
- yp_add(source, YP_ADD_ALL);
- }
- time(¤tTime);
- for (i=0;inum_yp_directories;i++) {
- source->ypdata[i]->yp_last_touch = currentTime;
- if (source->ypdata[i]->yp_touch_freq == 0) {
- source->ypdata[i]->yp_touch_freq = 30;
- }
- }
+ if(!suppress_yp) {
+ yp_add(source, YP_ADD_ALL);
- while (global.running == ICE_RUNNING) {
- time(¤tTime);
- if (list_on_yp) {
+ current_time = time(NULL);
+
+ for (i=0;inum_yp_directories;i++) {
+ source->ypdata[i]->yp_last_touch = current_time;
+ /* Don't permit touch intervals of less than 30 seconds */
+ if (source->ypdata[i]->yp_touch_interval <= 30) {
+ source->ypdata[i]->yp_touch_interval = 30;
+ }
+ }
+ }
+
+ while (global.running == ICE_RUNNING && source->running) {
+ if(!suppress_yp) {
+ current_time = time(NULL);
for (i=0;inum_yp_directories;i++) {
- if (currentTime > (source->ypdata[i]->yp_last_touch + source->ypdata[i]->yp_touch_freq)) {
- memset(current_song, '\000', sizeof(current_song));
+ if (current_time > (source->ypdata[i]->yp_last_touch +
+ source->ypdata[i]->yp_touch_interval)) {
+ current_song[0] = 0;
if (stats_get_value(source->mount, "artist")) {
- strncat(current_song, stats_get_value(source->mount, "artist"), sizeof(current_song) - 1);
+ strncat(current_song,
+ stats_get_value(source->mount, "artist"),
+ sizeof(current_song) - 1);
if (strlen(current_song) + 4 < sizeof(current_song)) {
strncat(current_song, " - ", 3);
}
}
if (stats_get_value(source->mount, "title")) {
- if (strlen(current_song) + strlen(stats_get_value(source->mount, "title")) < sizeof(current_song) -1) {
- strncat(current_song, stats_get_value(source->mount, "title"), sizeof(current_song) -1 - strlen(current_song));
+ if (strlen(current_song) +
+ strlen(stats_get_value(source->mount, "title"))
+ < sizeof(current_song) -1)
+ {
+ strncat(current_song,
+ stats_get_value(source->mount, "title"),
+ sizeof(current_song) - 1 -
+ strlen(current_song));
}
}
+
if (source->ypdata[i]->current_song) {
free(source->ypdata[i]->current_song);
source->ypdata[i]->current_song = NULL;
}
- source->ypdata[i]->current_song = (char *)malloc(strlen(current_song) + 1);
- memset(source->ypdata[i]->current_song, '\000', strlen(current_song) + 1);
+ source->ypdata[i]->current_song =
+ malloc(strlen(current_song) + 1);
strcpy(source->ypdata[i]->current_song, current_song);
- thread_create("YP Touch Thread", yp_touch_thread, (void *)source, THREAD_DETACHED);
+ thread_create("YP Touch Thread", yp_touch_thread,
+ (void *)source, THREAD_DETACHED);
}
}
}
+
ret = source->format->get_buffer(source->format, NULL, 0, &refbuf);
if(ret < 0) {
WARN0("Bad data from source");
@@ -486,7 +502,7 @@ void *source_main(void *arg)
done:
DEBUG0("Source exiting");
- if (list_on_yp) {
+ if(!suppress_yp) {
yp_remove(source);
}
@@ -502,7 +518,7 @@ done:
if(fallback_source) {
avl_delete(source->pending_tree, client, _remove_client);
- // TODO: reset client local format data?
+ /* TODO: reset client local format data? */
avl_tree_wlock(fallback_source->pending_tree);
avl_insert(fallback_source->pending_tree, (void *)client);
avl_tree_unlock(fallback_source->pending_tree);
@@ -520,7 +536,7 @@ done:
if(fallback_source) {
avl_delete(source->client_tree, client, _remove_client);
- // TODO: reset client local format data?
+ /* TODO: reset client local format data? */
avl_tree_wlock(fallback_source->pending_tree);
avl_insert(fallback_source->pending_tree, (void *)client);
avl_tree_unlock(fallback_source->pending_tree);
@@ -580,3 +596,4 @@ static int _free_client(void *key)
return 1;
}
+
diff --git a/src/source.h b/src/source.h
index 53b18fde..72474711 100644
--- a/src/source.h
+++ b/src/source.h
@@ -16,6 +16,10 @@ typedef struct source_tag
/* If this source drops, try to move all clients to this fallback */
char *fallback_mount;
+ /* set to zero to request the source to shutdown without causing a global
+ * shutdown */
+ int running;
+
struct _format_plugin_tag *format;
avl_tree *client_tree;
diff --git a/src/stats.c b/src/stats.c
index b4b61436..a3fe7d84 100644
--- a/src/stats.c
+++ b/src/stats.c
@@ -126,13 +126,13 @@ void stats_shutdown()
stats_t *stats_get_stats()
{
- // lock global stats
+ /* lock global stats
- // copy stats
+ copy stats
- // unlock global stats
+ unlock global stats
- // return copied stats
+ return copied stats */
return NULL;
}
diff --git a/src/yp.c b/src/yp.c
index bcf20a64..0447a6be 100644
--- a/src/yp.c
+++ b/src/yp.c
@@ -1,5 +1,6 @@
#include
#include
+#include
#include
@@ -20,11 +21,13 @@ int yp_submit_url(int curl_con, char *yp_url, char *url, char *type)
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,
+ config_get_config()->yp_url_timeout);
/* get it! */
- memset(curl_get_result(curl_con), '\000', sizeof(struct curl_memory_struct));
- memset(curl_get_header_result(curl_con), '\000', sizeof(struct curl_memory_struct2));
+ memset(curl_get_result(curl_con), 0, sizeof(struct curl_memory_struct));
+ memset(curl_get_header_result(curl_con), 0,
+ sizeof(struct curl_memory_struct2));
curl_easy_perform(curl_get_handle(curl_con));
@@ -36,7 +39,8 @@ int yp_submit_url(int curl_con, char *yp_url, char *url, char *type)
}
else {
if (strlen(curl_get_header_result(curl_con)->message) > 0) {
- ERROR3("Got a NAK from %s(%s) (%s)", type,curl_get_header_result(curl_con)->message, yp_url);
+ ERROR3("Got a NAK from %s(%s) (%s)", type,
+ curl_get_header_result(curl_con)->message, yp_url);
}
else {
ERROR2("Got a NAK from %s(Unknown) (%s)", type, yp_url);
@@ -52,18 +56,16 @@ void *yp_touch_thread(void *arg)
thread_exit(0);
return NULL;
}
-int yp_remove(void *psource)
+
+int yp_remove(source_t *source)
{
char *url = NULL;
int url_size = 0;
int ret = 0;
int curl_con = 0;
- char *p1 = NULL;
int i = 0;
- int regen_sid = 0;
long current_time = 0;
- source_t *source = (source_t *)psource;
current_time = time(¤t_time);
@@ -81,17 +83,17 @@ int yp_remove(void *psource)
url_size = strlen("action=remove&sid=") + 1;
url_size += strlen(source->ypdata[i]->sid);
url_size += 1024;
- url = (char *)malloc(url_size);
- memset(url, '\000', url_size);
+ url = malloc(url_size);
sprintf(url, "action=remove&sid=%s",
- source->ypdata[i]->sid);
+ source->ypdata[i]->sid);
curl_con = curl_get_connection();
if (curl_con < 0) {
ERROR0("Unable to get auth connection");
}
else {
- /* specify URL to get */
- ret = yp_submit_url(curl_con, source->ypdata[i]->yp_url, url, "yp_remove");
+ /* specify URL to get */
+ ret = yp_submit_url(curl_con, source->ypdata[i]->yp_url,
+ url, "yp_remove");
}
if (url) {
free(url);
@@ -101,19 +103,17 @@ int yp_remove(void *psource)
}
return 1;
}
-int yp_touch(void *psource)
+int yp_touch(source_t *source)
{
char *url = NULL;
int url_size = 0;
int ret = 0;
int curl_con = 0;
- char *p1 = NULL;
int i = 0;
int regen_sid = 0;
long current_time = 0;
- source_t *source = (source_t *)psource;
- current_time = time(¤t_time);
+ current_time = time(NULL);
for (i=0; inum_yp_directories; i++) {
source->ypdata[i]->yp_last_touch = current_time;
if (source->ypdata[i]->sid == 0) {
@@ -136,32 +136,32 @@ int yp_touch(void *psource)
}
else {
source->ypdata[i]->current_song = (char *)malloc(1);
- memset(source->ypdata[i]->current_song, '\000', 1);
+ source->ypdata[i]->current_song[0] = 0;
}
if (source->ypdata[i]->sid) {
url_size += strlen(source->ypdata[i]->sid);
}
else {
source->ypdata[i]->sid = (char *)malloc(1);
- memset(source->ypdata[i]->sid, '\000', 1);
+ source->ypdata[i]->sid[0] = 0;
}
url_size += 1024;
- url = (char *)malloc(url_size);
- memset(url, '\000', url_size);
- sprintf(url, "action=touch&sid=%s&st=%s&listeners=%d",
- source->ypdata[i]->sid,
- source->ypdata[i]->current_song,
- source->listeners);
+ url = malloc(url_size);
+ sprintf(url, "action=touch&sid=%s&st=%s&listeners=%ld",
+ source->ypdata[i]->sid,
+ source->ypdata[i]->current_song,
+ source->listeners);
curl_con = curl_get_connection();
if (curl_con < 0) {
ERROR0("Unable to get auth connection");
}
else {
- /* specify URL to get */
- ret = yp_submit_url(curl_con, source->ypdata[i]->yp_url, url, "yp_touch");
+ /* specify URL to get */
+ ret = yp_submit_url(curl_con, source->ypdata[i]->yp_url,
+ url, "yp_touch");
if (!ret) {
- source->ypdata[i]->sid[0] = '\000';
+ source->ypdata[i]->sid[0] = 0;
}
}
if (url) {
@@ -172,16 +172,14 @@ int yp_touch(void *psource)
}
return 1;
}
-int yp_add(void *psource, int which)
+int yp_add(source_t *source, int which)
{
char *url = NULL;
int url_size = 0;
int ret = 0;
int curl_con = 0;
- char *p1 = NULL;
int i = 0;
int ok = 0;
- source_t *source = (source_t *)psource;
for (i=0; inum_yp_directories; i++) {
if (which != -1) {
@@ -198,82 +196,83 @@ int yp_add(void *psource, int which)
if (ok) {
if (source->ypdata[i]) {
- url_size = strlen("action=add&sn=&genre=&cpswd=&desc=&url=&listenurl=&type=&b=") + 1;
+ url_size = strlen("action=add&sn=&genre=&cpswd=&desc=&url="
+ "&listenurl=&type=&b=") + 1;
if (source->ypdata[i]->server_name) {
url_size += strlen(source->ypdata[i]->server_name);
}
else {
source->ypdata[i]->server_name = (char *)malloc(1);
- memset(source->ypdata[i]->server_name, '\000', 1);
+ source->ypdata[i]->server_name[0] = 0;
}
if (source->ypdata[i]->server_desc) {
url_size += strlen(source->ypdata[i]->server_desc);
}
else {
source->ypdata[i]->server_desc = (char *)malloc(1);
- memset(source->ypdata[i]->server_desc, '\000', 1);
+ source->ypdata[i]->server_desc[0] = 0;
}
if (source->ypdata[i]->server_genre) {
url_size += strlen(source->ypdata[i]->server_genre);
}
else {
source->ypdata[i]->server_genre = (char *)malloc(1);
- memset(source->ypdata[i]->server_genre, '\000', 1);
+ source->ypdata[i]->server_genre[0] = 0;
}
if (source->ypdata[i]->cluster_password) {
url_size += strlen(source->ypdata[i]->cluster_password);
}
else {
source->ypdata[i]->cluster_password = (char *)malloc(1);
- memset(source->ypdata[i]->cluster_password, '\000', 1);
+ source->ypdata[i]->cluster_password[0] = 0;
}
if (source->ypdata[i]->server_url) {
url_size += strlen(source->ypdata[i]->server_url);
}
else {
source->ypdata[i]->server_url = (char *)malloc(1);
- memset(source->ypdata[i]->server_url, '\000', 1);
+ source->ypdata[i]->server_url[0] = 0;
}
if (source->ypdata[i]->listen_url) {
url_size += strlen(source->ypdata[i]->listen_url);
}
else {
source->ypdata[i]->listen_url = (char *)malloc(1);
- memset(source->ypdata[i]->listen_url, '\000', 1);
+ source->ypdata[i]->listen_url[0] = 0;
}
if (source->ypdata[i]->server_type) {
url_size += strlen(source->ypdata[i]->server_type);
}
else {
source->ypdata[i]->server_type = (char *)malloc(1);
- memset(source->ypdata[i]->server_type, '\000', 1);
+ source->ypdata[i]->server_type[0] = 0;
}
if (source->ypdata[i]->bitrate) {
url_size += strlen(source->ypdata[i]->bitrate);
}
else {
source->ypdata[i]->bitrate = (char *)malloc(1);
- memset(source->ypdata[i]->bitrate, '\000', 1);
+ source->ypdata[i]->bitrate[0] = 0;
}
if (source->ypdata[i]->current_song) {
url_size += strlen(source->ypdata[i]->current_song);
}
else {
source->ypdata[i]->current_song = (char *)malloc(1);
- memset(source->ypdata[i]->current_song, '\000', 1);
+ source->ypdata[i]->current_song[0] = 0;
}
url_size += 1024;
- url = (char *)malloc(url_size);
- memset(url, '\000', url_size);
- sprintf(url, "action=add&sn=%s&genre=%s&cpswd=%s&desc=%s&url=%s&listenurl=%s&type=%s&b=%s",
- source->ypdata[i]->server_name,
- source->ypdata[i]->server_genre,
- source->ypdata[i]->cluster_password,
- source->ypdata[i]->server_desc,
- source->ypdata[i]->server_url,
- source->ypdata[i]->listen_url,
- source->ypdata[i]->server_type,
- source->ypdata[i]->bitrate);
+ url = malloc(url_size);
+ sprintf(url, "action=add&sn=%s&genre=%s&cpswd=%s&desc=%s&url=%s"
+ "&listenurl=%s&type=%s&b=%s",
+ source->ypdata[i]->server_name,
+ source->ypdata[i]->server_genre,
+ source->ypdata[i]->cluster_password,
+ source->ypdata[i]->server_desc,
+ source->ypdata[i]->server_url,
+ source->ypdata[i]->listen_url,
+ source->ypdata[i]->server_type,
+ source->ypdata[i]->bitrate);
curl_con = curl_get_connection();
if (curl_con < 0) {
@@ -281,7 +280,8 @@ int yp_add(void *psource, int which)
}
else {
/* specify URL to get */
- ret = yp_submit_url(curl_con, source->ypdata[i]->yp_url, url, "yp_add");
+ ret = yp_submit_url(curl_con, source->ypdata[i]->yp_url,
+ url, "yp_add");
if (ret) {
if (strlen(curl_get_header_result(curl_con)->sid) > 0) {
@@ -290,10 +290,14 @@ int yp_add(void *psource, int which)
free(source->ypdata[i]->sid);
source->ypdata[i]->sid = NULL;
}
- source->ypdata[i]->sid = (char *)malloc(strlen(curl_get_header_result(curl_con)->sid) +1);
- memset(source->ypdata[i]->sid, '\000', strlen(curl_get_header_result(curl_con)->sid) +1);
- strcpy(source->ypdata[i]->sid, curl_get_header_result(curl_con)->sid);
- source->ypdata[i]->yp_touch_freq = curl_get_header_result(curl_con)->touch_freq;
+ source->ypdata[i]->sid = (char *)malloc(
+ strlen(curl_get_header_result(curl_con)->
+ sid) +1);
+ strcpy(source->ypdata[i]->sid,
+ curl_get_header_result(curl_con)->sid);
+ source->ypdata[i]->yp_touch_interval =
+ curl_get_header_result(
+ curl_con)->touch_interval;
}
}
}
@@ -310,12 +314,9 @@ int yp_add(void *psource, int which)
ypdata_t *yp_create_ypdata()
{
- ypdata_t *tmp;
-
- tmp = (ypdata_t *)malloc(sizeof(ypdata_t));
- memset(tmp, '\000', sizeof(ypdata_t));
- return(tmp);
+ return calloc(1, sizeof(ypdata_t));
}
+
void yp_destroy_ypdata(ypdata_t *ypdata)
{
if (ypdata) {
@@ -352,3 +353,4 @@ void yp_destroy_ypdata(ypdata_t *ypdata)
free(ypdata);
}
}
+
diff --git a/src/yp.h b/src/yp.h
index 4d2b151b..1e314eaa 100644
--- a/src/yp.h
+++ b/src/yp.h
@@ -2,29 +2,32 @@
#define __YP_H__
#include
+
+struct source_tag;
+
#define YP_ADD_ALL -1
typedef struct ypdata_tag
{
- char *sid;
- char *server_name;
- char *server_desc;
- char *server_genre;
- char *cluster_password;
- char *server_url;
- char *listen_url;
- char *bitrate;
- char *server_type;
- char *current_song;
- char *yp_url;
+ char *sid;
+ char *server_name;
+ char *server_desc;
+ char *server_genre;
+ char *cluster_password;
+ char *server_url;
+ char *listen_url;
+ char *bitrate;
+ char *server_type;
+ char *current_song;
+ char *yp_url;
int yp_url_timeout;
- long yp_last_touch;
- int yp_touch_freq;
+ long yp_last_touch;
+ int yp_touch_interval;
} ypdata_t;
void *yp_touch_thread(void *arg);
-int yp_add(void *psource, int which);
-int yp_touch(void *psource);
-int yp_remove(void *psource);
+int yp_add(struct source_tag *source, int which);
+int yp_touch(struct source_tag *source);
+int yp_remove(struct source_tag *psource);
ypdata_t *yp_create_ypdata();
void yp_destroy_ypdata(ypdata_t *ypdata);