diff --git a/admin/Makefile.am b/admin/Makefile.am
index 3a298c24..0bc58b45 100644
--- a/admin/Makefile.am
+++ b/admin/Makefile.am
@@ -4,5 +4,5 @@ AUTOMAKE_OPTIONS = foreign
admindir = $(pkgdatadir)/admin
dist_admin_DATA = listclients.xsl listmounts.xsl moveclients.xsl response.xsl \
- stats.xsl manageauth.xsl
+ stats.xsl manageauth.xsl updatemetadata.xsl
diff --git a/admin/listclients.xsl b/admin/listclients.xsl
index db7cd7ef..cfe01ef5 100644
--- a/admin/listclients.xsl
+++ b/admin/listclients.xsl
@@ -33,6 +33,7 @@
Show Listeners |
Move Listeners |
+ Update Metadata |
Kill Source
|
diff --git a/admin/listmounts.xsl b/admin/listmounts.xsl
index 3cc367b8..a2679a29 100644
--- a/admin/listmounts.xsl
+++ b/admin/listmounts.xsl
@@ -35,6 +35,7 @@
Show Listeners |
Move Listeners |
+ Update Metadata |
Kill Source
| Manage Authentication
|
diff --git a/admin/manageauth.xsl b/admin/manageauth.xsl
index e5f3af84..5e76609c 100644
--- a/admin/manageauth.xsl
+++ b/admin/manageauth.xsl
@@ -36,6 +36,7 @@
Show Listeners |
Move Listeners |
+ Update Metadata |
Kill Source
|
diff --git a/admin/stats.xsl b/admin/stats.xsl
index f3955e60..fecd461a 100644
--- a/admin/stats.xsl
+++ b/admin/stats.xsl
@@ -62,6 +62,7 @@
List Clients |
Move MountPoints |
+ Update Metadata |
Kill Source
| Manage Authentication
|
diff --git a/admin/updatemetadata.xsl b/admin/updatemetadata.xsl
new file mode 100644
index 00000000..b37f3f1d
--- /dev/null
+++ b/admin/updatemetadata.xsl
@@ -0,0 +1,55 @@
+
+
+
+
+
+Icecast Streaming Media Server
+
+
+
+
+
+
+Update Metadata
+
+
+
+
+
+
+
+
+()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Support icecast development at
www.icecast.org
+
+
+
+
diff --git a/conf/icecast_minimal.xml.in b/conf/icecast_minimal.xml.in
index 799040b5..dc584c08 100644
--- a/conf/icecast_minimal.xml.in
+++ b/conf/icecast_minimal.xml.in
@@ -25,13 +25,11 @@
@localstatedir@/log/@PACKAGE@
@pkgdatadir@/web
@pkgdatadir@/admin
+
access.log
error.log
3
-
- 0
-
diff --git a/src/admin.c b/src/admin.c
index 6bb8ff40..884a9429 100644
--- a/src/admin.c
+++ b/src/admin.c
@@ -48,16 +48,19 @@
/* Mount-specific commands */
#define COMMAND_RAW_FALLBACK 1
-#define COMMAND_METADATA_UPDATE 2
+#define COMMAND_RAW_METADATA_UPDATE 2
#define COMMAND_RAW_SHOW_LISTENERS 3
#define COMMAND_RAW_MOVE_CLIENTS 4
#define COMMAND_RAW_MANAGEAUTH 5
#define COMMAND_SHOUTCAST_METADATA_UPDATE 6
+#define COMMAND_RAW_UPDATEMETADATA 7
#define COMMAND_TRANSFORMED_FALLBACK 50
#define COMMAND_TRANSFORMED_SHOW_LISTENERS 53
#define COMMAND_TRANSFORMED_MOVE_CLIENTS 54
#define COMMAND_TRANSFORMED_MANAGEAUTH 55
+#define COMMAND_TRANSFORMED_UPDATEMETADATA 56
+#define COMMAND_TRANSFORMED_METADATA_UPDATE 57
/* Global commands */
#define COMMAND_RAW_LIST_MOUNTS 101
@@ -80,7 +83,8 @@
#define FALLBACK_RAW_REQUEST "fallbacks"
#define FALLBACK_TRANSFORMED_REQUEST "fallbacks.xsl"
#define SHOUTCAST_METADATA_REQUEST "admin.cgi"
-#define METADATA_REQUEST "metadata"
+#define METADATA_RAW_REQUEST "metadata"
+#define METADATA_TRANSFORMED_REQUEST "metadata.xsl"
#define LISTCLIENTS_RAW_REQUEST "listclients"
#define LISTCLIENTS_TRANSFORMED_REQUEST "listclients.xsl"
#define STATS_RAW_REQUEST "stats"
@@ -99,6 +103,8 @@
#define ADMIN_XSL_RESPONSE "response.xsl"
#define MANAGEAUTH_RAW_REQUEST "manageauth"
#define MANAGEAUTH_TRANSFORMED_REQUEST "manageauth.xsl"
+#define UPDATEMETADATA_RAW_REQUEST "updatemetadata"
+#define UPDATEMETADATA_TRANSFORMED_REQUEST "updatemetadata.xsl"
#define DEFAULT_RAW_REQUEST ""
#define DEFAULT_TRANSFORMED_REQUEST ""
#define BUILDM3U_RAW_REQUEST "buildm3u"
@@ -112,8 +118,10 @@ int admin_get_command(char *command)
return COMMAND_RAW_FALLBACK;
else if(!strcmp(command, FALLBACK_TRANSFORMED_REQUEST))
return COMMAND_TRANSFORMED_FALLBACK;
- else if(!strcmp(command, METADATA_REQUEST))
- return COMMAND_METADATA_UPDATE;
+ else if(!strcmp(command, METADATA_RAW_REQUEST))
+ return COMMAND_RAW_METADATA_UPDATE;
+ else if(!strcmp(command, METADATA_TRANSFORMED_REQUEST))
+ return COMMAND_TRANSFORMED_METADATA_UPDATE;
else if(!strcmp(command, SHOUTCAST_METADATA_REQUEST))
return COMMAND_SHOUTCAST_METADATA_UPDATE;
else if(!strcmp(command, LISTCLIENTS_RAW_REQUEST))
@@ -150,6 +158,10 @@ int admin_get_command(char *command)
return COMMAND_RAW_MANAGEAUTH;
else if(!strcmp(command, MANAGEAUTH_TRANSFORMED_REQUEST))
return COMMAND_TRANSFORMED_MANAGEAUTH;
+ else if(!strcmp(command, UPDATEMETADATA_RAW_REQUEST))
+ return COMMAND_RAW_UPDATEMETADATA;
+ else if(!strcmp(command, UPDATEMETADATA_TRANSFORMED_REQUEST))
+ return COMMAND_TRANSFORMED_UPDATEMETADATA;
else if(!strcmp(command, BUILDM3U_RAW_REQUEST))
return COMMAND_BUILDM3U;
else if(!strcmp(command, DEFAULT_TRANSFORMED_REQUEST))
@@ -161,7 +173,7 @@ int admin_get_command(char *command)
}
static void command_fallback(client_t *client, source_t *source, int response);
-static void command_metadata(client_t *client, source_t *source);
+static void command_metadata(client_t *client, source_t *source, int response);
static void command_shoutcast_metadata(client_t *client, source_t *source);
static void command_show_listeners(client_t *client, source_t *source,
int response);
@@ -177,6 +189,8 @@ static void command_buildm3u(client_t *client, source_t *source,
int response);
static void command_kill_source(client_t *client, source_t *source,
int response);
+static void command_updatemetadata(client_t *client, source_t *source,
+ int response);
static void admin_handle_mount_request(client_t *client, source_t *source,
int command);
static void admin_handle_general_request(client_t *client, int command);
@@ -446,8 +460,11 @@ static void admin_handle_mount_request(client_t *client, source_t *source,
case COMMAND_RAW_FALLBACK:
command_fallback(client, source, RAW);
break;
- case COMMAND_METADATA_UPDATE:
- command_metadata(client, source);
+ case COMMAND_RAW_METADATA_UPDATE:
+ command_metadata(client, source, RAW);
+ break;
+ case COMMAND_TRANSFORMED_METADATA_UPDATE:
+ command_metadata(client, source, TRANSFORMED);
break;
case COMMAND_SHOUTCAST_METADATA_UPDATE:
command_shoutcast_metadata(client, source);
@@ -485,6 +502,12 @@ static void admin_handle_mount_request(client_t *client, source_t *source,
case COMMAND_RAW_MANAGEAUTH:
command_manageauth(client, source, RAW);
break;
+ case COMMAND_TRANSFORMED_UPDATEMETADATA:
+ command_updatemetadata(client, source, TRANSFORMED);
+ break;
+ case COMMAND_RAW_UPDATEMETADATA:
+ command_updatemetadata(client, source, RAW);
+ break;
case COMMAND_BUILDM3U:
command_buildm3u(client, source, RAW);
break;
@@ -822,11 +845,19 @@ static void command_fallback(client_t *client, source_t *source,
html_success(client, "Fallback configured");
}
-static void command_metadata(client_t *client, source_t *source)
+static void command_metadata(client_t *client, source_t *source,
+ int response)
{
char *action;
char *song, *title, *artist;
format_plugin_t *plugin;
+ xmlDocPtr doc;
+ xmlNodePtr node;
+ int ok = 1;
+
+ doc = xmlNewDoc("1.0");
+ node = xmlNewDocNode(doc, NULL, "iceresponse", NULL);
+ xmlDocSetRootElement(doc, node);
DEBUG0("Got metadata update request");
@@ -837,7 +868,12 @@ static void command_metadata(client_t *client, source_t *source)
if (strcmp (action, "updinfo") != 0)
{
- client_send_400 (client, "No such action");
+ xmlNewChild(node, NULL, "message", "No such action");
+ xmlNewChild(node, NULL, "return", "0");
+ admin_send_response(doc, client, response,
+ ADMIN_XSL_RESPONSE);
+ xmlFreeDoc(doc);
+ client_destroy(client);
return;
}
@@ -860,13 +896,25 @@ static void command_metadata(client_t *client, source_t *source)
source->mount, artist, title);
}
}
-
- html_success(client, "Metadata update successful");
}
else
{
- client_send_400 (client, "mountpoint will not accept URL updates");
+ xmlNewChild(node, NULL, "message",
+ "Mountpoint will not accept URL updates");
+ xmlNewChild(node, NULL, "return", "1");
+ admin_send_response(doc, client, response,
+ ADMIN_XSL_RESPONSE);
+ xmlFreeDoc(doc);
+ client_destroy(client);
+ return;
}
+
+ xmlNewChild(node, NULL, "message", "Metadata update successful");
+ xmlNewChild(node, NULL, "return", "1");
+ admin_send_response(doc, client, response,
+ ADMIN_XSL_RESPONSE);
+ xmlFreeDoc(doc);
+ client_destroy(client);
}
static void command_shoutcast_metadata(client_t *client, source_t *source)
@@ -960,3 +1008,20 @@ static void command_list_mounts(client_t *client, int response)
return;
}
+static void command_updatemetadata(client_t *client, source_t *source,
+ int response)
+{
+ xmlDocPtr doc;
+ xmlNodePtr node, srcnode;
+
+ doc = xmlNewDoc("1.0");
+ node = xmlNewDocNode(doc, NULL, "icestats", NULL);
+ srcnode = xmlNewChild(node, NULL, "source", NULL);
+ xmlSetProp(srcnode, "mount", source->mount);
+ xmlDocSetRootElement(doc, node);
+
+ admin_send_response(doc, client, response,
+ UPDATEMETADATA_TRANSFORMED_REQUEST);
+ xmlFreeDoc(doc);
+ client_destroy(client);
+}
diff --git a/src/cfgfile.c b/src/cfgfile.c
index 1da264df..9ac4c0ec 100644
--- a/src/cfgfile.c
+++ b/src/cfgfile.c
@@ -188,6 +188,9 @@ void config_clear(ice_config_t *c)
xmlFree(mount->password);
xmlFree(mount->dumpfile);
xmlFree(mount->fallback_mount);
+ if (mount->cluster_password) {
+ xmlFree(mount->cluster_password);
+ }
xmlFree(mount->auth_type);
option = mount->auth_options;
@@ -610,6 +613,10 @@ static void _parse_mount(xmlDocPtr doc, xmlNodePtr node,
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
mount->burst_size = atoi(tmp);
if (tmp) xmlFree(tmp);
+ } else if (strcmp(node->name, "cluster-password") == 0) {
+ tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+ mount->cluster_password = (char *)xmlNodeListGetString(
+ doc, node->xmlChildrenNode, 1);
}
} while ((node = node->next));
}
diff --git a/src/cfgfile.h b/src/cfgfile.h
index f862ae22..1d8e8837 100644
--- a/src/cfgfile.h
+++ b/src/cfgfile.h
@@ -62,6 +62,7 @@ typedef struct _mount_proxy {
unsigned int source_timeout; /* source timeout in seconds */
char *auth_type; /* Authentication type */
+ char *cluster_password;
config_options_t *auth_options; /* Options for this type */
struct _mount_proxy *next;
} mount_proxy;
diff --git a/src/yp.c b/src/yp.c
index 648aac39..bf9ba87c 100644
--- a/src/yp.c
+++ b/src/yp.c
@@ -458,6 +458,7 @@ static ypdata_t *create_yp_entry (source_t *source)
unsigned len = 512;
int ret;
char *url;
+ mount_proxy *mountproxy = NULL;
ice_config_t *config;
if (yp == NULL)
@@ -486,6 +487,18 @@ static ypdata_t *create_yp_entry (source_t *source)
if (s) url = s;
snprintf (url, ret, "http://%s:%d%s", config->hostname, config->port, source->mount);
}
+
+ mountproxy = config->mounts;
+ while (mountproxy) {
+ if (strcmp (mountproxy->mountname, source->mount) == 0) {
+ if (mountproxy->cluster_password) {
+ add_yp_info (yp, "cluster_password",
+ mountproxy->cluster_password, YP_CLUSTER_PASSWORD);
+ }
+ break;
+ }
+ mountproxy = mountproxy->next;
+ }
config_release_config();
yp->listen_url = util_url_escape (url);
free (url);
@@ -813,6 +826,15 @@ static void add_yp_info (ypdata_t *yp, char *stat_name, void *info, int type)
stats_event (yp->mount, "yp_currently_playing", (char *)info);
}
break;
+ case YP_CLUSTER_PASSWORD:
+ escaped = util_url_escape(info);
+ if (escaped)
+ {
+ if (yp->cluster_password)
+ free (yp->cluster_password);
+ yp->cluster_password = escaped;
+ }
+ break;
}
}
diff --git a/src/yp.h b/src/yp.h
index 25fddaf5..fb656ec7 100644
--- a/src/yp.h
+++ b/src/yp.h
@@ -22,6 +22,7 @@
#define YP_AUDIO_INFO 6
#define YP_SERVER_TYPE 7
#define YP_CURRENT_SONG 8
+#define YP_CLUSTER_PASSWORD 9
struct source_tag;