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
|
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
|
||||||
|
74
src/admin.c
74
src/admin.c
@ -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) {
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user