Files
ginxsom/src/admin_handlers.c
2025-11-20 07:53:58 -04:00

216 lines
7.5 KiB
C

/*
* Ginxsom Admin Command Handlers
* Implements execution of admin commands received via Kind 23456 events
*/
#include "ginxsom.h"
#include <cjson/cJSON.h>
#include <sqlite3.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/statvfs.h>
#include <dirent.h>
// Forward declarations
static cJSON* handle_blob_list(char **args, int arg_count);
static cJSON* handle_blob_info(char **args, int arg_count);
static cJSON* handle_blob_delete(char **args, int arg_count);
static cJSON* handle_storage_stats(char **args, int arg_count);
static cJSON* handle_config_get(char **args, int arg_count);
static cJSON* handle_config_set(char **args, int arg_count);
static cJSON* handle_help(char **args, int arg_count);
// Command dispatch table
typedef struct {
const char *command;
cJSON* (*handler)(char **args, int arg_count);
const char *description;
} admin_command_t;
static admin_command_t command_table[] = {
{"blob_list", handle_blob_list, "List all blobs"},
{"blob_info", handle_blob_info, "Get blob information"},
{"blob_delete", handle_blob_delete, "Delete a blob"},
{"storage_stats", handle_storage_stats, "Get storage statistics"},
{"config_get", handle_config_get, "Get configuration value"},
{"config_set", handle_config_set, "Set configuration value"},
{"help", handle_help, "Show available commands"},
{NULL, NULL, NULL}
};
// Execute admin command and return JSON response
int execute_admin_command(char **command_array, int command_count, char **response_json_out) {
if (!command_array || command_count < 1 || !response_json_out) {
return -1;
}
const char *command = command_array[0];
// Find command handler
admin_command_t *cmd = NULL;
for (int i = 0; command_table[i].command != NULL; i++) {
if (strcmp(command_table[i].command, command) == 0) {
cmd = &command_table[i];
break;
}
}
cJSON *response;
if (cmd) {
// Execute command handler
response = cmd->handler(command_array + 1, command_count - 1);
} else {
// Unknown command
response = cJSON_CreateObject();
cJSON_AddStringToObject(response, "status", "error");
cJSON_AddStringToObject(response, "message", "Unknown command");
cJSON_AddStringToObject(response, "command", command);
}
// Convert response to JSON string
char *json_str = cJSON_PrintUnformatted(response);
cJSON_Delete(response);
if (!json_str) {
return -1;
}
*response_json_out = json_str;
return 0;
}
// Command handlers
static cJSON* handle_blob_list(char **args __attribute__((unused)), int arg_count __attribute__((unused))) {
cJSON *response = cJSON_CreateObject();
cJSON_AddStringToObject(response, "status", "success");
cJSON_AddStringToObject(response, "command", "blob_list");
// TODO: Implement actual blob listing from database
cJSON *blobs = cJSON_CreateArray();
cJSON_AddItemToObject(response, "blobs", blobs);
cJSON_AddNumberToObject(response, "count", 0);
return response;
}
static cJSON* handle_blob_info(char **args, int arg_count) {
cJSON *response = cJSON_CreateObject();
if (arg_count < 1) {
cJSON_AddStringToObject(response, "status", "error");
cJSON_AddStringToObject(response, "message", "Missing blob hash argument");
return response;
}
cJSON_AddStringToObject(response, "status", "success");
cJSON_AddStringToObject(response, "command", "blob_info");
cJSON_AddStringToObject(response, "hash", args[0]);
// TODO: Implement actual blob info retrieval from database
cJSON_AddStringToObject(response, "message", "Not yet implemented");
return response;
}
static cJSON* handle_blob_delete(char **args, int arg_count) {
cJSON *response = cJSON_CreateObject();
if (arg_count < 1) {
cJSON_AddStringToObject(response, "status", "error");
cJSON_AddStringToObject(response, "message", "Missing blob hash argument");
return response;
}
cJSON_AddStringToObject(response, "status", "success");
cJSON_AddStringToObject(response, "command", "blob_delete");
cJSON_AddStringToObject(response, "hash", args[0]);
// TODO: Implement actual blob deletion
cJSON_AddStringToObject(response, "message", "Not yet implemented");
return response;
}
static cJSON* handle_storage_stats(char **args __attribute__((unused)), int arg_count __attribute__((unused))) {
cJSON *response = cJSON_CreateObject();
cJSON_AddStringToObject(response, "status", "success");
cJSON_AddStringToObject(response, "command", "storage_stats");
// Get filesystem stats
struct statvfs stat;
if (statvfs(".", &stat) == 0) {
unsigned long long total = stat.f_blocks * stat.f_frsize;
unsigned long long available = stat.f_bavail * stat.f_frsize;
unsigned long long used = total - available;
cJSON_AddNumberToObject(response, "total_bytes", (double)total);
cJSON_AddNumberToObject(response, "used_bytes", (double)used);
cJSON_AddNumberToObject(response, "available_bytes", (double)available);
}
// TODO: Add blob count and total blob size from database
cJSON_AddNumberToObject(response, "blob_count", 0);
cJSON_AddNumberToObject(response, "blob_total_bytes", 0);
return response;
}
static cJSON* handle_config_get(char **args, int arg_count) {
cJSON *response = cJSON_CreateObject();
if (arg_count < 1) {
cJSON_AddStringToObject(response, "status", "error");
cJSON_AddStringToObject(response, "message", "Missing config key argument");
return response;
}
cJSON_AddStringToObject(response, "status", "success");
cJSON_AddStringToObject(response, "command", "config_get");
cJSON_AddStringToObject(response, "key", args[0]);
// TODO: Implement actual config retrieval from database
cJSON_AddStringToObject(response, "value", "");
cJSON_AddStringToObject(response, "message", "Not yet implemented");
return response;
}
static cJSON* handle_config_set(char **args, int arg_count) {
cJSON *response = cJSON_CreateObject();
if (arg_count < 2) {
cJSON_AddStringToObject(response, "status", "error");
cJSON_AddStringToObject(response, "message", "Missing config key or value argument");
return response;
}
cJSON_AddStringToObject(response, "status", "success");
cJSON_AddStringToObject(response, "command", "config_set");
cJSON_AddStringToObject(response, "key", args[0]);
cJSON_AddStringToObject(response, "value", args[1]);
// TODO: Implement actual config update in database
cJSON_AddStringToObject(response, "message", "Not yet implemented");
return response;
}
static cJSON* handle_help(char **args __attribute__((unused)), int arg_count __attribute__((unused))) {
cJSON *response = cJSON_CreateObject();
cJSON_AddStringToObject(response, "status", "success");
cJSON_AddStringToObject(response, "command", "help");
cJSON *commands = cJSON_CreateArray();
for (int i = 0; command_table[i].command != NULL; i++) {
cJSON *cmd = cJSON_CreateObject();
cJSON_AddStringToObject(cmd, "command", command_table[i].command);
cJSON_AddStringToObject(cmd, "description", command_table[i].description);
cJSON_AddItemToArray(commands, cmd);
}
cJSON_AddItemToObject(response, "commands", commands);
return response;
}