From b3d5a657d2aed13701e6a1980e87c13033eab82d Mon Sep 17 00:00:00 2001 From: oddsock Date: Tue, 7 Dec 2004 22:29:46 +0000 Subject: [PATCH] add a new web admin feature which allows the updating of metadata (now that we support metadata updates for most stream types). This is an new admin feature. add cluster-password to the config to allow for future clustering of relays on the xiph stream directory. svn path=/icecast/trunk/icecast/; revision=8345 --- admin/Makefile.am | 2 +- admin/listclients.xsl | 1 + admin/listmounts.xsl | 1 + admin/manageauth.xsl | 1 + admin/stats.xsl | 1 + admin/updatemetadata.xsl | 55 +++++++++++++++++++++++ conf/icecast_minimal.xml.in | 4 +- src/admin.c | 89 ++++++++++++++++++++++++++++++++----- src/cfgfile.c | 7 +++ src/cfgfile.h | 1 + src/yp.c | 22 +++++++++ src/yp.h | 1 + 12 files changed, 169 insertions(+), 16 deletions(-) create mode 100644 admin/updatemetadata.xsl 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 + + + +
+ + + +
+ List MountPoints | + Move Listeners | + Stats | + Status Page +
+
+

Update Metadata

+
+
+ +
+
+ +

+ +()

+ +
+ + + +
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;