2004-01-28 20:02:12 -05:00
|
|
|
/* Icecast
|
|
|
|
*
|
|
|
|
* This program is distributed under the GNU General Public License, version 2.
|
|
|
|
* A copy of this license is included with this source.
|
|
|
|
*
|
|
|
|
* Copyright 2000-2004, Jack Moffitt <jack@xiph.org,
|
|
|
|
* Michael Smith <msmith@xiph.org>,
|
|
|
|
* oddsock <oddsock@xiph.org>,
|
|
|
|
* Karl Heyes <karl@xiph.org>
|
|
|
|
* and others (see AUTHORS for details).
|
|
|
|
*/
|
|
|
|
|
2003-07-20 21:58:54 -04:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include <config.h>
|
|
|
|
#endif
|
|
|
|
|
2003-03-06 09:17:33 -05:00
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
2003-03-07 09:57:36 -05:00
|
|
|
#include <stdarg.h>
|
|
|
|
#include <time.h>
|
2003-05-15 17:03:32 -04:00
|
|
|
#include <libxml/xmlmemory.h>
|
|
|
|
#include <libxml/parser.h>
|
|
|
|
#include <libxml/tree.h>
|
2003-03-06 09:17:33 -05:00
|
|
|
|
2003-07-20 21:58:54 -04:00
|
|
|
#include "cfgfile.h"
|
2003-03-06 09:17:33 -05:00
|
|
|
#include "connection.h"
|
|
|
|
#include "refbuf.h"
|
|
|
|
#include "client.h"
|
|
|
|
#include "source.h"
|
|
|
|
#include "global.h"
|
|
|
|
#include "event.h"
|
|
|
|
#include "stats.h"
|
2003-05-15 17:03:32 -04:00
|
|
|
#include "os.h"
|
2003-05-28 09:43:48 -04:00
|
|
|
#include "xslt.h"
|
2003-03-06 09:17:33 -05:00
|
|
|
|
|
|
|
#include "format.h"
|
2004-02-26 05:39:56 -05:00
|
|
|
#include "format_mp3.h"
|
2003-03-06 09:17:33 -05:00
|
|
|
|
|
|
|
#include "logging.h"
|
2004-04-30 10:36:07 -04:00
|
|
|
#include "auth.h"
|
2003-05-15 19:19:57 -04:00
|
|
|
#ifdef _WIN32
|
|
|
|
#define snprintf _snprintf
|
|
|
|
#endif
|
2003-03-06 09:17:33 -05:00
|
|
|
|
|
|
|
#define CATMODULE "admin"
|
|
|
|
|
2003-03-09 09:12:24 -05:00
|
|
|
#define COMMAND_ERROR (-1)
|
|
|
|
|
|
|
|
/* Mount-specific commands */
|
2003-05-15 17:03:32 -04:00
|
|
|
#define COMMAND_RAW_FALLBACK 1
|
2003-03-09 09:12:24 -05:00
|
|
|
#define COMMAND_METADATA_UPDATE 2
|
2003-05-15 17:03:32 -04:00
|
|
|
#define COMMAND_RAW_SHOW_LISTENERS 3
|
|
|
|
#define COMMAND_RAW_MOVE_CLIENTS 4
|
2004-04-30 10:36:07 -04:00
|
|
|
#define COMMAND_RAW_MANAGEAUTH 5
|
2003-05-15 17:03:32 -04:00
|
|
|
|
|
|
|
#define COMMAND_TRANSFORMED_FALLBACK 50
|
|
|
|
#define COMMAND_TRANSFORMED_SHOW_LISTENERS 53
|
|
|
|
#define COMMAND_TRANSFORMED_MOVE_CLIENTS 54
|
2004-04-30 10:36:07 -04:00
|
|
|
#define COMMAND_TRANSFORMED_MANAGEAUTH 55
|
2003-03-09 09:12:24 -05:00
|
|
|
|
|
|
|
/* Global commands */
|
2004-02-02 19:48:02 -05:00
|
|
|
#define COMMAND_RAW_LIST_MOUNTS 101
|
|
|
|
#define COMMAND_RAW_STATS 102
|
|
|
|
#define COMMAND_RAW_LISTSTREAM 103
|
|
|
|
#define COMMAND_PLAINTEXT_LISTSTREAM 104
|
|
|
|
#define COMMAND_TRANSFORMED_LIST_MOUNTS 201
|
|
|
|
#define COMMAND_TRANSFORMED_STATS 202
|
|
|
|
#define COMMAND_TRANSFORMED_LISTSTREAM 203
|
2003-03-06 09:17:33 -05:00
|
|
|
|
2003-03-30 08:52:27 -05:00
|
|
|
/* Client management commands */
|
2004-02-02 19:48:02 -05:00
|
|
|
#define COMMAND_RAW_KILL_CLIENT 301
|
|
|
|
#define COMMAND_RAW_KILL_SOURCE 302
|
|
|
|
#define COMMAND_TRANSFORMED_KILL_CLIENT 401
|
|
|
|
#define COMMAND_TRANSFORMED_KILL_SOURCE 402
|
2003-05-15 17:03:32 -04:00
|
|
|
|
2004-04-30 13:32:34 -04:00
|
|
|
/* Admin commands requiring no auth */
|
|
|
|
#define COMMAND_BUILDM3U 501
|
|
|
|
|
2003-05-15 17:03:32 -04:00
|
|
|
#define FALLBACK_RAW_REQUEST "fallbacks"
|
|
|
|
#define FALLBACK_TRANSFORMED_REQUEST "fallbacks.xsl"
|
|
|
|
#define METADATA_REQUEST "metadata"
|
|
|
|
#define LISTCLIENTS_RAW_REQUEST "listclients"
|
|
|
|
#define LISTCLIENTS_TRANSFORMED_REQUEST "listclients.xsl"
|
|
|
|
#define STATS_RAW_REQUEST "stats"
|
|
|
|
#define STATS_TRANSFORMED_REQUEST "stats.xsl"
|
|
|
|
#define LISTMOUNTS_RAW_REQUEST "listmounts"
|
|
|
|
#define LISTMOUNTS_TRANSFORMED_REQUEST "listmounts.xsl"
|
|
|
|
#define STREAMLIST_RAW_REQUEST "streamlist"
|
|
|
|
#define STREAMLIST_TRANSFORMED_REQUEST "streamlist.xsl"
|
2003-12-12 18:06:44 -05:00
|
|
|
#define STREAMLIST_PLAINTEXT_REQUEST "streamlist.txt"
|
2003-05-15 17:03:32 -04:00
|
|
|
#define MOVECLIENTS_RAW_REQUEST "moveclients"
|
|
|
|
#define MOVECLIENTS_TRANSFORMED_REQUEST "moveclients.xsl"
|
|
|
|
#define KILLCLIENT_RAW_REQUEST "killclient"
|
|
|
|
#define KILLCLIENT_TRANSFORMED_REQUEST "killclient.xsl"
|
|
|
|
#define KILLSOURCE_RAW_REQUEST "killsource"
|
|
|
|
#define KILLSOURCE_TRANSFORMED_REQUEST "killsource.xsl"
|
|
|
|
#define ADMIN_XSL_RESPONSE "response.xsl"
|
2004-04-30 10:36:07 -04:00
|
|
|
#define MANAGEAUTH_RAW_REQUEST "manageauth"
|
|
|
|
#define MANAGEAUTH_TRANSFORMED_REQUEST "manageauth.xsl"
|
2003-05-15 17:03:32 -04:00
|
|
|
#define DEFAULT_RAW_REQUEST ""
|
|
|
|
#define DEFAULT_TRANSFORMED_REQUEST ""
|
2004-04-30 13:32:34 -04:00
|
|
|
#define BUILDM3U_RAW_REQUEST "buildm3u"
|
2003-05-15 17:03:32 -04:00
|
|
|
|
|
|
|
#define RAW 1
|
|
|
|
#define TRANSFORMED 2
|
2003-12-12 18:06:44 -05:00
|
|
|
#define PLAINTEXT 3
|
2003-03-06 09:17:33 -05:00
|
|
|
int admin_get_command(char *command)
|
|
|
|
{
|
2003-05-15 17:03:32 -04:00
|
|
|
if(!strcmp(command, FALLBACK_RAW_REQUEST))
|
|
|
|
return COMMAND_RAW_FALLBACK;
|
|
|
|
else if(!strcmp(command, FALLBACK_TRANSFORMED_REQUEST))
|
|
|
|
return COMMAND_TRANSFORMED_FALLBACK;
|
|
|
|
else if(!strcmp(command, METADATA_REQUEST))
|
2003-03-06 09:17:33 -05:00
|
|
|
return COMMAND_METADATA_UPDATE;
|
2003-05-15 17:03:32 -04:00
|
|
|
else if(!strcmp(command, LISTCLIENTS_RAW_REQUEST))
|
|
|
|
return COMMAND_RAW_SHOW_LISTENERS;
|
|
|
|
else if(!strcmp(command, LISTCLIENTS_TRANSFORMED_REQUEST))
|
|
|
|
return COMMAND_TRANSFORMED_SHOW_LISTENERS;
|
|
|
|
else if(!strcmp(command, STATS_RAW_REQUEST))
|
2003-03-09 09:12:24 -05:00
|
|
|
return COMMAND_RAW_STATS;
|
2003-05-15 17:03:32 -04:00
|
|
|
else if(!strcmp(command, STATS_TRANSFORMED_REQUEST))
|
|
|
|
return COMMAND_TRANSFORMED_STATS;
|
2003-03-09 09:12:24 -05:00
|
|
|
else if(!strcmp(command, "stats.xml")) /* The old way */
|
|
|
|
return COMMAND_RAW_STATS;
|
2003-05-15 17:03:32 -04:00
|
|
|
else if(!strcmp(command, LISTMOUNTS_RAW_REQUEST))
|
|
|
|
return COMMAND_RAW_LIST_MOUNTS;
|
|
|
|
else if(!strcmp(command, LISTMOUNTS_TRANSFORMED_REQUEST))
|
|
|
|
return COMMAND_TRANSFORMED_LIST_MOUNTS;
|
|
|
|
else if(!strcmp(command, STREAMLIST_RAW_REQUEST))
|
2003-03-10 17:20:16 -05:00
|
|
|
return COMMAND_RAW_LISTSTREAM;
|
2003-12-12 18:06:44 -05:00
|
|
|
else if(!strcmp(command, STREAMLIST_PLAINTEXT_REQUEST))
|
|
|
|
return COMMAND_PLAINTEXT_LISTSTREAM;
|
2003-05-15 17:03:32 -04:00
|
|
|
else if(!strcmp(command, MOVECLIENTS_RAW_REQUEST))
|
|
|
|
return COMMAND_RAW_MOVE_CLIENTS;
|
|
|
|
else if(!strcmp(command, MOVECLIENTS_TRANSFORMED_REQUEST))
|
|
|
|
return COMMAND_TRANSFORMED_MOVE_CLIENTS;
|
|
|
|
else if(!strcmp(command, KILLCLIENT_RAW_REQUEST))
|
|
|
|
return COMMAND_RAW_KILL_CLIENT;
|
|
|
|
else if(!strcmp(command, KILLCLIENT_TRANSFORMED_REQUEST))
|
|
|
|
return COMMAND_TRANSFORMED_KILL_CLIENT;
|
|
|
|
else if(!strcmp(command, KILLSOURCE_RAW_REQUEST))
|
|
|
|
return COMMAND_RAW_KILL_SOURCE;
|
|
|
|
else if(!strcmp(command, KILLSOURCE_TRANSFORMED_REQUEST))
|
|
|
|
return COMMAND_TRANSFORMED_KILL_SOURCE;
|
2004-04-30 10:36:07 -04:00
|
|
|
else if(!strcmp(command, MANAGEAUTH_RAW_REQUEST))
|
|
|
|
return COMMAND_RAW_MANAGEAUTH;
|
|
|
|
else if(!strcmp(command, MANAGEAUTH_TRANSFORMED_REQUEST))
|
|
|
|
return COMMAND_TRANSFORMED_MANAGEAUTH;
|
2004-04-30 13:32:34 -04:00
|
|
|
else if(!strcmp(command, BUILDM3U_RAW_REQUEST))
|
|
|
|
return COMMAND_BUILDM3U;
|
2003-05-15 17:03:32 -04:00
|
|
|
else if(!strcmp(command, DEFAULT_TRANSFORMED_REQUEST))
|
|
|
|
return COMMAND_TRANSFORMED_STATS;
|
|
|
|
else if(!strcmp(command, DEFAULT_RAW_REQUEST))
|
|
|
|
return COMMAND_TRANSFORMED_STATS;
|
2003-03-06 09:17:33 -05:00
|
|
|
else
|
|
|
|
return COMMAND_ERROR;
|
|
|
|
}
|
|
|
|
|
2003-05-15 17:03:32 -04:00
|
|
|
static void command_fallback(client_t *client, source_t *source, int response);
|
2003-03-06 09:17:33 -05:00
|
|
|
static void command_metadata(client_t *client, source_t *source);
|
2003-05-15 17:03:32 -04:00
|
|
|
static void command_show_listeners(client_t *client, source_t *source,
|
|
|
|
int response);
|
|
|
|
static void command_move_clients(client_t *client, source_t *source,
|
|
|
|
int response);
|
|
|
|
static void command_stats(client_t *client, int response);
|
|
|
|
static void command_list_mounts(client_t *client, int response);
|
|
|
|
static void command_kill_client(client_t *client, source_t *source,
|
|
|
|
int response);
|
2004-04-30 10:36:07 -04:00
|
|
|
static void command_manageauth(client_t *client, source_t *source,
|
|
|
|
int response);
|
2004-04-30 13:32:34 -04:00
|
|
|
static void command_buildm3u(client_t *client, source_t *source,
|
|
|
|
int response);
|
2003-05-15 17:03:32 -04:00
|
|
|
static void command_kill_source(client_t *client, source_t *source,
|
|
|
|
int response);
|
2003-03-06 09:17:33 -05:00
|
|
|
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);
|
2003-05-15 17:03:32 -04:00
|
|
|
static void admin_send_response(xmlDocPtr doc, client_t *client,
|
|
|
|
int response, char *xslt_template);
|
|
|
|
static void html_write(client_t *client, char *fmt, ...);
|
|
|
|
|
|
|
|
xmlDocPtr admin_build_sourcelist(char *current_source)
|
|
|
|
{
|
|
|
|
avl_node *node;
|
|
|
|
source_t *source;
|
|
|
|
xmlNodePtr xmlnode, srcnode;
|
|
|
|
xmlDocPtr doc;
|
|
|
|
char buf[22];
|
|
|
|
time_t now = time(NULL);
|
|
|
|
|
|
|
|
doc = xmlNewDoc("1.0");
|
|
|
|
xmlnode = xmlNewDocNode(doc, NULL, "icestats", NULL);
|
|
|
|
xmlDocSetRootElement(doc, xmlnode);
|
2003-03-06 09:17:33 -05:00
|
|
|
|
2003-05-15 17:03:32 -04:00
|
|
|
if (current_source) {
|
|
|
|
xmlNewChild(xmlnode, NULL, "current_source", current_source);
|
|
|
|
}
|
|
|
|
|
|
|
|
node = avl_get_first(global.source_tree);
|
|
|
|
while(node) {
|
|
|
|
source = (source_t *)node->key;
|
2004-02-19 10:24:06 -05:00
|
|
|
if (source->running)
|
|
|
|
{
|
|
|
|
srcnode = xmlNewChild(xmlnode, NULL, "source", NULL);
|
|
|
|
xmlSetProp(srcnode, "mount", source->mount);
|
2003-05-15 17:03:32 -04:00
|
|
|
|
2004-02-19 10:24:06 -05:00
|
|
|
xmlNewChild(srcnode, NULL, "fallback",
|
2003-05-15 17:03:32 -04:00
|
|
|
(source->fallback_mount != NULL)?
|
|
|
|
source->fallback_mount:"");
|
2004-02-19 10:24:06 -05:00
|
|
|
snprintf(buf, sizeof(buf), "%ld", source->listeners);
|
|
|
|
xmlNewChild(srcnode, NULL, "listeners", buf);
|
2004-02-29 09:55:04 -05:00
|
|
|
snprintf(buf, sizeof(buf), "%lu",
|
|
|
|
(unsigned long)(now - source->con->con_time));
|
2004-02-19 10:24:06 -05:00
|
|
|
xmlNewChild(srcnode, NULL, "Connected", buf);
|
|
|
|
xmlNewChild(srcnode, NULL, "Format",
|
|
|
|
source->format->format_description);
|
2004-04-30 10:36:07 -04:00
|
|
|
if (source->authenticator) {
|
|
|
|
xmlNewChild(srcnode, NULL, "authenticator",
|
|
|
|
source->authenticator->type);
|
|
|
|
}
|
2004-02-19 10:24:06 -05:00
|
|
|
}
|
2003-05-15 17:03:32 -04:00
|
|
|
node = avl_get_next(node);
|
|
|
|
}
|
|
|
|
return(doc);
|
|
|
|
}
|
|
|
|
|
|
|
|
void admin_send_response(xmlDocPtr doc, client_t *client,
|
|
|
|
int response, char *xslt_template)
|
|
|
|
{
|
2003-07-24 12:21:22 -04:00
|
|
|
xmlChar *buff = NULL;
|
2003-05-15 17:03:32 -04:00
|
|
|
int len = 0;
|
|
|
|
ice_config_t *config;
|
|
|
|
char *fullpath_xslt_template;
|
|
|
|
int fullpath_xslt_template_len;
|
|
|
|
char *adminwebroot;
|
|
|
|
|
|
|
|
client->respcode = 200;
|
|
|
|
if (response == RAW) {
|
2003-07-24 12:21:22 -04:00
|
|
|
xmlDocDumpMemory(doc, &buff, &len);
|
2003-05-15 17:03:32 -04:00
|
|
|
html_write(client, "HTTP/1.0 200 OK\r\n"
|
|
|
|
"Content-Length: %d\r\n"
|
|
|
|
"Content-Type: text/xml\r\n"
|
|
|
|
"\r\n", len);
|
|
|
|
html_write(client, buff);
|
|
|
|
}
|
|
|
|
if (response == TRANSFORMED) {
|
|
|
|
config = config_get_config();
|
|
|
|
adminwebroot = config->adminroot_dir;
|
|
|
|
config_release_config();
|
|
|
|
fullpath_xslt_template_len = strlen(adminwebroot) +
|
|
|
|
strlen(xslt_template) + 2;
|
|
|
|
fullpath_xslt_template = malloc(fullpath_xslt_template_len);
|
|
|
|
memset(fullpath_xslt_template, '\000', fullpath_xslt_template_len);
|
|
|
|
snprintf(fullpath_xslt_template, fullpath_xslt_template_len, "%s%s%s",
|
|
|
|
adminwebroot, PATH_SEPARATOR, xslt_template);
|
|
|
|
html_write(client, "HTTP/1.0 200 OK\r\n"
|
|
|
|
"Content-Type: text/html\r\n"
|
|
|
|
"\r\n");
|
|
|
|
DEBUG1("Sending XSLT (%s)", fullpath_xslt_template);
|
|
|
|
xslt_transform(doc, fullpath_xslt_template, client);
|
|
|
|
free(fullpath_xslt_template);
|
|
|
|
}
|
|
|
|
if (buff) {
|
|
|
|
xmlFree(buff);
|
|
|
|
}
|
|
|
|
}
|
2003-03-06 09:17:33 -05:00
|
|
|
void admin_handle_request(client_t *client, char *uri)
|
|
|
|
{
|
|
|
|
char *mount, *command_string;
|
|
|
|
int command;
|
2004-04-30 13:32:34 -04:00
|
|
|
int noauth = 0;
|
2003-03-06 09:17:33 -05:00
|
|
|
|
|
|
|
if(strncmp("/admin/", uri, 7)) {
|
|
|
|
ERROR0("Internal error: admin request isn't");
|
|
|
|
client_send_401(client);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
command_string = uri + 7;
|
|
|
|
|
2003-05-15 17:03:32 -04:00
|
|
|
DEBUG1("Got command (%s)", command_string);
|
2003-03-06 09:17:33 -05:00
|
|
|
command = admin_get_command(command_string);
|
|
|
|
|
|
|
|
if(command < 0) {
|
|
|
|
ERROR1("Error parsing command string or unrecognised command: %s",
|
|
|
|
command_string);
|
|
|
|
client_send_400(client, "Unrecognised command");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mount = httpp_get_query_param(client->parser, "mount");
|
|
|
|
|
|
|
|
if(mount != NULL) {
|
|
|
|
source_t *source;
|
|
|
|
|
2004-04-30 13:32:34 -04:00
|
|
|
if (command == COMMAND_BUILDM3U) {
|
|
|
|
noauth = 1;
|
|
|
|
}
|
2003-03-06 09:17:33 -05:00
|
|
|
/* This is a mount request, handle it as such */
|
2004-04-30 13:32:34 -04:00
|
|
|
if (!noauth) {
|
|
|
|
if(!connection_check_admin_pass(client->parser)) {
|
|
|
|
if(!connection_check_source_pass(client->parser, mount)) {
|
|
|
|
INFO1("Bad or missing password on mount modification admin "
|
|
|
|
"request (command: %s)", command_string);
|
|
|
|
client_send_401(client);
|
|
|
|
return;
|
|
|
|
}
|
2003-03-09 09:12:24 -05:00
|
|
|
}
|
2003-03-06 09:17:33 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
avl_tree_rlock(global.source_tree);
|
2004-01-14 20:01:09 -05:00
|
|
|
source = source_find_mount_raw(mount);
|
2003-03-06 09:17:33 -05:00
|
|
|
|
2004-01-27 20:22:36 -05:00
|
|
|
if (source == NULL)
|
|
|
|
{
|
2003-03-06 09:17:33 -05:00
|
|
|
WARN2("Admin command %s on non-existent source %s",
|
|
|
|
command_string, mount);
|
2004-02-20 12:42:57 -05:00
|
|
|
avl_tree_unlock(global.source_tree);
|
2003-03-06 09:17:33 -05:00
|
|
|
client_send_400(client, "Source does not exist");
|
|
|
|
}
|
2004-01-27 20:22:36 -05:00
|
|
|
else
|
|
|
|
{
|
2004-02-19 10:24:06 -05:00
|
|
|
if (source->running == 0)
|
|
|
|
{
|
|
|
|
INFO2("Received admin command %s on unavailable mount \"%s\"",
|
|
|
|
command_string, mount);
|
|
|
|
avl_tree_unlock (global.source_tree);
|
|
|
|
client_send_400 (client, "Source is not available");
|
|
|
|
return;
|
|
|
|
}
|
2004-01-27 20:22:36 -05:00
|
|
|
INFO2("Received admin command %s on mount \"%s\"",
|
|
|
|
command_string, mount);
|
|
|
|
admin_handle_mount_request(client, source, command);
|
2004-02-20 12:42:57 -05:00
|
|
|
avl_tree_unlock(global.source_tree);
|
2004-01-27 20:22:36 -05:00
|
|
|
}
|
2003-03-06 09:17:33 -05:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
|
2003-12-12 18:06:44 -05:00
|
|
|
if (command == COMMAND_PLAINTEXT_LISTSTREAM) {
|
|
|
|
/* this request is used by a slave relay to retrieve
|
|
|
|
mounts from the master, so handle this request
|
|
|
|
validating against the relay password */
|
|
|
|
if(!connection_check_relay_pass(client->parser)) {
|
|
|
|
INFO1("Bad or missing password on admin command "
|
|
|
|
"request (command: %s)", command_string);
|
|
|
|
client_send_401(client);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if(!connection_check_admin_pass(client->parser)) {
|
|
|
|
INFO1("Bad or missing password on admin command "
|
|
|
|
"request (command: %s)", command_string);
|
|
|
|
client_send_401(client);
|
|
|
|
return;
|
|
|
|
}
|
2003-03-06 09:17:33 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
admin_handle_general_request(client, command);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void admin_handle_general_request(client_t *client, int command)
|
|
|
|
{
|
|
|
|
switch(command) {
|
|
|
|
case COMMAND_RAW_STATS:
|
2003-05-15 17:03:32 -04:00
|
|
|
command_stats(client, RAW);
|
2003-03-06 09:17:33 -05:00
|
|
|
break;
|
2003-05-15 17:03:32 -04:00
|
|
|
case COMMAND_RAW_LIST_MOUNTS:
|
|
|
|
command_list_mounts(client, RAW);
|
2003-03-10 17:20:16 -05:00
|
|
|
break;
|
|
|
|
case COMMAND_RAW_LISTSTREAM:
|
2003-05-15 17:03:32 -04:00
|
|
|
command_list_mounts(client, RAW);
|
|
|
|
break;
|
2003-12-12 18:06:44 -05:00
|
|
|
case COMMAND_PLAINTEXT_LISTSTREAM:
|
|
|
|
command_list_mounts(client, PLAINTEXT);
|
|
|
|
break;
|
2003-05-15 17:03:32 -04:00
|
|
|
case COMMAND_TRANSFORMED_STATS:
|
|
|
|
command_stats(client, TRANSFORMED);
|
|
|
|
break;
|
|
|
|
case COMMAND_TRANSFORMED_LIST_MOUNTS:
|
|
|
|
command_list_mounts(client, TRANSFORMED);
|
|
|
|
break;
|
|
|
|
case COMMAND_TRANSFORMED_LISTSTREAM:
|
|
|
|
command_list_mounts(client, TRANSFORMED);
|
|
|
|
break;
|
|
|
|
case COMMAND_TRANSFORMED_MOVE_CLIENTS:
|
|
|
|
command_list_mounts(client, TRANSFORMED);
|
2003-03-09 09:12:24 -05:00
|
|
|
break;
|
2003-03-06 09:17:33 -05:00
|
|
|
default:
|
|
|
|
WARN0("General admin request not recognised");
|
|
|
|
client_send_400(client, "Unknown admin request");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void admin_handle_mount_request(client_t *client, source_t *source,
|
|
|
|
int command)
|
|
|
|
{
|
|
|
|
switch(command) {
|
2003-05-15 17:03:32 -04:00
|
|
|
case COMMAND_RAW_FALLBACK:
|
|
|
|
command_fallback(client, source, RAW);
|
2003-03-06 09:17:33 -05:00
|
|
|
break;
|
|
|
|
case COMMAND_METADATA_UPDATE:
|
|
|
|
command_metadata(client, source);
|
|
|
|
break;
|
2003-05-15 17:03:32 -04:00
|
|
|
case COMMAND_RAW_SHOW_LISTENERS:
|
|
|
|
command_show_listeners(client, source, RAW);
|
|
|
|
break;
|
|
|
|
case COMMAND_RAW_MOVE_CLIENTS:
|
|
|
|
command_move_clients(client, source, RAW);
|
|
|
|
break;
|
|
|
|
case COMMAND_RAW_KILL_CLIENT:
|
|
|
|
command_kill_client(client, source, RAW);
|
2003-03-07 09:57:36 -05:00
|
|
|
break;
|
2003-05-15 17:03:32 -04:00
|
|
|
case COMMAND_RAW_KILL_SOURCE:
|
|
|
|
command_kill_source(client, source, RAW);
|
2003-03-14 02:59:58 -05:00
|
|
|
break;
|
2003-05-15 17:03:32 -04:00
|
|
|
case COMMAND_TRANSFORMED_FALLBACK:
|
|
|
|
command_fallback(client, source, RAW);
|
2003-03-30 08:52:27 -05:00
|
|
|
break;
|
2003-05-15 17:03:32 -04:00
|
|
|
case COMMAND_TRANSFORMED_SHOW_LISTENERS:
|
|
|
|
command_show_listeners(client, source, TRANSFORMED);
|
|
|
|
break;
|
|
|
|
case COMMAND_TRANSFORMED_MOVE_CLIENTS:
|
|
|
|
command_move_clients(client, source, TRANSFORMED);
|
|
|
|
break;
|
|
|
|
case COMMAND_TRANSFORMED_KILL_CLIENT:
|
|
|
|
command_kill_client(client, source, TRANSFORMED);
|
|
|
|
break;
|
|
|
|
case COMMAND_TRANSFORMED_KILL_SOURCE:
|
|
|
|
command_kill_source(client, source, TRANSFORMED);
|
2003-03-31 07:54:44 -05:00
|
|
|
break;
|
2004-04-30 10:36:07 -04:00
|
|
|
case COMMAND_TRANSFORMED_MANAGEAUTH:
|
|
|
|
command_manageauth(client, source, TRANSFORMED);
|
|
|
|
break;
|
|
|
|
case COMMAND_RAW_MANAGEAUTH:
|
|
|
|
command_manageauth(client, source, RAW);
|
|
|
|
break;
|
2004-04-30 13:32:34 -04:00
|
|
|
case COMMAND_BUILDM3U:
|
|
|
|
command_buildm3u(client, source, RAW);
|
|
|
|
break;
|
2003-03-06 09:17:33 -05:00
|
|
|
default:
|
|
|
|
WARN0("Mount request not recognised");
|
|
|
|
client_send_400(client, "Mount request unknown");
|
2003-03-07 09:57:36 -05:00
|
|
|
break;
|
2003-03-06 09:17:33 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#define COMMAND_REQUIRE(client,name,var) \
|
|
|
|
do { \
|
|
|
|
(var) = httpp_get_query_param((client)->parser, (name)); \
|
|
|
|
if((var) == NULL) { \
|
|
|
|
client_send_400((client), "Missing parameter"); \
|
|
|
|
return; \
|
|
|
|
} \
|
|
|
|
} while(0);
|
2003-05-15 17:03:32 -04:00
|
|
|
#define COMMAND_OPTIONAL(client,name,var) \
|
|
|
|
(var) = httpp_get_query_param((client)->parser, (name))
|
2003-03-06 09:17:33 -05:00
|
|
|
|
2003-03-07 09:57:36 -05:00
|
|
|
static void html_success(client_t *client, char *message)
|
2003-03-06 09:17:33 -05:00
|
|
|
{
|
|
|
|
int bytes;
|
|
|
|
|
|
|
|
client->respcode = 200;
|
|
|
|
bytes = sock_write(client->con->sock,
|
|
|
|
"HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n"
|
|
|
|
"<html><head><title>Admin request successful</title></head>"
|
|
|
|
"<body><p>%s</p></body></html>", message);
|
|
|
|
if(bytes > 0) client->con->sent_bytes = bytes;
|
|
|
|
client_destroy(client);
|
|
|
|
}
|
|
|
|
|
2003-03-07 09:57:36 -05:00
|
|
|
static void html_write(client_t *client, char *fmt, ...)
|
|
|
|
{
|
|
|
|
int bytes;
|
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
va_start(ap, fmt);
|
|
|
|
bytes = sock_write_fmt(client->con->sock, fmt, ap);
|
|
|
|
va_end(ap);
|
|
|
|
if(bytes > 0) client->con->sent_bytes = bytes;
|
|
|
|
}
|
|
|
|
|
2003-05-15 17:03:32 -04:00
|
|
|
static void command_move_clients(client_t *client, source_t *source,
|
|
|
|
int response)
|
2003-03-14 02:59:58 -05:00
|
|
|
{
|
|
|
|
char *dest_source;
|
|
|
|
source_t *dest;
|
2003-05-15 17:03:32 -04:00
|
|
|
xmlDocPtr doc;
|
|
|
|
xmlNodePtr node;
|
|
|
|
char buf[255];
|
|
|
|
int parameters_passed = 0;
|
|
|
|
|
|
|
|
DEBUG0("Doing optional check");
|
2003-05-28 09:43:48 -04:00
|
|
|
if((COMMAND_OPTIONAL(client, "destination", dest_source))) {
|
2003-05-15 17:03:32 -04:00
|
|
|
parameters_passed = 1;
|
|
|
|
}
|
|
|
|
DEBUG1("Done optional check (%d)", parameters_passed);
|
|
|
|
if (!parameters_passed) {
|
|
|
|
doc = admin_build_sourcelist(source->mount);
|
|
|
|
admin_send_response(doc, client, response,
|
|
|
|
MOVECLIENTS_TRANSFORMED_REQUEST);
|
|
|
|
xmlFreeDoc(doc);
|
|
|
|
client_destroy(client);
|
|
|
|
return;
|
|
|
|
}
|
2004-01-27 20:22:36 -05:00
|
|
|
|
2004-01-29 11:46:54 -05:00
|
|
|
dest = source_find_mount (dest_source);
|
|
|
|
|
|
|
|
if (dest == NULL)
|
|
|
|
{
|
|
|
|
client_send_400 (client, "No such destination");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2004-02-02 19:48:02 -05:00
|
|
|
if (strcmp (dest->mount, source->mount) == 0)
|
2004-01-27 20:22:36 -05:00
|
|
|
{
|
|
|
|
client_send_400 (client, "supplied mountpoints are identical");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2004-01-29 11:46:54 -05:00
|
|
|
if (dest->running == 0)
|
|
|
|
{
|
|
|
|
client_send_400 (client, "Destination not running");
|
2003-03-14 02:59:58 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2003-05-15 17:03:32 -04:00
|
|
|
doc = xmlNewDoc("1.0");
|
|
|
|
node = xmlNewDocNode(doc, NULL, "iceresponse", NULL);
|
|
|
|
xmlDocSetRootElement(doc, node);
|
|
|
|
|
2004-01-29 11:46:54 -05:00
|
|
|
source_move_clients (source, dest);
|
2003-03-14 02:59:58 -05:00
|
|
|
|
2003-05-15 17:03:32 -04:00
|
|
|
memset(buf, '\000', sizeof(buf));
|
2004-01-29 11:46:54 -05:00
|
|
|
snprintf (buf, sizeof(buf), "Clients moved from %s to %s",
|
|
|
|
source->mount, dest_source);
|
2003-05-15 17:03:32 -04:00
|
|
|
xmlNewChild(node, NULL, "message", buf);
|
|
|
|
xmlNewChild(node, NULL, "return", "1");
|
|
|
|
|
|
|
|
admin_send_response(doc, client, response,
|
|
|
|
ADMIN_XSL_RESPONSE);
|
|
|
|
xmlFreeDoc(doc);
|
|
|
|
client_destroy(client);
|
2003-03-14 02:59:58 -05:00
|
|
|
}
|
|
|
|
|
2003-05-15 17:03:32 -04:00
|
|
|
static void command_show_listeners(client_t *client, source_t *source,
|
|
|
|
int response)
|
2003-03-07 09:57:36 -05:00
|
|
|
{
|
2003-05-15 17:03:32 -04:00
|
|
|
xmlDocPtr doc;
|
|
|
|
xmlNodePtr node, srcnode, listenernode;
|
2003-03-07 09:57:36 -05:00
|
|
|
avl_node *client_node;
|
|
|
|
client_t *current;
|
2003-05-15 17:03:32 -04:00
|
|
|
char buf[22];
|
|
|
|
char *userAgent = NULL;
|
2003-03-07 09:57:36 -05:00
|
|
|
time_t now = time(NULL);
|
|
|
|
|
2003-05-15 17:03:32 -04:00
|
|
|
doc = xmlNewDoc("1.0");
|
|
|
|
node = xmlNewDocNode(doc, NULL, "icestats", NULL);
|
|
|
|
srcnode = xmlNewChild(node, NULL, "source", NULL);
|
|
|
|
xmlSetProp(srcnode, "mount", source->mount);
|
|
|
|
xmlDocSetRootElement(doc, node);
|
2003-03-07 09:57:36 -05:00
|
|
|
|
2003-05-15 17:03:32 -04:00
|
|
|
memset(buf, '\000', sizeof(buf));
|
2003-05-28 09:43:48 -04:00
|
|
|
snprintf(buf, sizeof(buf)-1, "%ld", source->listeners);
|
2003-05-15 17:03:32 -04:00
|
|
|
xmlNewChild(srcnode, NULL, "Listeners", buf);
|
2003-03-07 09:57:36 -05:00
|
|
|
|
|
|
|
avl_tree_rlock(source->client_tree);
|
|
|
|
|
|
|
|
client_node = avl_get_first(source->client_tree);
|
|
|
|
while(client_node) {
|
|
|
|
current = (client_t *)client_node->key;
|
2003-05-15 17:03:32 -04:00
|
|
|
listenernode = xmlNewChild(srcnode, NULL, "listener", NULL);
|
|
|
|
xmlNewChild(listenernode, NULL, "IP", current->con->ip);
|
|
|
|
userAgent = httpp_getvar(current->parser, "user-agent");
|
|
|
|
if (userAgent) {
|
|
|
|
xmlNewChild(listenernode, NULL, "UserAgent", userAgent);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
xmlNewChild(listenernode, NULL, "UserAgent", "Unknown");
|
|
|
|
}
|
|
|
|
memset(buf, '\000', sizeof(buf));
|
2003-05-28 09:43:48 -04:00
|
|
|
snprintf(buf, sizeof(buf)-1, "%ld", now - current->con->con_time);
|
2003-05-15 17:03:32 -04:00
|
|
|
xmlNewChild(listenernode, NULL, "Connected", buf);
|
|
|
|
memset(buf, '\000', sizeof(buf));
|
2003-05-28 09:43:48 -04:00
|
|
|
snprintf(buf, sizeof(buf)-1, "%lu", current->con->id);
|
2003-05-15 17:03:32 -04:00
|
|
|
xmlNewChild(listenernode, NULL, "ID", buf);
|
2004-04-30 10:36:07 -04:00
|
|
|
if (current->username) {
|
|
|
|
xmlNewChild(listenernode, NULL, "username", current->username);
|
|
|
|
}
|
2003-03-07 09:57:36 -05:00
|
|
|
client_node = avl_get_next(client_node);
|
|
|
|
}
|
|
|
|
|
|
|
|
avl_tree_unlock(source->client_tree);
|
2003-05-15 17:03:32 -04:00
|
|
|
admin_send_response(doc, client, response,
|
|
|
|
LISTCLIENTS_TRANSFORMED_REQUEST);
|
|
|
|
xmlFreeDoc(doc);
|
2003-03-07 09:57:36 -05:00
|
|
|
client_destroy(client);
|
|
|
|
}
|
|
|
|
|
2004-04-30 13:32:34 -04:00
|
|
|
static void command_buildm3u(client_t *client, source_t *source,
|
|
|
|
int response)
|
|
|
|
{
|
|
|
|
char *username = NULL;
|
|
|
|
char *password = NULL;
|
|
|
|
char *host = NULL;
|
|
|
|
int port = 0;
|
|
|
|
ice_config_t *config;
|
|
|
|
|
|
|
|
COMMAND_REQUIRE(client, "username", username);
|
|
|
|
COMMAND_REQUIRE(client, "password", password);
|
|
|
|
|
|
|
|
config = config_get_config();
|
|
|
|
host = config->hostname;
|
|
|
|
port = config->port;
|
|
|
|
|
|
|
|
client->respcode = 200;
|
|
|
|
sock_write(client->con->sock,
|
|
|
|
"HTTP/1.0 200 OK\r\n"
|
|
|
|
"Content-Type: audio/x-mpegurl\r\n"
|
|
|
|
"Content-Disposition = attachment; filename=listen.m3u\r\n\r\n"
|
|
|
|
"http://%s:%s@%s:%d%s\r\n",
|
|
|
|
username,
|
|
|
|
password,
|
|
|
|
host,
|
|
|
|
port,
|
|
|
|
source->mount
|
|
|
|
);
|
|
|
|
|
|
|
|
client_destroy(client);
|
|
|
|
config_release_config();
|
|
|
|
}
|
2004-04-30 10:36:07 -04:00
|
|
|
static void command_manageauth(client_t *client, source_t *source,
|
|
|
|
int response)
|
|
|
|
{
|
|
|
|
xmlDocPtr doc;
|
|
|
|
xmlNodePtr node, srcnode, msgnode;
|
|
|
|
char *action = NULL;
|
|
|
|
char *username = NULL;
|
|
|
|
char *password = NULL;
|
|
|
|
char *message = NULL;
|
|
|
|
int ret = AUTH_OK;
|
|
|
|
|
|
|
|
if((COMMAND_OPTIONAL(client, "action", action))) {
|
|
|
|
if (!strcmp(action, "add")) {
|
|
|
|
COMMAND_REQUIRE(client, "username", username);
|
|
|
|
COMMAND_REQUIRE(client, "password", password);
|
|
|
|
ret = auth_adduser(source, username, password);
|
|
|
|
if (ret == AUTH_FAILED) {
|
|
|
|
message = strdup("User add failed - check the icecast error log");
|
|
|
|
}
|
|
|
|
if (ret == AUTH_USERADDED) {
|
|
|
|
message = strdup("User added");
|
|
|
|
}
|
|
|
|
if (ret == AUTH_USEREXISTS) {
|
|
|
|
message = strdup("User already exists - not added");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!strcmp(action, "delete")) {
|
|
|
|
COMMAND_REQUIRE(client, "username", username);
|
|
|
|
ret = auth_deleteuser(source, username);
|
|
|
|
if (ret == AUTH_FAILED) {
|
|
|
|
message = strdup("User delete failed - check the icecast error log");
|
|
|
|
}
|
|
|
|
if (ret == AUTH_USERDELETED) {
|
|
|
|
message = strdup("User deleted");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
doc = xmlNewDoc("1.0");
|
|
|
|
node = xmlNewDocNode(doc, NULL, "icestats", NULL);
|
|
|
|
srcnode = xmlNewChild(node, NULL, "source", NULL);
|
|
|
|
xmlSetProp(srcnode, "mount", source->mount);
|
|
|
|
|
|
|
|
if (message) {
|
|
|
|
msgnode = xmlNewChild(node, NULL, "iceresponse", NULL);
|
|
|
|
xmlNewChild(msgnode, NULL, "message", message);
|
|
|
|
}
|
|
|
|
|
|
|
|
xmlDocSetRootElement(doc, node);
|
|
|
|
|
|
|
|
auth_get_userlist(source, srcnode);
|
|
|
|
|
|
|
|
admin_send_response(doc, client, response,
|
|
|
|
MANAGEAUTH_TRANSFORMED_REQUEST);
|
|
|
|
if (message) {
|
|
|
|
free(message);
|
|
|
|
}
|
|
|
|
xmlFreeDoc(doc);
|
|
|
|
client_destroy(client);
|
|
|
|
}
|
|
|
|
|
2003-05-15 17:03:32 -04:00
|
|
|
static void command_kill_source(client_t *client, source_t *source,
|
|
|
|
int response)
|
2003-03-31 07:54:44 -05:00
|
|
|
{
|
2003-05-15 17:03:32 -04:00
|
|
|
xmlDocPtr doc;
|
|
|
|
xmlNodePtr node;
|
|
|
|
|
|
|
|
doc = xmlNewDoc("1.0");
|
|
|
|
node = xmlNewDocNode(doc, NULL, "iceresponse", NULL);
|
|
|
|
xmlNewChild(node, NULL, "message", "Source Removed");
|
|
|
|
xmlNewChild(node, NULL, "return", "1");
|
|
|
|
xmlDocSetRootElement(doc, node);
|
|
|
|
|
2003-03-31 07:54:44 -05:00
|
|
|
source->running = 0;
|
|
|
|
|
2003-05-15 17:03:32 -04:00
|
|
|
admin_send_response(doc, client, response,
|
|
|
|
ADMIN_XSL_RESPONSE);
|
|
|
|
xmlFreeDoc(doc);
|
|
|
|
client_destroy(client);
|
2003-03-31 07:54:44 -05:00
|
|
|
}
|
|
|
|
|
2003-05-15 17:03:32 -04:00
|
|
|
static void command_kill_client(client_t *client, source_t *source,
|
|
|
|
int response)
|
2003-03-30 08:52:27 -05:00
|
|
|
{
|
|
|
|
char *idtext;
|
|
|
|
int id;
|
|
|
|
client_t *listener;
|
2003-05-15 17:03:32 -04:00
|
|
|
xmlDocPtr doc;
|
|
|
|
xmlNodePtr node;
|
|
|
|
char buf[50] = "";
|
2003-03-30 08:52:27 -05:00
|
|
|
|
|
|
|
COMMAND_REQUIRE(client, "id", idtext);
|
|
|
|
|
|
|
|
id = atoi(idtext);
|
|
|
|
|
|
|
|
listener = source_find_client(source, id);
|
|
|
|
|
2003-05-15 17:03:32 -04:00
|
|
|
doc = xmlNewDoc("1.0");
|
|
|
|
node = xmlNewDocNode(doc, NULL, "iceresponse", NULL);
|
|
|
|
xmlDocSetRootElement(doc, node);
|
|
|
|
DEBUG1("Response is %d", response);
|
|
|
|
|
2003-03-30 08:52:27 -05:00
|
|
|
if(listener != NULL) {
|
|
|
|
INFO1("Admin request: client %d removed", id);
|
|
|
|
|
|
|
|
/* This tags it for removal on the next iteration of the main source
|
|
|
|
* loop
|
|
|
|
*/
|
|
|
|
listener->con->error = 1;
|
2003-05-15 17:03:32 -04:00
|
|
|
memset(buf, '\000', sizeof(buf));
|
|
|
|
snprintf(buf, sizeof(buf)-1, "Client %d removed", id);
|
|
|
|
xmlNewChild(node, NULL, "message", buf);
|
|
|
|
xmlNewChild(node, NULL, "return", "1");
|
2003-03-30 08:52:27 -05:00
|
|
|
}
|
|
|
|
else {
|
2003-05-15 17:03:32 -04:00
|
|
|
memset(buf, '\000', sizeof(buf));
|
|
|
|
snprintf(buf, sizeof(buf)-1, "Client %d not found", id);
|
|
|
|
xmlNewChild(node, NULL, "message", buf);
|
|
|
|
xmlNewChild(node, NULL, "return", "0");
|
2003-03-30 08:52:27 -05:00
|
|
|
}
|
2003-05-15 17:03:32 -04:00
|
|
|
admin_send_response(doc, client, response,
|
|
|
|
ADMIN_XSL_RESPONSE);
|
|
|
|
xmlFreeDoc(doc);
|
|
|
|
client_destroy(client);
|
2003-03-30 08:52:27 -05:00
|
|
|
}
|
|
|
|
|
2003-05-15 17:03:32 -04:00
|
|
|
static void command_fallback(client_t *client, source_t *source,
|
|
|
|
int response)
|
2003-03-06 09:17:33 -05:00
|
|
|
{
|
|
|
|
char *fallback;
|
|
|
|
char *old;
|
|
|
|
|
|
|
|
DEBUG0("Got fallback request");
|
|
|
|
|
|
|
|
COMMAND_REQUIRE(client, "fallback", fallback);
|
|
|
|
|
|
|
|
old = source->fallback_mount;
|
|
|
|
source->fallback_mount = strdup(fallback);
|
|
|
|
free(old);
|
|
|
|
|
2003-03-07 09:57:36 -05:00
|
|
|
html_success(client, "Fallback configured");
|
2003-03-06 09:17:33 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
static void command_metadata(client_t *client, source_t *source)
|
|
|
|
{
|
|
|
|
char *action;
|
|
|
|
char *value;
|
2004-02-26 05:39:56 -05:00
|
|
|
mp3_state *state;
|
2003-06-26 09:31:17 -04:00
|
|
|
#ifdef USE_YP
|
|
|
|
int i;
|
|
|
|
time_t current_time;
|
|
|
|
#endif
|
2003-03-06 09:17:33 -05:00
|
|
|
|
|
|
|
DEBUG0("Got metadata update request");
|
|
|
|
|
|
|
|
COMMAND_REQUIRE(client, "mode", action);
|
|
|
|
COMMAND_REQUIRE(client, "song", value);
|
|
|
|
|
2004-02-26 05:39:56 -05:00
|
|
|
if (source->format->type != FORMAT_TYPE_MP3)
|
2004-02-25 15:11:31 -05:00
|
|
|
{
|
|
|
|
client_send_400 (client, "Not mp3, cannot update metadata");
|
2003-03-06 09:17:33 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2004-02-25 15:11:31 -05:00
|
|
|
if (strcmp (action, "updinfo") != 0)
|
|
|
|
{
|
|
|
|
client_send_400 (client, "No such action");
|
2003-03-06 09:17:33 -05:00
|
|
|
return;
|
|
|
|
}
|
2004-02-26 05:39:56 -05:00
|
|
|
|
|
|
|
state = source->format->_state;
|
|
|
|
|
|
|
|
thread_mutex_lock(&(state->lock));
|
|
|
|
free(state->metadata);
|
|
|
|
state->metadata = strdup(value);
|
|
|
|
state->metadata_age++;
|
|
|
|
thread_mutex_unlock(&(state->lock));
|
2003-03-06 09:17:33 -05:00
|
|
|
|
2003-05-15 17:03:32 -04:00
|
|
|
DEBUG2("Metadata on mountpoint %s changed to \"%s\"",
|
|
|
|
source->mount, value);
|
2003-03-06 09:17:33 -05:00
|
|
|
stats_event(source->mount, "title", value);
|
2004-02-25 15:11:31 -05:00
|
|
|
|
2003-06-26 09:31:17 -04:00
|
|
|
#ifdef USE_YP
|
|
|
|
/* If we get an update on the mountpoint, force a
|
|
|
|
yp touch */
|
|
|
|
current_time = time(NULL);
|
|
|
|
for (i=0; i<source->num_yp_directories; i++) {
|
|
|
|
source->ypdata[i]->yp_last_touch = current_time -
|
|
|
|
source->ypdata[i]->yp_touch_interval + 2;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2003-03-07 09:57:36 -05:00
|
|
|
html_success(client, "Metadata update successful");
|
2003-03-06 09:17:33 -05:00
|
|
|
}
|
|
|
|
|
2003-05-15 17:03:32 -04:00
|
|
|
static void command_stats(client_t *client, int response) {
|
|
|
|
xmlDocPtr doc;
|
|
|
|
|
2003-03-06 09:17:33 -05:00
|
|
|
DEBUG0("Stats request, sending xml stats");
|
|
|
|
|
2003-05-15 17:03:32 -04:00
|
|
|
stats_get_xml(&doc);
|
|
|
|
admin_send_response(doc, client, response, STATS_TRANSFORMED_REQUEST);
|
|
|
|
xmlFreeDoc(doc);
|
2003-03-06 09:17:33 -05:00
|
|
|
client_destroy(client);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2004-02-25 16:43:52 -05:00
|
|
|
static void command_list_mounts(client_t *client, int response)
|
|
|
|
{
|
2003-12-12 18:06:44 -05:00
|
|
|
avl_node *node;
|
|
|
|
source_t *source;
|
2003-03-09 09:12:24 -05:00
|
|
|
|
|
|
|
DEBUG0("List mounts request");
|
|
|
|
|
2004-02-25 16:43:52 -05:00
|
|
|
avl_tree_rlock (global.source_tree);
|
2004-01-27 21:17:57 -05:00
|
|
|
if (response == PLAINTEXT)
|
|
|
|
{
|
2004-02-25 16:43:52 -05:00
|
|
|
char buffer [4096], *buf = buffer;
|
|
|
|
unsigned remaining = sizeof (buffer);
|
|
|
|
int ret = sprintf (buffer,
|
|
|
|
"HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n");
|
|
|
|
|
2003-12-12 18:06:44 -05:00
|
|
|
node = avl_get_first(global.source_tree);
|
2004-02-25 16:43:52 -05:00
|
|
|
while (node && ret > 0 && ret < remaining)
|
|
|
|
{
|
|
|
|
remaining -= ret;
|
|
|
|
buf += ret;
|
2003-12-12 18:06:44 -05:00
|
|
|
source = (source_t *)node->key;
|
2004-02-25 16:43:52 -05:00
|
|
|
ret = snprintf (buf, remaining, "%s\n", source->mount);
|
2003-12-12 18:06:44 -05:00
|
|
|
node = avl_get_next(node);
|
|
|
|
}
|
2004-02-25 16:43:52 -05:00
|
|
|
avl_tree_unlock (global.source_tree);
|
|
|
|
/* handle last line */
|
|
|
|
if (ret > 0 && ret < remaining)
|
|
|
|
{
|
|
|
|
remaining -= ret;
|
|
|
|
buf += ret;
|
|
|
|
}
|
|
|
|
sock_write_bytes (client->con->sock, buffer, sizeof (buffer)-remaining);
|
2003-12-12 18:06:44 -05:00
|
|
|
}
|
2004-02-25 16:43:52 -05:00
|
|
|
else
|
|
|
|
{
|
|
|
|
xmlDocPtr doc = admin_build_sourcelist(NULL);
|
|
|
|
avl_tree_unlock (global.source_tree);
|
2003-12-12 18:06:44 -05:00
|
|
|
|
|
|
|
admin_send_response(doc, client, response,
|
|
|
|
LISTMOUNTS_TRANSFORMED_REQUEST);
|
|
|
|
xmlFreeDoc(doc);
|
|
|
|
}
|
2003-03-09 09:12:24 -05:00
|
|
|
client_destroy(client);
|
2003-12-12 18:06:44 -05:00
|
|
|
|
2003-03-09 09:12:24 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|