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:
parent
d1e8e7bfb7
commit
b520eb3272
11
News
11
News
@ -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
|
||||
Implemented the ability to reread the config file on SIGHUP. For now, this
|
||||
does not affect configuration for currently running sources (only new
|
||||
|
74
src/admin.c
74
src/admin.c
@ -1,5 +1,7 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "connection.h"
|
||||
@ -21,6 +23,7 @@
|
||||
#define COMMAND_FALLBACK 1
|
||||
#define COMMAND_RAW_STATS 2
|
||||
#define COMMAND_METADATA_UPDATE 3
|
||||
#define COMMAND_SHOW_LISTENERS 4
|
||||
|
||||
int admin_get_command(char *command)
|
||||
{
|
||||
@ -32,12 +35,15 @@ int admin_get_command(char *command)
|
||||
return COMMAND_RAW_STATS;
|
||||
else if(!strcmp(command, "metadata"))
|
||||
return COMMAND_METADATA_UPDATE;
|
||||
else if(!strcmp(command, "listclients"))
|
||||
return COMMAND_SHOW_LISTENERS;
|
||||
else
|
||||
return COMMAND_ERROR;
|
||||
}
|
||||
|
||||
static void command_fallback(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);
|
||||
|
||||
@ -132,10 +138,13 @@ static void admin_handle_mount_request(client_t *client, source_t *source,
|
||||
case COMMAND_METADATA_UPDATE:
|
||||
command_metadata(client, source);
|
||||
break;
|
||||
case COMMAND_SHOW_LISTENERS:
|
||||
command_show_listeners(client, source);
|
||||
break;
|
||||
default:
|
||||
WARN0("Mount request not recognised");
|
||||
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);
|
||||
|
||||
static void command_success(client_t *client, char *message)
|
||||
static void html_success(client_t *client, char *message)
|
||||
{
|
||||
int bytes;
|
||||
|
||||
@ -161,6 +170,63 @@ static void command_success(client_t *client, char *message)
|
||||
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)
|
||||
{
|
||||
char *fallback;
|
||||
@ -174,7 +240,7 @@ static void command_fallback(client_t *client, source_t *source)
|
||||
source->fallback_mount = strdup(fallback);
|
||||
free(old);
|
||||
|
||||
command_success(client, "Fallback configured");
|
||||
html_success(client, "Fallback configured");
|
||||
}
|
||||
|
||||
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);
|
||||
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) {
|
||||
|
@ -314,6 +314,15 @@ int sock_write(sock_t sock, const char *fmt, ...)
|
||||
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)
|
||||
{
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
#ifndef __SOCK_H
|
||||
#define __SOCK_H
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
@ -87,6 +88,7 @@ int sock_connected (int sock, unsigned timeout);
|
||||
/* Socket write functions */
|
||||
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_fmt(sock_t sock, char *fmt, va_list ap);
|
||||
int sock_write_string(sock_t sock, const char *buff);
|
||||
ssize_t sock_writev (int sock, const struct iovec *iov, const size_t count);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user