1
0
mirror of https://gitlab.xiph.org/xiph/icecast-server.git synced 2024-12-04 14:46:30 -05:00

Implement listing of all currently connected clients on a mountpoint

svn path=/trunk/icecast/; revision=4434
This commit is contained in:
Michael Smith 2003-03-07 14:57:36 +00:00
parent d1e8e7bfb7
commit b520eb3272
4 changed files with 92 additions and 4 deletions

11
News
View File

@ -1,3 +1,14 @@
2003-03-08
Started implementing generic admin interface. Supports (so far):
- dynamic configuration of mount fallbacks
/admin/fallbacks?mount=/mount&fallback=/fallback
- setting of mp3 metadata
/admin/metadata?mount=/mount&mode=updinfo&song=New%20Title
- dumping raw xml stats
/admin/rawstats
- listing all connected clients on a mountpoint:
/admin/listclients?mount=/mountname
2003-03-05 2003-03-05
Implemented the ability to reread the config file on SIGHUP. For now, this Implemented the ability to reread the config file on SIGHUP. For now, this
does not affect configuration for currently running sources (only new does not affect configuration for currently running sources (only new

View File

@ -1,5 +1,7 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h>
#include <time.h>
#include "config.h" #include "config.h"
#include "connection.h" #include "connection.h"
@ -21,6 +23,7 @@
#define COMMAND_FALLBACK 1 #define COMMAND_FALLBACK 1
#define COMMAND_RAW_STATS 2 #define COMMAND_RAW_STATS 2
#define COMMAND_METADATA_UPDATE 3 #define COMMAND_METADATA_UPDATE 3
#define COMMAND_SHOW_LISTENERS 4
int admin_get_command(char *command) int admin_get_command(char *command)
{ {
@ -32,12 +35,15 @@ int admin_get_command(char *command)
return COMMAND_RAW_STATS; return COMMAND_RAW_STATS;
else if(!strcmp(command, "metadata")) else if(!strcmp(command, "metadata"))
return COMMAND_METADATA_UPDATE; return COMMAND_METADATA_UPDATE;
else if(!strcmp(command, "listclients"))
return COMMAND_SHOW_LISTENERS;
else else
return COMMAND_ERROR; return COMMAND_ERROR;
} }
static void command_fallback(client_t *client, source_t *source); static void command_fallback(client_t *client, source_t *source);
static void command_metadata(client_t *client, source_t *source); static void command_metadata(client_t *client, source_t *source);
static void command_show_listeners(client_t *client, source_t *source);
static void command_raw_stats(client_t *client); static void command_raw_stats(client_t *client);
@ -132,10 +138,13 @@ static void admin_handle_mount_request(client_t *client, source_t *source,
case COMMAND_METADATA_UPDATE: case COMMAND_METADATA_UPDATE:
command_metadata(client, source); command_metadata(client, source);
break; break;
case COMMAND_SHOW_LISTENERS:
command_show_listeners(client, source);
break;
default: default:
WARN0("Mount request not recognised"); WARN0("Mount request not recognised");
client_send_400(client, "Mount request unknown"); client_send_400(client, "Mount request unknown");
return; break;
} }
} }
@ -148,7 +157,7 @@ static void admin_handle_mount_request(client_t *client, source_t *source,
} \ } \
} while(0); } while(0);
static void command_success(client_t *client, char *message) static void html_success(client_t *client, char *message)
{ {
int bytes; int bytes;
@ -161,6 +170,63 @@ static void command_success(client_t *client, char *message)
client_destroy(client); client_destroy(client);
} }
static void html_head(client_t *client)
{
int bytes;
client->respcode = 200;
bytes = sock_write(client->con->sock,
"HTTP/1.0 200 OK\r\n"
"Content-Type: text/html\r\n"
"\r\n"
"<html><head><title>Admin request</title></head>"
"<body>");
if(bytes > 0) client->con->sent_bytes = bytes;
}
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;
}
static void command_show_listeners(client_t *client, source_t *source)
{
avl_node *client_node;
client_t *current;
time_t now = time(NULL);
DEBUG1("Dumping listeners on mountpoint %s", source->mount);
html_head(client);
html_write(client,
"<table><tr><td>IP</td><td>Connected</td><td>ID</td></tr>");
avl_tree_rlock(source->client_tree);
client_node = avl_get_first(source->client_tree);
while(client_node) {
current = (client_t *)client_node->key;
html_write(client, "<tr><td>%s</td><td>%d</td><td>%ld</td></tr>",
current->con->ip, now-current->con->con_time, current->con->id);
client_node = avl_get_next(client_node);
}
avl_tree_unlock(source->client_tree);
html_write(client, "</table></body></html>");
client_destroy(client);
}
static void command_fallback(client_t *client, source_t *source) static void command_fallback(client_t *client, source_t *source)
{ {
char *fallback; char *fallback;
@ -174,7 +240,7 @@ static void command_fallback(client_t *client, source_t *source)
source->fallback_mount = strdup(fallback); source->fallback_mount = strdup(fallback);
free(old); free(old);
command_success(client, "Fallback configured"); 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)
@ -210,7 +276,7 @@ static void command_metadata(client_t *client, source_t *source)
DEBUG2("Metadata on mountpoint %s changed to \"%s\"", source->mount, value); DEBUG2("Metadata on mountpoint %s changed to \"%s\"", source->mount, value);
stats_event(source->mount, "title", value); stats_event(source->mount, "title", value);
command_success(client, "Metadata update successful"); html_success(client, "Metadata update successful");
} }
static void command_raw_stats(client_t *client) { static void command_raw_stats(client_t *client) {

View File

@ -314,6 +314,15 @@ int sock_write(sock_t sock, const char *fmt, ...)
return sock_write_bytes(sock, buff, strlen(buff)); return sock_write_bytes(sock, buff, strlen(buff));
} }
int sock_write_fmt(sock_t sock, char *fmt, va_list ap)
{
char buff[1024];
vsnprintf(buff, 1024, fmt, ap);
return sock_write_bytes(sock, buff, strlen(buff));
}
int sock_read_bytes(sock_t sock, char *buff, const int len) int sock_read_bytes(sock_t sock, char *buff, const int len)
{ {

View File

@ -22,6 +22,7 @@
#ifndef __SOCK_H #ifndef __SOCK_H
#define __SOCK_H #define __SOCK_H
#include <stdarg.h>
#ifdef _WIN32 #ifdef _WIN32
#include <winsock2.h> #include <winsock2.h>
@ -87,6 +88,7 @@ int sock_connected (int sock, unsigned timeout);
/* Socket write functions */ /* Socket write functions */
int sock_write_bytes(sock_t sock, const void *buff, const size_t len); int sock_write_bytes(sock_t sock, const void *buff, const size_t len);
int sock_write(sock_t sock, const char *fmt, ...); int sock_write(sock_t sock, const char *fmt, ...);
int sock_write_fmt(sock_t sock, char *fmt, va_list ap);
int sock_write_string(sock_t sock, const char *buff); int sock_write_string(sock_t sock, const char *buff);
ssize_t sock_writev (int sock, const struct iovec *iov, const size_t count); ssize_t sock_writev (int sock, const struct iovec *iov, const size_t count);