Commit 822057ca authored by Philipp Schafft's avatar Philipp Schafft 🦁

Feature: Allow registering new admin commands on the fly

parent bc38c935
......@@ -46,6 +46,8 @@
#define CATMODULE "admin"
#define ADMIN_MAX_COMMAND_TABLES 8
/* Helper macros */
#define COMMAND_REQUIRE(client,name,var) \
do { \
......@@ -94,15 +96,6 @@
#define DEFAULT_TRANSFORMED_REQUEST ""
#define BUILDM3U_RAW_REQUEST "buildm3u"
typedef void (*request_function_ptr)(client_t *, source_t *, admin_format_t);
typedef struct admin_command_handler {
const char *route;
const int type;
const int format;
const request_function_ptr function;
} admin_command_handler_t;
typedef struct {
const char *prefix;
size_t length;
......@@ -157,7 +150,7 @@ static const admin_command_handler_t handlers[] = {
{ DEFAULT_RAW_REQUEST, ADMINTYPE_HYBRID, ADMIN_FORMAT_TRANSFORMED, command_stats }
};
static admin_command_table_t command_tables[] = {
static admin_command_table_t command_tables[ADMIN_MAX_COMMAND_TABLES] = {
{.prefix = NULL, .length = (sizeof(handlers)/sizeof(*handlers)), .handlers = handlers},
};
......@@ -288,6 +281,41 @@ int admin_get_command_type(admin_command_id_t command)
return ADMINTYPE_ERROR;
}
int admin_command_table_register(const char *prefix, size_t handlers_length, const admin_command_handler_t *handlers)
{
size_t i;
if (prefix == NULL || handlers_length == 0 || handlers == NULL)
return -1;
for (i = 0; i < (sizeof(command_tables)/sizeof(*command_tables)); i++) {
if (__is_command_table_valid(&(command_tables[i])))
continue;
command_tables[i].prefix = prefix;
command_tables[i].length = handlers_length;
command_tables[i].handlers = handlers;
return 0;
}
return -1;
}
int admin_command_table_unregister(const char *prefix)
{
size_t i;
for (i = 0; i < (sizeof(command_tables)/sizeof(*command_tables)); i++) {
if (command_tables[i].prefix != NULL && strcmp(command_tables[i].prefix, prefix) == 0) {
memset(&(command_tables[i]), 0, sizeof(command_tables[i]));
return 0;
}
}
return -1;
}
/* build an XML doc containing information about currently running sources.
* If a mountpoint is passed then that source will not be added to the XML
* doc even if the source is running */
......
......@@ -45,6 +45,15 @@ typedef enum {
#define ADMIN_COMMAND_ERROR ((admin_command_id_t)(-1))
#define ADMIN_COMMAND_ANY ((admin_command_id_t)0) /* for ACL framework */
typedef void (*admin_request_function_ptr)(client_t * client, source_t * source, admin_format_t format);
typedef struct admin_command_handler {
const char *route;
const int type;
const int format;
const admin_request_function_ptr function;
} admin_command_handler_t;
void admin_handle_request(client_t *client, const char *uri);
void admin_send_response(xmlDocPtr doc,
......@@ -61,4 +70,10 @@ xmlNodePtr admin_add_role_to_authentication(auth_t *auth, xmlNodePtr parent);
admin_command_id_t admin_get_command(const char *command);
int admin_get_command_type(admin_command_id_t command);
/* Register and unregister admin commands below /admin/$prefix/.
* All parameters must be kept in memory as long as the registration is valid as there will be no copy made.
*/
int admin_command_table_register(const char *prefix, size_t handlers_length, const admin_command_handler_t *handlers);
int admin_command_table_unregister(const char *prefix);
#endif /* __ADMIN_H__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment