diff --git a/src/admin.c b/src/admin.c index 7218ca22..56f542d1 100644 --- a/src/admin.c +++ b/src/admin.c @@ -335,14 +335,22 @@ void admin_handle_request(client_t *client, const char *uri) if (command == COMMAND_SHOUTCAST_METADATA_UPDATE) { ice_config_t *config; + const char *sc_mount; const char *pass = httpp_get_query_param (client->parser, "pass"); + listener_t *listener; + if (pass == NULL) { client_send_400 (client, "missing pass parameter"); return; } config = config_get_config (); - httpp_set_query_param (client->parser, "mount", (char *)config->shoutcast_mount); + sc_mount = config->shoutcast_mount; + listener = config_get_listen_sock (config, client->con); + if (listener && listener->shoutcast_mount) + sc_mount = listener->shoutcast_mount; + + httpp_set_query_param (client->parser, "mount", sc_mount); httpp_setvar (client->parser, HTTPP_VAR_PROTOCOL, "ICY"); httpp_setvar (client->parser, HTTPP_VAR_ICYPASSWORD, pass); config_release_config (); diff --git a/src/cfgfile.c b/src/cfgfile.c index 6244181c..4766d8fc 100644 --- a/src/cfgfile.c +++ b/src/cfgfile.c @@ -157,6 +157,7 @@ listener_t *config_clear_listener (listener_t *listener) { next = listener->next; if (listener->bind_address) xmlFree (listener->bind_address); + if (listener->shoutcast_mount) xmlFree (listener->shoutcast_mount); free (listener); } return next; @@ -800,7 +801,13 @@ static void _parse_listen_socket(xmlDocPtr doc, xmlNodePtr node, listener->shoutcast_compat = atoi(tmp); if(tmp) xmlFree(tmp); } + else if (xmlStrcmp (node->name, XMLSTR("shoutcast-mount")) == 0) { + if (listener->shoutcast_mount) xmlFree (listener->shoutcast_mount); + listener->shoutcast_mount = (char *)xmlNodeListGetString(doc, + node->xmlChildrenNode, 1); + } else if (xmlStrcmp (node->name, XMLSTR("bind-address")) == 0) { + if (listener->bind_address) xmlFree (listener->bind_address); listener->bind_address = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); } @@ -809,6 +816,19 @@ static void _parse_listen_socket(xmlDocPtr doc, xmlNodePtr node, listener->next = configuration->listen_sock; configuration->listen_sock = listener; configuration->listen_sock_count++; + if (listener->shoutcast_mount) + { + listener_t *sc_port = calloc (1, sizeof (listener_t)); + sc_port->port = listener->port+1; + sc_port->shoutcast_compat = 1; + sc_port->shoutcast_mount = (char*)xmlStrdup (XMLSTR(listener->shoutcast_mount)); + if (listener->bind_address) + sc_port->bind_address = (char*)xmlStrdup (XMLSTR(listener->bind_address)); + + sc_port->next = configuration->listen_sock; + configuration->listen_sock = sc_port; + configuration->listen_sock_count++; + } } static void _parse_authentication(xmlDocPtr doc, xmlNodePtr node, diff --git a/src/cfgfile.h b/src/cfgfile.h index 97685629..fa5aa69d 100644 --- a/src/cfgfile.h +++ b/src/cfgfile.h @@ -103,6 +103,7 @@ typedef struct _listener_t { int port; char *bind_address; int shoutcast_compat; + char *shoutcast_mount; int ssl; } listener_t; diff --git a/src/connection.c b/src/connection.c index 7732a8f0..f1af8263 100644 --- a/src/connection.c +++ b/src/connection.c @@ -87,6 +87,7 @@ typedef struct client_queue_tag { int offset; int stream_offset; int shoutcast; + char *shoutcast_mount; struct client_queue_tag *next; } client_queue_t; @@ -758,6 +759,8 @@ void connection_accept_loop(void) node->shoutcast = 1; if (listener->ssl && ssl_ok) connection_uses_ssl (client->con); + if (listener->shoutcast_mount) + node->shoutcast_mount = strdup (listener->shoutcast_mount); } config_release_config(); @@ -1096,7 +1099,6 @@ static void _handle_stats_request (client_t *client, char *uri) static void _handle_get_request (client_t *client, char *passed_uri) { - int fileserve; int port; char *serverhost = NULL; int serverport = 0; @@ -1106,7 +1108,6 @@ static void _handle_get_request (client_t *client, char *passed_uri) listener_t *listen_sock; config = config_get_config(); - fileserve = config->fileserve; port = config->port; listen_sock = config_get_listen_sock (config, client->con); @@ -1160,10 +1161,15 @@ static void _handle_shoutcast_compatible (client_queue_t *node) char *shoutcast_mount; client_t *client = node->client; + if (node->shoutcast_mount) + shoutcast_mount = node->shoutcast_mount; + else + shoutcast_mount = config->shoutcast_mount; + if (node->shoutcast == 1) { char *source_password, *ptr, *headers; - mount_proxy *mountinfo = config_find_mount (config, config->shoutcast_mount); + mount_proxy *mountinfo = config_find_mount (config, shoutcast_mount); if (mountinfo && mountinfo->password) source_password = strdup (mountinfo->password); @@ -1192,6 +1198,7 @@ static void _handle_shoutcast_compatible (client_queue_t *node) { client_destroy (client); free (source_password); + free (node->shoutcast_mount); free (node); return; } @@ -1215,10 +1222,12 @@ static void _handle_shoutcast_compatible (client_queue_t *node) INFO1 ("password does not match \"%s\"", client->refbuf->data); client_destroy (client); free (source_password); + free (node->shoutcast_mount); free (node); return; } - shoutcast_mount = strdup (config->shoutcast_mount); + /* actually make a copy as we are dropping the config lock */ + shoutcast_mount = strdup (shoutcast_mount); config_release_config(); /* Here we create a valid HTTP request based of the information that was passed in via the non-HTTP style protocol above. This @@ -1249,6 +1258,7 @@ static void _handle_shoutcast_compatible (client_queue_t *node) } free (http_compliant); free (shoutcast_mount); + free (node->shoutcast_mount); free (node); return; } @@ -1295,6 +1305,14 @@ static void *_handle_connection(void *arg) client->refbuf->len = node->offset - node->stream_offset; memmove (ptr, ptr + node->stream_offset, client->refbuf->len); } + + rawuri = httpp_getvar(parser, HTTPP_VAR_URI); + + /* assign a port-based shoutcast mountpoint if required */ + if (node->shoutcast_mount && strcmp (rawuri, "/admin.cgi") == 0) + httpp_set_query_param (client->parser, "mount", node->shoutcast_mount); + + free (node->shoutcast_mount); free (node); if (strcmp("ICE", httpp_getvar(parser, HTTPP_VAR_PROTOCOL)) && @@ -1304,7 +1322,6 @@ static void *_handle_connection(void *arg) continue; } - rawuri = httpp_getvar(parser, HTTPP_VAR_URI); uri = util_normalise_uri(rawuri); if (uri == NULL)