mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2025-02-02 15:07:36 -05:00
Lots of fixes for screwy code formatting, plus:
make streams public by default, send ice-private: 1 to make them private. However, default config file has yp servers commented out. A little fix for compilation on some solaris systems Redo some config file stuff: now all the passwords are inside an element <authentication>, (though for now they're also accepted in the old location), and added admin username and password. Move some of the admin activities over to using the admin passwords (admin action that affect a mountpoint use the source password) Fill in some (but not yet all, maybe i'll do that later) of the infrastructure for per-mountpoint passwords. Fix lots of headers/code so that it works properly/portably on non-win32 systems. svn path=/trunk/icecast/; revision=4325
This commit is contained in:
parent
ffb1f3bc7e
commit
9e168dc870
22
TODO
22
TODO
@ -8,6 +8,8 @@ BUGS
|
|||||||
|
|
||||||
- make install - doesn't install configs?
|
- make install - doesn't install configs?
|
||||||
|
|
||||||
|
- pthread/bsd: -pthread instead of -lpthread (autoconf)
|
||||||
|
|
||||||
FEATURES
|
FEATURES
|
||||||
--------
|
--------
|
||||||
|
|
||||||
@ -30,4 +32,24 @@ FEATURES
|
|||||||
|
|
||||||
- stats to list currently connected clients: ip and hostname
|
- 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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,12 +11,23 @@
|
|||||||
<source-timeout>10</source-timeout>
|
<source-timeout>10</source-timeout>
|
||||||
</limits>
|
</limits>
|
||||||
|
|
||||||
<source-password>hackme</source-password>
|
<authentication>
|
||||||
<relay-password>hackme</relay-password>
|
<!-- Sources log in with username 'source' -->
|
||||||
|
<source-password>hackme</source-password>
|
||||||
|
<!-- Relays log in username 'relay' -->
|
||||||
|
<relay-password>hackme</relay-password>
|
||||||
|
|
||||||
<directory>
|
<!-- Admin logs in with the username given below -->
|
||||||
<yp-url>http://www.oddsock.org/cgi-bin/yp-cgi</yp-url>
|
<admin-user>admin</admin-user>
|
||||||
</directory>
|
<admin-password>hackme</admin-password>
|
||||||
|
</authentication>
|
||||||
|
|
||||||
|
<!-- Uncomment this if you want directory listings -->
|
||||||
|
<!--
|
||||||
|
<directory>
|
||||||
|
<yp-url>http://www.oddsock.org/cgi-bin/yp-cgi</yp-url>
|
||||||
|
</directory>
|
||||||
|
-->
|
||||||
|
|
||||||
<hostname>localhost</hostname>
|
<hostname>localhost</hostname>
|
||||||
<port>8000</port>
|
<port>8000</port>
|
||||||
@ -30,15 +41,15 @@
|
|||||||
<fileserve>1</fileserve>
|
<fileserve>1</fileserve>
|
||||||
|
|
||||||
<paths>
|
<paths>
|
||||||
<basedir>/usr/local/icecast2</basedir>
|
<basedir>/usr/local/icecast</basedir>
|
||||||
<logdir>/usr/local/icecast2/logs</logdir>
|
<logdir>/usr/local/icecast/logs</logdir>
|
||||||
<webroot>/usr/local/icecast2/web</webroot>
|
<webroot>/usr/local/icecast/web</webroot>
|
||||||
</paths>
|
</paths>
|
||||||
|
|
||||||
<logging>
|
<logging>
|
||||||
<accesslog>access.log</accesslog>
|
<accesslog>access.log</accesslog>
|
||||||
<errorlog>error.log</errorlog>
|
<errorlog>error.log</errorlog>
|
||||||
<loglevel>4</loglevel> <!-- 4 Debug, 3 Info, 2 Warn, 1 Error -->
|
<loglevel>4</loglevel> <!-- 4 Debug, 3 Info, 2 Warn, 1 Error -->
|
||||||
</logging>
|
</logging>
|
||||||
|
|
||||||
<security>
|
<security>
|
||||||
|
76
src/config.c
76
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_paths(xmlDocPtr doc, xmlNodePtr node);
|
||||||
static void _parse_logging(xmlDocPtr doc, xmlNodePtr node);
|
static void _parse_logging(xmlDocPtr doc, xmlNodePtr node);
|
||||||
static void _parse_security(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);
|
static void _add_server(xmlDocPtr doc, xmlNodePtr node);
|
||||||
|
|
||||||
void config_initialize(void)
|
void config_initialize(void)
|
||||||
@ -171,7 +172,7 @@ static void _set_defaults(void)
|
|||||||
_configuration.relay_password = CONFIG_DEFAULT_RELAY_PASSWORD;
|
_configuration.relay_password = CONFIG_DEFAULT_RELAY_PASSWORD;
|
||||||
_configuration.ice_login = CONFIG_DEFAULT_ICE_LOGIN;
|
_configuration.ice_login = CONFIG_DEFAULT_ICE_LOGIN;
|
||||||
_configuration.fileserve = CONFIG_DEFAULT_FILESERVE;
|
_configuration.fileserve = CONFIG_DEFAULT_FILESERVE;
|
||||||
_configuration.touch_freq = CONFIG_DEFAULT_TOUCH_FREQ;
|
_configuration.touch_interval = CONFIG_DEFAULT_TOUCH_FREQ;
|
||||||
_configuration.dir_list = NULL;
|
_configuration.dir_list = NULL;
|
||||||
_configuration.hostname = CONFIG_DEFAULT_HOSTNAME;
|
_configuration.hostname = CONFIG_DEFAULT_HOSTNAME;
|
||||||
_configuration.port = CONFIG_DEFAULT_PORT;
|
_configuration.port = CONFIG_DEFAULT_PORT;
|
||||||
@ -207,7 +208,10 @@ static void _parse_root(xmlDocPtr doc, xmlNodePtr node)
|
|||||||
} else if (strcmp(node->name, "admin") == 0) {
|
} else if (strcmp(node->name, "admin") == 0) {
|
||||||
if (_configuration.admin && _configuration.admin != CONFIG_DEFAULT_ADMIN) xmlFree(_configuration.admin);
|
if (_configuration.admin && _configuration.admin != CONFIG_DEFAULT_ADMIN) xmlFree(_configuration.admin);
|
||||||
_configuration.admin = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
|
_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;
|
char *mount, *pass;
|
||||||
if ((mount = (char *)xmlGetProp(node, "mount")) != NULL) {
|
if ((mount = (char *)xmlGetProp(node, "mount")) != NULL) {
|
||||||
pass = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
|
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);
|
_configuration.source_password = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
|
||||||
}
|
}
|
||||||
} else if (strcmp(node->name, "relay-password") == 0) {
|
} else if (strcmp(node->name, "relay-password") == 0) {
|
||||||
if (_configuration.relay_password && _configuration.relay_password != CONFIG_DEFAULT_RELAY_PASSWORD) xmlFree(_configuration.relay_password);
|
/* TODO: This is the backwards-compatibility location */
|
||||||
_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) {
|
} else if (strcmp(node->name, "icelogin") == 0) {
|
||||||
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
|
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
|
||||||
_configuration.ice_login = atoi(tmp);
|
_configuration.ice_login = atoi(tmp);
|
||||||
@ -300,6 +305,47 @@ static void _parse_limits(xmlDocPtr doc, xmlNodePtr node)
|
|||||||
} while ((node = node->next));
|
} 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)
|
static void _parse_directory(xmlDocPtr doc, xmlNodePtr node)
|
||||||
{
|
{
|
||||||
char *tmp;
|
char *tmp;
|
||||||
@ -313,16 +359,19 @@ static void _parse_directory(xmlDocPtr doc, xmlNodePtr node)
|
|||||||
if (xmlIsBlankNode(node)) continue;
|
if (xmlIsBlankNode(node)) continue;
|
||||||
|
|
||||||
if (strcmp(node->name, "yp-url") == 0) {
|
if (strcmp(node->name, "yp-url") == 0) {
|
||||||
if (_configuration.yp_url[_configuration.num_yp_directories]) xmlFree(_configuration.yp_url[_configuration.num_yp_directories]);
|
if (_configuration.yp_url[_configuration.num_yp_directories])
|
||||||
_configuration.yp_url[_configuration.num_yp_directories] = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
|
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) {
|
} else if (strcmp(node->name, "yp-url-timeout") == 0) {
|
||||||
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
|
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) {
|
} else if (strcmp(node->name, "server") == 0) {
|
||||||
_add_server(doc, node->xmlChildrenNode);
|
_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);
|
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
|
||||||
_configuration.touch_freq = atoi(tmp);
|
_configuration.touch_interval = atoi(tmp);
|
||||||
if (tmp) xmlFree(tmp);
|
if (tmp) xmlFree(tmp);
|
||||||
}
|
}
|
||||||
} while ((node = node->next));
|
} while ((node = node->next));
|
||||||
@ -411,7 +460,7 @@ static void _add_server(xmlDocPtr doc, xmlNodePtr node)
|
|||||||
char *tmp;
|
char *tmp;
|
||||||
|
|
||||||
server = (ice_config_dir_t *)malloc(sizeof(ice_config_dir_t));
|
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;
|
server->host = NULL;
|
||||||
addnode = 0;
|
addnode = 0;
|
||||||
|
|
||||||
@ -420,11 +469,12 @@ static void _add_server(xmlDocPtr doc, xmlNodePtr node)
|
|||||||
if (xmlIsBlankNode(node)) continue;
|
if (xmlIsBlankNode(node)) continue;
|
||||||
|
|
||||||
if (strcmp(node->name, "host") == 0) {
|
if (strcmp(node->name, "host") == 0) {
|
||||||
server->host = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
|
server->host = (char *)xmlNodeListGetString(doc,
|
||||||
|
node->xmlChildrenNode, 1);
|
||||||
addnode = 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);
|
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
|
||||||
server->touch_freq = atoi(tmp);
|
server->touch_interval = atoi(tmp);
|
||||||
if (tmp) xmlFree(tmp);
|
if (tmp) xmlFree(tmp);
|
||||||
}
|
}
|
||||||
server->next = NULL;
|
server->next = NULL;
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
typedef struct ice_config_dir_tag
|
typedef struct ice_config_dir_tag
|
||||||
{
|
{
|
||||||
char *host;
|
char *host;
|
||||||
int touch_freq;
|
int touch_interval;
|
||||||
struct ice_config_dir_tag *next;
|
struct ice_config_dir_tag *next;
|
||||||
} ice_config_dir_t;
|
} ice_config_dir_t;
|
||||||
|
|
||||||
@ -31,8 +31,10 @@ typedef struct ice_config_tag
|
|||||||
|
|
||||||
char *source_password;
|
char *source_password;
|
||||||
char *relay_password;
|
char *relay_password;
|
||||||
|
char *admin_username;
|
||||||
|
char *admin_password;
|
||||||
|
|
||||||
int touch_freq;
|
int touch_interval;
|
||||||
ice_config_dir_t *dir_list;
|
ice_config_dir_t *dir_list;
|
||||||
|
|
||||||
char *hostname;
|
char *hostname;
|
||||||
|
@ -32,11 +32,11 @@ void _dump_config(ice_config_t *config)
|
|||||||
printf("threadpool_size = %d\n", config->threadpool_size);
|
printf("threadpool_size = %d\n", config->threadpool_size);
|
||||||
printf("client_timeout = %d\n", config->client_timeout);
|
printf("client_timeout = %d\n", config->client_timeout);
|
||||||
printf("source_password = %s\n", config->source_password);
|
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;
|
node = config->dir_list;
|
||||||
while (node) {
|
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);
|
printf("directory.host = %s\n", node->host);
|
||||||
|
|
||||||
node = node->next;
|
node = node->next;
|
||||||
|
@ -404,7 +404,17 @@ static int _check_relay_pass(http_parser_t *parser)
|
|||||||
return _check_pass_http(parser, "relay", pass);
|
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;
|
char *pass = config_get_config()->source_password;
|
||||||
int ret;
|
int ret;
|
||||||
@ -428,15 +438,15 @@ static void handle_fallback_request(client_t *client)
|
|||||||
char *mount, *value, *old;
|
char *mount, *value, *old;
|
||||||
int bytes;
|
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");
|
INFO0("Bad or missing password on fallback configuration request");
|
||||||
client_send_401(client);
|
client_send_401(client);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mount = httpp_get_query_param(client->parser, "mount");
|
|
||||||
value = httpp_get_query_param(client->parser, "fallback");
|
|
||||||
|
|
||||||
if(value == NULL || mount == NULL) {
|
if(value == NULL || mount == NULL) {
|
||||||
client_send_400(client, "Missing parameter");
|
client_send_400(client, "Missing parameter");
|
||||||
return;
|
return;
|
||||||
@ -472,16 +482,16 @@ static void handle_metadata_request(client_t *client)
|
|||||||
mp3_state *state;
|
mp3_state *state;
|
||||||
int bytes;
|
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");
|
INFO0("Metadata request with wrong or missing password");
|
||||||
client_send_401(client);
|
client_send_401(client);
|
||||||
return;
|
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) {
|
if(value == NULL || action == NULL || mount == NULL) {
|
||||||
client_send_400(client, "Missing parameter");
|
client_send_400(client, "Missing parameter");
|
||||||
return;
|
return;
|
||||||
@ -533,7 +543,7 @@ static void _handle_source_request(connection_t *con,
|
|||||||
INFO1("Source logging in at mountpoint \"%s\"", uri);
|
INFO1("Source logging in at mountpoint \"%s\"", uri);
|
||||||
stats_event_inc(NULL, "source_connections");
|
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);
|
INFO1("Source (%s) attempted to login with invalid or missing password", uri);
|
||||||
client_send_401(client);
|
client_send_401(client);
|
||||||
return;
|
return;
|
||||||
@ -564,7 +574,7 @@ static void _handle_stats_request(connection_t *con,
|
|||||||
|
|
||||||
stats_event_inc(NULL, "stats_connections");
|
stats_event_inc(NULL, "stats_connections");
|
||||||
|
|
||||||
if (!_check_source_pass(parser)) {
|
if (!_check_admin_pass(parser)) {
|
||||||
ERROR0("Bad password for stats connection");
|
ERROR0("Bad password for stats connection");
|
||||||
connection_close(con);
|
connection_close(con);
|
||||||
httpp_destroy(parser);
|
httpp_destroy(parser);
|
||||||
@ -606,7 +616,7 @@ static void _handle_get_request(connection_t *con,
|
|||||||
*/
|
*/
|
||||||
/* TODO: add GUID-xxxxxx */
|
/* TODO: add GUID-xxxxxx */
|
||||||
if (strcmp(uri, "/admin/stats.xml") == 0) {
|
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");
|
INFO0("Request for /admin/stats.xml with incorrect or no password");
|
||||||
client_send_401(client);
|
client_send_401(client);
|
||||||
return;
|
return;
|
||||||
|
@ -226,7 +226,7 @@ static void *fserv_thread_function(void *arg)
|
|||||||
&client->buf[client->offset],
|
&client->buf[client->offset],
|
||||||
client->datasize - 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) {
|
if(sbytes >= 0) {
|
||||||
client->offset += sbytes;
|
client->offset += sbytes;
|
||||||
client->client->con->sent_bytes += sbytes;
|
client->client->con->sent_bytes += sbytes;
|
||||||
|
49
src/geturl.c
49
src/geturl.c
@ -1,5 +1,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <thread/thread.h>
|
#include <thread/thread.h>
|
||||||
|
|
||||||
@ -20,10 +21,10 @@
|
|||||||
#define CATMODULE "geturl"
|
#define CATMODULE "geturl"
|
||||||
|
|
||||||
static curl_connection curl_connections[NUM_CONNECTIONS];
|
static curl_connection curl_connections[NUM_CONNECTIONS];
|
||||||
mutex_t _curl_mutex;
|
static mutex_t _curl_mutex;
|
||||||
|
|
||||||
size_t
|
size_t curl_write_memory_callback(void *ptr, size_t size,
|
||||||
curl_write_memory_callback(void *ptr, size_t size, size_t nmemb, void *data)
|
size_t nmemb, void *data)
|
||||||
{
|
{
|
||||||
register int realsize = size * nmemb;
|
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;
|
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 *p1 = 0;
|
||||||
char *p2 = 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: ");
|
p1 = (char *)ptr + strlen("SID: ");
|
||||||
p2 = strchr((const char *)p1, '\r');
|
p2 = strchr((const char *)p1, '\r');
|
||||||
memset(mem->sid, '\000', sizeof(mem->sid));
|
memset(mem->sid, '\000', sizeof(mem->sid));
|
||||||
if (p2) {
|
if (p2) {
|
||||||
if (p2-p1 > sizeof(mem->sid)-1) {
|
if (p2-p1 > sizeof(mem->sid)-1) {
|
||||||
copylen = sizeof(mem->sid)-1;
|
copylen = sizeof(mem->sid)-1;
|
||||||
}
|
|
||||||
else {
|
|
||||||
copylen = p2-p1;
|
|
||||||
}
|
|
||||||
strncpy(mem->sid, p1, copylen);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
strncpy(mem->sid, p1, sizeof(mem->sid)-1);
|
copylen = p2-p1;
|
||||||
strcpy(mem->sid, p1);
|
|
||||||
}
|
}
|
||||||
|
strncpy(mem->sid, p1, copylen);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
strncpy(mem->sid, p1, sizeof(mem->sid)-1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!strncmp(ptr, "YPMessage: ", strlen("YPMessage: "))) {
|
if (!strncmp(ptr, "YPMessage: ", strlen("YPMessage: "))) {
|
||||||
p1 = (char *)ptr + 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 {
|
else {
|
||||||
strncpy(mem->message, p1, sizeof(mem->message)-1);
|
strncpy(mem->message, p1, sizeof(mem->message)-1);
|
||||||
strcpy(mem->message, p1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!strncmp(ptr, "TouchFreq: ", strlen("TouchFreq: "))) {
|
if (!strncmp(ptr, "TouchFreq: ", strlen("TouchFreq: "))) {
|
||||||
p1 = (char *)ptr + strlen("TouchFreq: ");
|
p1 = (char *)ptr + strlen("TouchFreq: ");
|
||||||
mem->touch_freq = atoi(p1);
|
mem->touch_interval = atoi(p1);
|
||||||
}
|
}
|
||||||
if (!strncmp(ptr, "YPResponse: ", strlen("YPResponse: "))) {
|
if (!strncmp(ptr, "YPResponse: ", strlen("YPResponse: "))) {
|
||||||
p1 = (char *)ptr + strlen("YPResponse: ");
|
p1 = (char *)ptr + strlen("YPResponse: ");
|
||||||
@ -95,13 +95,14 @@ int curl_initialize()
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
thread_mutex_create(&_curl_mutex);
|
thread_mutex_create(&_curl_mutex);
|
||||||
|
|
||||||
memset(&curl_connections, '\000', sizeof(curl_connections));
|
memset(&curl_connections, 0, sizeof(curl_connections));
|
||||||
for (i=0; i<NUM_CONNECTIONS; i++) {
|
for (i=0; i<NUM_CONNECTIONS; i++) {
|
||||||
curl_connections[i].curl_handle = curl_easy_init();
|
curl_connections[i].curl_handle = curl_easy_init();
|
||||||
curl_easy_setopt(curl_connections[i].curl_handle,
|
curl_easy_setopt(curl_connections[i].curl_handle,
|
||||||
CURLOPT_WRITEFUNCTION, curl_write_memory_callback);
|
CURLOPT_WRITEFUNCTION, curl_write_memory_callback);
|
||||||
curl_easy_setopt(curl_connections[i].curl_handle,
|
curl_easy_setopt(curl_connections[i].curl_handle,
|
||||||
CURLOPT_WRITEHEADER, (void *)&(curl_connections[i].header_result));
|
CURLOPT_WRITEHEADER,
|
||||||
|
(void *)&(curl_connections[i].header_result));
|
||||||
curl_easy_setopt(curl_connections[i].curl_handle,
|
curl_easy_setopt(curl_connections[i].curl_handle,
|
||||||
CURLOPT_HEADERFUNCTION, curl_header_memory_callback);
|
CURLOPT_HEADERFUNCTION, curl_header_memory_callback);
|
||||||
curl_easy_setopt(curl_connections[i].curl_handle,
|
curl_easy_setopt(curl_connections[i].curl_handle,
|
||||||
@ -114,7 +115,7 @@ void curl_shutdown()
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
for (i=0; i<NUM_CONNECTIONS; i++) {
|
for (i=0; i<NUM_CONNECTIONS; i++) {
|
||||||
curl_easy_cleanup(curl_connections[i].curl_handle);
|
curl_easy_cleanup(curl_connections[i].curl_handle);
|
||||||
memset(&(curl_connections[i]), '\000', sizeof(curl_connections[i]));
|
memset(&(curl_connections[i]), 0, sizeof(curl_connections[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int curl_get_connection()
|
int curl_get_connection()
|
||||||
@ -145,9 +146,9 @@ int curl_release_connection(int which)
|
|||||||
{
|
{
|
||||||
thread_mutex_lock(&_curl_mutex);
|
thread_mutex_lock(&_curl_mutex);
|
||||||
curl_connections[which].in_use = 0;
|
curl_connections[which].in_use = 0;
|
||||||
memset(&(curl_connections[which].result), '\000',
|
memset(&(curl_connections[which].result), 0,
|
||||||
sizeof(curl_connections[which].result));
|
sizeof(curl_connections[which].result));
|
||||||
memset(&(curl_connections[which].header_result), '\000',
|
memset(&(curl_connections[which].header_result), 0,
|
||||||
sizeof(curl_connections[which].header_result));
|
sizeof(curl_connections[which].header_result));
|
||||||
thread_mutex_unlock(&_curl_mutex);
|
thread_mutex_unlock(&_curl_mutex);
|
||||||
return 1;
|
return 1;
|
||||||
@ -155,7 +156,7 @@ int curl_release_connection(int which)
|
|||||||
void curl_print_header_result(struct curl_memory_struct2 *mem) {
|
void curl_print_header_result(struct curl_memory_struct2 *mem) {
|
||||||
DEBUG1("SID -> (%s)", mem->sid);
|
DEBUG1("SID -> (%s)", mem->sid);
|
||||||
DEBUG1("Message -> (%s)", mem->message);
|
DEBUG1("Message -> (%s)", mem->message);
|
||||||
DEBUG1("Touch Freq -> (%d)", mem->touch_freq);
|
DEBUG1("Touch Freq -> (%d)", mem->touch_interval);
|
||||||
DEBUG1("Response -> (%d)", mem->response);
|
DEBUG1("Response -> (%d)", mem->response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,6 +165,7 @@ CURL *curl_get_handle(int which)
|
|||||||
{
|
{
|
||||||
return curl_connections[which].curl_handle;
|
return curl_connections[which].curl_handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct curl_memory_struct *curl_get_result(int which)
|
struct curl_memory_struct *curl_get_result(int which)
|
||||||
{
|
{
|
||||||
return &(curl_connections[which].result);
|
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);
|
return &(curl_connections[which].header_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ struct curl_memory_struct {
|
|||||||
struct curl_memory_struct2 {
|
struct curl_memory_struct2 {
|
||||||
char sid[YP_SID_SIZE];
|
char sid[YP_SID_SIZE];
|
||||||
char message[YP_RESPONSE_SIZE];
|
char message[YP_RESPONSE_SIZE];
|
||||||
int touch_freq;
|
int touch_interval;
|
||||||
int response;
|
int response;
|
||||||
size_t size;
|
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);
|
void curl_print_header_result(struct curl_memory_struct2 *mem);
|
||||||
int curl_get_connection();
|
int curl_get_connection();
|
||||||
int curl_release_connection(int which);
|
int curl_release_connection(int which);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -665,7 +665,7 @@ int sock_accept(sock_t serversock, char *ip, int len)
|
|||||||
ret = accept(serversock, (struct sockaddr *)&sin, &slen);
|
ret = accept(serversock, (struct sockaddr *)&sin, &slen);
|
||||||
|
|
||||||
if (ret >= 0 && ip != NULL) {
|
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);
|
strncpy(ip, inet_ntoa(sin.sin_addr), len);
|
||||||
sock_set_nolinger(ret);
|
sock_set_nolinger(ret);
|
||||||
sock_set_keepalive(ret);
|
sock_set_keepalive(ret);
|
||||||
|
@ -42,6 +42,10 @@ struct iovec
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_INET_PTON
|
||||||
|
#define inet_aton(a,b) inet_pton(AF_INET, (a), (b))
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef int sock_t;
|
typedef int sock_t;
|
||||||
|
|
||||||
/* The following values are based on unix avoiding errno value clashes */
|
/* The following values are based on unix avoiding errno value clashes */
|
||||||
|
121
src/source.c
121
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->parser = parser;
|
||||||
src->client_tree = avl_tree_new(_compare_clients, NULL);
|
src->client_tree = avl_tree_new(_compare_clients, NULL);
|
||||||
src->pending_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->num_yp_directories = 0;
|
||||||
src->listeners = 0;
|
src->listeners = 0;
|
||||||
for (i=0;i<config_get_config()->num_yp_directories;i++) {
|
for (i=0;i<config_get_config()->num_yp_directories;i++) {
|
||||||
if (config_get_config()->yp_url[i]) {
|
if (config_get_config()->yp_url[i]) {
|
||||||
src->ypdata[src->num_yp_directories] = yp_create_ypdata();
|
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 =
|
||||||
src->ypdata[src->num_yp_directories]->yp_url_timeout = config_get_config()->yp_url_timeout[i];
|
config_get_config()->yp_url[i];
|
||||||
src->ypdata[src->num_yp_directories]->yp_touch_freq = 0;
|
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++;
|
src->num_yp_directories++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -136,17 +139,15 @@ void *source_main(void *arg)
|
|||||||
client_t *client;
|
client_t *client;
|
||||||
avl_node *client_node;
|
avl_node *client_node;
|
||||||
char *s;
|
char *s;
|
||||||
long currentTime = 0;
|
long current_time;
|
||||||
char current_song[256];
|
char current_song[256];
|
||||||
char prev_current_song[256];
|
|
||||||
|
|
||||||
refbuf_t *refbuf, *abuf;
|
refbuf_t *refbuf, *abuf;
|
||||||
int data_done;
|
int data_done;
|
||||||
|
|
||||||
int listeners = 0;
|
int listeners = 0;
|
||||||
int listen_url_size = 0;
|
|
||||||
int i=0;
|
int i=0;
|
||||||
int list_on_yp = 0;
|
int suppress_yp = 0;
|
||||||
|
|
||||||
timeout = config_get_config()->source_timeout;
|
timeout = config_get_config()->source_timeout;
|
||||||
|
|
||||||
@ -169,8 +170,7 @@ void *source_main(void *arg)
|
|||||||
if (source->ypdata[i]->server_name) {
|
if (source->ypdata[i]->server_name) {
|
||||||
free(source->ypdata[i]->server_name);
|
free(source->ypdata[i]->server_name);
|
||||||
}
|
}
|
||||||
source->ypdata[i]->server_name = (char *)malloc(strlen(s) +1);
|
source->ypdata[i]->server_name = malloc(strlen(s) +1);
|
||||||
memset(source->ypdata[i]->server_name, '\000', strlen(s) + 1);
|
|
||||||
strcpy(source->ypdata[i]->server_name, s);
|
strcpy(source->ypdata[i]->server_name, s);
|
||||||
}
|
}
|
||||||
stats_event(source->mount, "name", s);
|
stats_event(source->mount, "name", s);
|
||||||
@ -180,8 +180,7 @@ void *source_main(void *arg)
|
|||||||
if (source->ypdata[i]->server_url) {
|
if (source->ypdata[i]->server_url) {
|
||||||
free(source->ypdata[i]->server_url);
|
free(source->ypdata[i]->server_url);
|
||||||
}
|
}
|
||||||
source->ypdata[i]->server_url = (char *)malloc(strlen(s) +1);
|
source->ypdata[i]->server_url = malloc(strlen(s) +1);
|
||||||
memset(source->ypdata[i]->server_url, '\000', strlen(s) + 1);
|
|
||||||
strcpy(source->ypdata[i]->server_url, s);
|
strcpy(source->ypdata[i]->server_url, s);
|
||||||
}
|
}
|
||||||
stats_event(source->mount, "url", s);
|
stats_event(source->mount, "url", s);
|
||||||
@ -191,8 +190,7 @@ void *source_main(void *arg)
|
|||||||
if (source->ypdata[i]->server_genre) {
|
if (source->ypdata[i]->server_genre) {
|
||||||
free(source->ypdata[i]->server_genre);
|
free(source->ypdata[i]->server_genre);
|
||||||
}
|
}
|
||||||
source->ypdata[i]->server_genre = (char *)malloc(strlen(s) +1);
|
source->ypdata[i]->server_genre = malloc(strlen(s) +1);
|
||||||
memset(source->ypdata[i]->server_genre, '\000', strlen(s) + 1);
|
|
||||||
strcpy(source->ypdata[i]->server_genre, s);
|
strcpy(source->ypdata[i]->server_genre, s);
|
||||||
}
|
}
|
||||||
stats_event(source->mount, "genre", s);
|
stats_event(source->mount, "genre", s);
|
||||||
@ -202,8 +200,7 @@ void *source_main(void *arg)
|
|||||||
if (source->ypdata[i]->bitrate) {
|
if (source->ypdata[i]->bitrate) {
|
||||||
free(source->ypdata[i]->bitrate);
|
free(source->ypdata[i]->bitrate);
|
||||||
}
|
}
|
||||||
source->ypdata[i]->bitrate = (char *)malloc(strlen(s) +1);
|
source->ypdata[i]->bitrate = malloc(strlen(s) +1);
|
||||||
memset(source->ypdata[i]->bitrate, '\000', strlen(s) + 1);
|
|
||||||
strcpy(source->ypdata[i]->bitrate, s);
|
strcpy(source->ypdata[i]->bitrate, s);
|
||||||
}
|
}
|
||||||
stats_event(source->mount, "bitrate", s);
|
stats_event(source->mount, "bitrate", s);
|
||||||
@ -213,78 +210,97 @@ void *source_main(void *arg)
|
|||||||
if (source->ypdata[i]->server_desc) {
|
if (source->ypdata[i]->server_desc) {
|
||||||
free(source->ypdata[i]->server_desc);
|
free(source->ypdata[i]->server_desc);
|
||||||
}
|
}
|
||||||
source->ypdata[i]->server_desc = (char *)malloc(strlen(s) +1);
|
source->ypdata[i]->server_desc = malloc(strlen(s) +1);
|
||||||
memset(source->ypdata[i]->server_desc, '\000', strlen(s) + 1);
|
|
||||||
strcpy(source->ypdata[i]->server_desc, s);
|
strcpy(source->ypdata[i]->server_desc, s);
|
||||||
}
|
}
|
||||||
stats_event(source->mount, "description", 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);
|
stats_event(source->mount, "public", s);
|
||||||
list_on_yp = atoi(s);
|
suppress_yp = atoi(s);
|
||||||
}
|
}
|
||||||
for (i=0;i<source->num_yp_directories;i++) {
|
for (i=0;i<source->num_yp_directories;i++) {
|
||||||
if (source->ypdata[i]->server_type) {
|
if (source->ypdata[i]->server_type) {
|
||||||
free(source->ypdata[i]->server_type);
|
free(source->ypdata[i]->server_type);
|
||||||
}
|
}
|
||||||
source->ypdata[i]->server_type = (char *)malloc(strlen(source->format->format_description) +1);
|
source->ypdata[i]->server_type = malloc(
|
||||||
memset(source->ypdata[i]->server_type, '\000', strlen(source->format->format_description) + 1);
|
strlen(source->format->format_description) + 1);
|
||||||
strcpy(source->ypdata[i]->server_type, source->format->format_description);
|
strcpy(source->ypdata[i]->server_type,
|
||||||
|
source->format->format_description);
|
||||||
}
|
}
|
||||||
stats_event(source->mount, "type", source->format->format_description);
|
stats_event(source->mount, "type", source->format->format_description);
|
||||||
|
|
||||||
for (i=0;i<source->num_yp_directories;i++) {
|
for (i=0;i<source->num_yp_directories;i++) {
|
||||||
|
int listen_url_size;
|
||||||
if (source->ypdata[i]->listen_url) {
|
if (source->ypdata[i]->listen_url) {
|
||||||
free(source->ypdata[i]->listen_url);
|
free(source->ypdata[i]->listen_url);
|
||||||
}
|
}
|
||||||
// 6 for max size of port
|
/* 6 for max size of port */
|
||||||
listen_url_size = strlen("http://") + strlen(config_get_config()->hostname) + strlen(":") + 6 + strlen(source->mount) + 1;
|
listen_url_size = strlen("http://") +
|
||||||
source->ypdata[i]->listen_url = (char *)malloc(listen_url_size);
|
strlen(config_get_config()->hostname) +
|
||||||
memset(source->ypdata[i]->listen_url, '\000', listen_url_size);
|
strlen(":") + 6 + strlen(source->mount) + 1;
|
||||||
sprintf(source->ypdata[i]->listen_url, "http://%s:%d%s", config_get_config()->hostname, config_get_config()->port, source->mount);
|
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) {
|
if(!suppress_yp) {
|
||||||
yp_add(source, YP_ADD_ALL);
|
yp_add(source, YP_ADD_ALL);
|
||||||
}
|
|
||||||
time(¤tTime);
|
|
||||||
for (i=0;i<source->num_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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (global.running == ICE_RUNNING) {
|
current_time = time(NULL);
|
||||||
time(¤tTime);
|
|
||||||
if (list_on_yp) {
|
for (i=0;i<source->num_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;i<source->num_yp_directories;i++) {
|
for (i=0;i<source->num_yp_directories;i++) {
|
||||||
if (currentTime > (source->ypdata[i]->yp_last_touch + source->ypdata[i]->yp_touch_freq)) {
|
if (current_time > (source->ypdata[i]->yp_last_touch +
|
||||||
memset(current_song, '\000', sizeof(current_song));
|
source->ypdata[i]->yp_touch_interval)) {
|
||||||
|
current_song[0] = 0;
|
||||||
if (stats_get_value(source->mount, "artist")) {
|
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)) {
|
if (strlen(current_song) + 4 < sizeof(current_song)) {
|
||||||
strncat(current_song, " - ", 3);
|
strncat(current_song, " - ", 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (stats_get_value(source->mount, "title")) {
|
if (stats_get_value(source->mount, "title")) {
|
||||||
if (strlen(current_song) + strlen(stats_get_value(source->mount, "title")) < sizeof(current_song) -1) {
|
if (strlen(current_song) +
|
||||||
strncat(current_song, stats_get_value(source->mount, "title"), sizeof(current_song) -1 - 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) {
|
if (source->ypdata[i]->current_song) {
|
||||||
free(source->ypdata[i]->current_song);
|
free(source->ypdata[i]->current_song);
|
||||||
source->ypdata[i]->current_song = NULL;
|
source->ypdata[i]->current_song = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
source->ypdata[i]->current_song = (char *)malloc(strlen(current_song) + 1);
|
source->ypdata[i]->current_song =
|
||||||
memset(source->ypdata[i]->current_song, '\000', strlen(current_song) + 1);
|
malloc(strlen(current_song) + 1);
|
||||||
strcpy(source->ypdata[i]->current_song, current_song);
|
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);
|
ret = source->format->get_buffer(source->format, NULL, 0, &refbuf);
|
||||||
if(ret < 0) {
|
if(ret < 0) {
|
||||||
WARN0("Bad data from source");
|
WARN0("Bad data from source");
|
||||||
@ -486,7 +502,7 @@ void *source_main(void *arg)
|
|||||||
done:
|
done:
|
||||||
|
|
||||||
DEBUG0("Source exiting");
|
DEBUG0("Source exiting");
|
||||||
if (list_on_yp) {
|
if(!suppress_yp) {
|
||||||
yp_remove(source);
|
yp_remove(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -502,7 +518,7 @@ done:
|
|||||||
if(fallback_source) {
|
if(fallback_source) {
|
||||||
avl_delete(source->pending_tree, client, _remove_client);
|
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_tree_wlock(fallback_source->pending_tree);
|
||||||
avl_insert(fallback_source->pending_tree, (void *)client);
|
avl_insert(fallback_source->pending_tree, (void *)client);
|
||||||
avl_tree_unlock(fallback_source->pending_tree);
|
avl_tree_unlock(fallback_source->pending_tree);
|
||||||
@ -520,7 +536,7 @@ done:
|
|||||||
if(fallback_source) {
|
if(fallback_source) {
|
||||||
avl_delete(source->client_tree, client, _remove_client);
|
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_tree_wlock(fallback_source->pending_tree);
|
||||||
avl_insert(fallback_source->pending_tree, (void *)client);
|
avl_insert(fallback_source->pending_tree, (void *)client);
|
||||||
avl_tree_unlock(fallback_source->pending_tree);
|
avl_tree_unlock(fallback_source->pending_tree);
|
||||||
@ -580,3 +596,4 @@ static int _free_client(void *key)
|
|||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,10 @@ typedef struct source_tag
|
|||||||
/* If this source drops, try to move all clients to this fallback */
|
/* If this source drops, try to move all clients to this fallback */
|
||||||
char *fallback_mount;
|
char *fallback_mount;
|
||||||
|
|
||||||
|
/* set to zero to request the source to shutdown without causing a global
|
||||||
|
* shutdown */
|
||||||
|
int running;
|
||||||
|
|
||||||
struct _format_plugin_tag *format;
|
struct _format_plugin_tag *format;
|
||||||
|
|
||||||
avl_tree *client_tree;
|
avl_tree *client_tree;
|
||||||
|
@ -126,13 +126,13 @@ void stats_shutdown()
|
|||||||
|
|
||||||
stats_t *stats_get_stats()
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
126
src/yp.c
126
src/yp.c
@ -1,5 +1,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <thread/thread.h>
|
#include <thread/thread.h>
|
||||||
|
|
||||||
@ -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_URL, yp_url);
|
||||||
curl_easy_setopt(curl_get_handle(curl_con), CURLOPT_POSTFIELDS, 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! */
|
/* get it! */
|
||||||
memset(curl_get_result(curl_con), '\000', sizeof(struct curl_memory_struct));
|
memset(curl_get_result(curl_con), 0, sizeof(struct curl_memory_struct));
|
||||||
memset(curl_get_header_result(curl_con), '\000', sizeof(struct curl_memory_struct2));
|
memset(curl_get_header_result(curl_con), 0,
|
||||||
|
sizeof(struct curl_memory_struct2));
|
||||||
|
|
||||||
curl_easy_perform(curl_get_handle(curl_con));
|
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 {
|
else {
|
||||||
if (strlen(curl_get_header_result(curl_con)->message) > 0) {
|
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 {
|
else {
|
||||||
ERROR2("Got a NAK from %s(Unknown) (%s)", type, yp_url);
|
ERROR2("Got a NAK from %s(Unknown) (%s)", type, yp_url);
|
||||||
@ -52,18 +56,16 @@ void *yp_touch_thread(void *arg)
|
|||||||
thread_exit(0);
|
thread_exit(0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
int yp_remove(void *psource)
|
|
||||||
|
int yp_remove(source_t *source)
|
||||||
{
|
{
|
||||||
char *url = NULL;
|
char *url = NULL;
|
||||||
int url_size = 0;
|
int url_size = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int curl_con = 0;
|
int curl_con = 0;
|
||||||
char *p1 = NULL;
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
int regen_sid = 0;
|
|
||||||
long current_time = 0;
|
long current_time = 0;
|
||||||
source_t *source = (source_t *)psource;
|
|
||||||
|
|
||||||
current_time = time(¤t_time);
|
current_time = time(¤t_time);
|
||||||
|
|
||||||
@ -81,17 +83,17 @@ int yp_remove(void *psource)
|
|||||||
url_size = strlen("action=remove&sid=") + 1;
|
url_size = strlen("action=remove&sid=") + 1;
|
||||||
url_size += strlen(source->ypdata[i]->sid);
|
url_size += strlen(source->ypdata[i]->sid);
|
||||||
url_size += 1024;
|
url_size += 1024;
|
||||||
url = (char *)malloc(url_size);
|
url = malloc(url_size);
|
||||||
memset(url, '\000', url_size);
|
|
||||||
sprintf(url, "action=remove&sid=%s",
|
sprintf(url, "action=remove&sid=%s",
|
||||||
source->ypdata[i]->sid);
|
source->ypdata[i]->sid);
|
||||||
curl_con = curl_get_connection();
|
curl_con = curl_get_connection();
|
||||||
if (curl_con < 0) {
|
if (curl_con < 0) {
|
||||||
ERROR0("Unable to get auth connection");
|
ERROR0("Unable to get auth connection");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* specify URL to get */
|
/* specify URL to get */
|
||||||
ret = yp_submit_url(curl_con, source->ypdata[i]->yp_url, url, "yp_remove");
|
ret = yp_submit_url(curl_con, source->ypdata[i]->yp_url,
|
||||||
|
url, "yp_remove");
|
||||||
}
|
}
|
||||||
if (url) {
|
if (url) {
|
||||||
free(url);
|
free(url);
|
||||||
@ -101,19 +103,17 @@ int yp_remove(void *psource)
|
|||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
int yp_touch(void *psource)
|
int yp_touch(source_t *source)
|
||||||
{
|
{
|
||||||
char *url = NULL;
|
char *url = NULL;
|
||||||
int url_size = 0;
|
int url_size = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int curl_con = 0;
|
int curl_con = 0;
|
||||||
char *p1 = NULL;
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int regen_sid = 0;
|
int regen_sid = 0;
|
||||||
long current_time = 0;
|
long current_time = 0;
|
||||||
source_t *source = (source_t *)psource;
|
|
||||||
|
|
||||||
current_time = time(¤t_time);
|
current_time = time(NULL);
|
||||||
for (i=0; i<source->num_yp_directories; i++) {
|
for (i=0; i<source->num_yp_directories; i++) {
|
||||||
source->ypdata[i]->yp_last_touch = current_time;
|
source->ypdata[i]->yp_last_touch = current_time;
|
||||||
if (source->ypdata[i]->sid == 0) {
|
if (source->ypdata[i]->sid == 0) {
|
||||||
@ -136,32 +136,32 @@ int yp_touch(void *psource)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
source->ypdata[i]->current_song = (char *)malloc(1);
|
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) {
|
if (source->ypdata[i]->sid) {
|
||||||
url_size += strlen(source->ypdata[i]->sid);
|
url_size += strlen(source->ypdata[i]->sid);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
source->ypdata[i]->sid = (char *)malloc(1);
|
source->ypdata[i]->sid = (char *)malloc(1);
|
||||||
memset(source->ypdata[i]->sid, '\000', 1);
|
source->ypdata[i]->sid[0] = 0;
|
||||||
}
|
}
|
||||||
url_size += 1024;
|
url_size += 1024;
|
||||||
url = (char *)malloc(url_size);
|
url = malloc(url_size);
|
||||||
memset(url, '\000', url_size);
|
sprintf(url, "action=touch&sid=%s&st=%s&listeners=%ld",
|
||||||
sprintf(url, "action=touch&sid=%s&st=%s&listeners=%d",
|
source->ypdata[i]->sid,
|
||||||
source->ypdata[i]->sid,
|
source->ypdata[i]->current_song,
|
||||||
source->ypdata[i]->current_song,
|
source->listeners);
|
||||||
source->listeners);
|
|
||||||
|
|
||||||
curl_con = curl_get_connection();
|
curl_con = curl_get_connection();
|
||||||
if (curl_con < 0) {
|
if (curl_con < 0) {
|
||||||
ERROR0("Unable to get auth connection");
|
ERROR0("Unable to get auth connection");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* specify URL to get */
|
/* specify URL to get */
|
||||||
ret = yp_submit_url(curl_con, source->ypdata[i]->yp_url, url, "yp_touch");
|
ret = yp_submit_url(curl_con, source->ypdata[i]->yp_url,
|
||||||
|
url, "yp_touch");
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
source->ypdata[i]->sid[0] = '\000';
|
source->ypdata[i]->sid[0] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (url) {
|
if (url) {
|
||||||
@ -172,16 +172,14 @@ int yp_touch(void *psource)
|
|||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
int yp_add(void *psource, int which)
|
int yp_add(source_t *source, int which)
|
||||||
{
|
{
|
||||||
char *url = NULL;
|
char *url = NULL;
|
||||||
int url_size = 0;
|
int url_size = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int curl_con = 0;
|
int curl_con = 0;
|
||||||
char *p1 = NULL;
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
source_t *source = (source_t *)psource;
|
|
||||||
|
|
||||||
for (i=0; i<source->num_yp_directories; i++) {
|
for (i=0; i<source->num_yp_directories; i++) {
|
||||||
if (which != -1) {
|
if (which != -1) {
|
||||||
@ -198,82 +196,83 @@ int yp_add(void *psource, int which)
|
|||||||
|
|
||||||
if (ok) {
|
if (ok) {
|
||||||
if (source->ypdata[i]) {
|
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) {
|
if (source->ypdata[i]->server_name) {
|
||||||
url_size += strlen(source->ypdata[i]->server_name);
|
url_size += strlen(source->ypdata[i]->server_name);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
source->ypdata[i]->server_name = (char *)malloc(1);
|
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) {
|
if (source->ypdata[i]->server_desc) {
|
||||||
url_size += strlen(source->ypdata[i]->server_desc);
|
url_size += strlen(source->ypdata[i]->server_desc);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
source->ypdata[i]->server_desc = (char *)malloc(1);
|
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) {
|
if (source->ypdata[i]->server_genre) {
|
||||||
url_size += strlen(source->ypdata[i]->server_genre);
|
url_size += strlen(source->ypdata[i]->server_genre);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
source->ypdata[i]->server_genre = (char *)malloc(1);
|
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) {
|
if (source->ypdata[i]->cluster_password) {
|
||||||
url_size += strlen(source->ypdata[i]->cluster_password);
|
url_size += strlen(source->ypdata[i]->cluster_password);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
source->ypdata[i]->cluster_password = (char *)malloc(1);
|
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) {
|
if (source->ypdata[i]->server_url) {
|
||||||
url_size += strlen(source->ypdata[i]->server_url);
|
url_size += strlen(source->ypdata[i]->server_url);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
source->ypdata[i]->server_url = (char *)malloc(1);
|
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) {
|
if (source->ypdata[i]->listen_url) {
|
||||||
url_size += strlen(source->ypdata[i]->listen_url);
|
url_size += strlen(source->ypdata[i]->listen_url);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
source->ypdata[i]->listen_url = (char *)malloc(1);
|
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) {
|
if (source->ypdata[i]->server_type) {
|
||||||
url_size += strlen(source->ypdata[i]->server_type);
|
url_size += strlen(source->ypdata[i]->server_type);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
source->ypdata[i]->server_type = (char *)malloc(1);
|
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) {
|
if (source->ypdata[i]->bitrate) {
|
||||||
url_size += strlen(source->ypdata[i]->bitrate);
|
url_size += strlen(source->ypdata[i]->bitrate);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
source->ypdata[i]->bitrate = (char *)malloc(1);
|
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) {
|
if (source->ypdata[i]->current_song) {
|
||||||
url_size += strlen(source->ypdata[i]->current_song);
|
url_size += strlen(source->ypdata[i]->current_song);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
source->ypdata[i]->current_song = (char *)malloc(1);
|
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_size += 1024;
|
||||||
url = (char *)malloc(url_size);
|
url = malloc(url_size);
|
||||||
memset(url, '\000', url_size);
|
sprintf(url, "action=add&sn=%s&genre=%s&cpswd=%s&desc=%s&url=%s"
|
||||||
sprintf(url, "action=add&sn=%s&genre=%s&cpswd=%s&desc=%s&url=%s&listenurl=%s&type=%s&b=%s",
|
"&listenurl=%s&type=%s&b=%s",
|
||||||
source->ypdata[i]->server_name,
|
source->ypdata[i]->server_name,
|
||||||
source->ypdata[i]->server_genre,
|
source->ypdata[i]->server_genre,
|
||||||
source->ypdata[i]->cluster_password,
|
source->ypdata[i]->cluster_password,
|
||||||
source->ypdata[i]->server_desc,
|
source->ypdata[i]->server_desc,
|
||||||
source->ypdata[i]->server_url,
|
source->ypdata[i]->server_url,
|
||||||
source->ypdata[i]->listen_url,
|
source->ypdata[i]->listen_url,
|
||||||
source->ypdata[i]->server_type,
|
source->ypdata[i]->server_type,
|
||||||
source->ypdata[i]->bitrate);
|
source->ypdata[i]->bitrate);
|
||||||
|
|
||||||
curl_con = curl_get_connection();
|
curl_con = curl_get_connection();
|
||||||
if (curl_con < 0) {
|
if (curl_con < 0) {
|
||||||
@ -281,7 +280,8 @@ int yp_add(void *psource, int which)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* specify URL to get */
|
/* 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 (ret) {
|
||||||
if (strlen(curl_get_header_result(curl_con)->sid) > 0) {
|
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);
|
free(source->ypdata[i]->sid);
|
||||||
source->ypdata[i]->sid = NULL;
|
source->ypdata[i]->sid = NULL;
|
||||||
}
|
}
|
||||||
source->ypdata[i]->sid = (char *)malloc(strlen(curl_get_header_result(curl_con)->sid) +1);
|
source->ypdata[i]->sid = (char *)malloc(
|
||||||
memset(source->ypdata[i]->sid, '\000', strlen(curl_get_header_result(curl_con)->sid) +1);
|
strlen(curl_get_header_result(curl_con)->
|
||||||
strcpy(source->ypdata[i]->sid, curl_get_header_result(curl_con)->sid);
|
sid) +1);
|
||||||
source->ypdata[i]->yp_touch_freq = curl_get_header_result(curl_con)->touch_freq;
|
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 *yp_create_ypdata()
|
||||||
{
|
{
|
||||||
ypdata_t *tmp;
|
return calloc(1, sizeof(ypdata_t));
|
||||||
|
|
||||||
tmp = (ypdata_t *)malloc(sizeof(ypdata_t));
|
|
||||||
memset(tmp, '\000', sizeof(ypdata_t));
|
|
||||||
return(tmp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void yp_destroy_ypdata(ypdata_t *ypdata)
|
void yp_destroy_ypdata(ypdata_t *ypdata)
|
||||||
{
|
{
|
||||||
if (ypdata) {
|
if (ypdata) {
|
||||||
@ -352,3 +353,4 @@ void yp_destroy_ypdata(ypdata_t *ypdata)
|
|||||||
free(ypdata);
|
free(ypdata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
35
src/yp.h
35
src/yp.h
@ -2,29 +2,32 @@
|
|||||||
#define __YP_H__
|
#define __YP_H__
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
struct source_tag;
|
||||||
|
|
||||||
#define YP_ADD_ALL -1
|
#define YP_ADD_ALL -1
|
||||||
typedef struct ypdata_tag
|
typedef struct ypdata_tag
|
||||||
{
|
{
|
||||||
char *sid;
|
char *sid;
|
||||||
char *server_name;
|
char *server_name;
|
||||||
char *server_desc;
|
char *server_desc;
|
||||||
char *server_genre;
|
char *server_genre;
|
||||||
char *cluster_password;
|
char *cluster_password;
|
||||||
char *server_url;
|
char *server_url;
|
||||||
char *listen_url;
|
char *listen_url;
|
||||||
char *bitrate;
|
char *bitrate;
|
||||||
char *server_type;
|
char *server_type;
|
||||||
char *current_song;
|
char *current_song;
|
||||||
char *yp_url;
|
char *yp_url;
|
||||||
int yp_url_timeout;
|
int yp_url_timeout;
|
||||||
long yp_last_touch;
|
long yp_last_touch;
|
||||||
int yp_touch_freq;
|
int yp_touch_interval;
|
||||||
} ypdata_t;
|
} ypdata_t;
|
||||||
|
|
||||||
void *yp_touch_thread(void *arg);
|
void *yp_touch_thread(void *arg);
|
||||||
int yp_add(void *psource, int which);
|
int yp_add(struct source_tag *source, int which);
|
||||||
int yp_touch(void *psource);
|
int yp_touch(struct source_tag *source);
|
||||||
int yp_remove(void *psource);
|
int yp_remove(struct source_tag *psource);
|
||||||
ypdata_t *yp_create_ypdata();
|
ypdata_t *yp_create_ypdata();
|
||||||
void yp_destroy_ypdata(ypdata_t *ypdata);
|
void yp_destroy_ypdata(ypdata_t *ypdata);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user