From 9db452e96bb3eb1a2a934c23b9ba5fb4f3dd1730 Mon Sep 17 00:00:00 2001 From: Alex 'AdUser' Z Date: Thu, 21 Apr 2016 16:17:47 +1000 Subject: [PATCH] + commands.[ch] --- src/commands.c | 164 +++++++++++++++++++++++++++++++++++++++++++++++++ src/commands.h | 18 ++++++ 2 files changed, 182 insertions(+) create mode 100644 src/commands.c create mode 100644 src/commands.h diff --git a/src/commands.c b/src/commands.c new file mode 100644 index 0000000..50443b2 --- /dev/null +++ b/src/commands.c @@ -0,0 +1,164 @@ +/* Copyright 2016 Alex 'AdUser' Z (ad_user@runbox.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include "common.h" +#include "cmsg.h" +#include "commands.h" + +struct f2b_cmd_t { + const char *help; + const char *tokens[CMD_TOKENS_MAX]; + char *data; +} commands[] = { + [CMD_NONE] = { + .tokens = { NULL }, + .help = "Unspecified command" + }, + [CMD_RESP] = { + .tokens = { NULL }, + .help = "Command response, used internally", + }, + [CMD_HELP] = { + .tokens = { "help", NULL }, + .help = "Show available commands", + }, + [CMD_PING] = { + .tokens = { "ping", NULL }, + .help = "Check the connection", + }, + [CMD_STATUS] = { + .tokens = { "status", NULL }, + .help = "Show general stats and jails list", + }, + [CMD_ROTATE] = { + .tokens = { "rotate", NULL }, + .help = "Reopen daemon's own log file", + }, + [CMD_RELOAD] = { + .tokens = { "reload", NULL }, + .help = "Reload own config, all jails will be reset.", + }, + [CMD_SHUTDOWN] = { + .tokens = { "shutdown", NULL }, + .help = "Gracefully terminate f2b daemon", + }, + [CMD_JAIL_STATUS] = { + .tokens = { "jail", "", "status", NULL }, + .help = "Show status and stats of given jail", + }, + [CMD_JAIL_SET] = { + .tokens = { "jail", "", "set", "", "", NULL }, + .help = "Set parameter of given jail", + }, + [CMD_JAIL_IP_SHOW] = { + .tokens = { "jail", "", "show", "", NULL }, + .help = "Show ip status in given jail", + }, + [CMD_JAIL_IP_BAN] = { + .tokens = { "jail", "", "ban", "", NULL }, + .help = "Forcefully ban some ip in given jail", + }, + [CMD_JAIL_IP_RELEASE] = { + .tokens = { "jail", "", "release", "", NULL }, + .help = "Forcefully release some ip in given jail", + }, +}; + +void +f2b_cmd_help() { + struct f2b_cmd_t *cmd = NULL; + const char **p = NULL; + + fputs("Available commands:\n\n", stdout); + for (size_t i = CMD_PING; i < CMD_MAX_NUMBER; i++) { + cmd = &commands[i]; + if (cmd->tokens[0] == NULL) + continue; + for (p = cmd->tokens; *p != NULL; p++) + fprintf(stdout, "%s ", *p); + fprintf(stdout, "\n\t%s\n\n", cmd->help); + } + + return; +} + +/** + * @brief Parse command from line + * @param src Line taken from user input + * @param buf Buffer for command parameters + * @param buflen Size of buffer above + * @return Type of parsed command or CMD_NONE if no matches + */ +enum f2b_cmsg_type +f2b_cmd_parse(const char *src, char *buf, size_t buflen) { + size_t tokenc = 0; /* tokens count */ + char *tokens[CMD_TOKENS_MAX] = { NULL }; + char line[INPUT_LINE_MAX]; + char *p; + + assert(line != NULL); + /* strip leading spaces */ + while (isblank(*line)) + src++; + /* strip trailing spaces, newlines, etc */ + strlcpy(line, src, sizeof(line)); + for (size_t l = strlen(line); l > 0 && isspace(line[l]); l--) + line[l - 1] = '\0'; + + if (line[0] == '\0') + return CMD_NONE; /* empty string */ + tokenc = 1; + + buf[0] = '\0'; + + /* split string to tokens */ + tokens[0] = strtok_r(line, " \t", &p); + for (size_t i = 1; i < CMD_TOKENS_MAX; i++) { + tokens[i] = strtok_r(NULL, " \t", &p); + if (tokens[i] == NULL) + break; + tokenc++; + } + + if (strcmp(line, "ping") == 0) { return CMD_PING; } + else if (strcmp(line, "help") == 0) { return CMD_HELP; } + else if (strcmp(line, "status") == 0) { return CMD_STATUS; } + else if (strcmp(line, "rotate") == 0) { return CMD_ROTATE; } + else if (strcmp(line, "reload") == 0) { return CMD_RELOAD; } + else if (strcmp(line, "shutdown") == 0) { return CMD_SHUTDOWN; } + else if (strcmp(line, "jail") == 0 && tokenc > 1) { + /* commands for jail */ + strlcpy(buf, tokens[1], buflen); + strlcat(buf, "\n", buflen); + if (tokenc == 3 && strcmp(tokens[2], "status") == 0) { + return CMD_JAIL_STATUS; + } + if (tokenc == 5 && strcmp(tokens[2], "set") == 0) { + strlcat(buf, tokens[3], buflen); + strlcat(buf, "\n", buflen); + strlcat(buf, tokens[4], buflen); + strlcat(buf, "\n", buflen); + return CMD_JAIL_SET; + } + if (tokenc == 4 && strcmp(tokens[2], "show") == 0) { + strlcat(buf, tokens[3], buflen); + strlcat(buf, "\n", buflen); + return CMD_JAIL_IP_SHOW; + } + if (tokenc == 4 && strcmp(tokens[2], "ban") == 0) { + strlcat(buf, tokens[3], buflen); + strlcat(buf, "\n", buflen); + return CMD_JAIL_IP_BAN; + } + if (tokenc == 4 && strcmp(tokens[2], "release") == 0) { + strlcat(buf, tokens[3], buflen); + strlcat(buf, "\n", buflen); + return CMD_JAIL_IP_RELEASE; + } + } + + return CMD_NONE; +} diff --git a/src/commands.h b/src/commands.h new file mode 100644 index 0000000..366c874 --- /dev/null +++ b/src/commands.h @@ -0,0 +1,18 @@ +/* Copyright 2016 Alex 'AdUser' Z (ad_user@runbox.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef F2B_COMMANDS_H_ +#define F2B_COMMANDS_H_ + +/* yes, i know about LINE_MAX */ +#define INPUT_LINE_MAX 256 +#define CMD_TOKENS_MAX 6 + +void f2b_cmd_help(); +enum f2b_cmsg_type +f2b_cmd_parse(const char *src, char *buf, size_t buflen); + +#endif /* F2B_COMMANDS_H_ */