]> source.dussan.org Git - rspamd.git/commitdiff
Add preliminary version of rspamadm control command
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 17 Oct 2015 12:42:12 +0000 (13:42 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 17 Oct 2015 12:42:12 +0000 (13:42 +0100)
src/rspamadm/CMakeLists.txt
src/rspamadm/commands.c
src/rspamadm/control.c [new file with mode: 0644]

index 13e0dc4771e7c479b75a7cf83e1027eda6a9ce0f..20cf3b3a0d86edf957550594c887b69dee35d627 100644 (file)
@@ -6,7 +6,7 @@ SET(RSPAMADMSRC rspamadm.c commands.c pw.c keypair.c configtest.c
         ${CMAKE_SOURCE_DIR}/src/lua_worker.c
         ${CMAKE_SOURCE_DIR}/src/smtp_proxy.c
         ${CMAKE_SOURCE_DIR}/src/worker.c
-        ${CMAKE_SOURCE_DIR}/src/http_proxy.c fuzzy_merge.c configdump.c)
+        ${CMAKE_SOURCE_DIR}/src/http_proxy.c fuzzy_merge.c configdump.c control.c)
 
 ADD_EXECUTABLE(rspamadm ${RSPAMADMSRC})
 TARGET_LINK_LIBRARIES(rspamadm rspamd-server)
index aa0302eb97574b4d14c731ceef473cfc9a53d33e..b2e2c87f57ac8962522d56c68cb91b0733b24f80 100644 (file)
@@ -28,6 +28,7 @@ extern struct rspamadm_command keypair_command;
 extern struct rspamadm_command configtest_command;
 extern struct rspamadm_command fuzzy_merge_command;
 extern struct rspamadm_command configdump_command;
+extern struct rspamadm_command control_command;
 
 const struct rspamadm_command *commands[] = {
        &help_command,
@@ -36,6 +37,7 @@ const struct rspamadm_command *commands[] = {
        &configtest_command,
        &fuzzy_merge_command,
        &configdump_command,
+       &control_command,
        NULL
 };
 
diff --git a/src/rspamadm/control.c b/src/rspamadm/control.c
new file mode 100644 (file)
index 0000000..55b286c
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2015, Vsevolod Stakhov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *      * Redistributions of source code must retain the above copyright
+ *        notice, this list of conditions and the following disclaimer.
+ *      * Redistributions in binary form must reproduce the above copyright
+ *        notice, this list of conditions and the following disclaimer in the
+ *        documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR ''AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "rspamadm.h"
+#include "cryptobox.h"
+#include "printf.h"
+#include "http.h"
+#include "addr.h"
+#include "unix-std.h"
+#include <event.h>
+#include "libutil/util.h"
+
+static gchar *control_path = RSPAMD_DBDIR "/rspamd.sock";
+gboolean json = FALSE;
+gboolean ucl = FALSE;
+gboolean compact = FALSE;
+gdouble timeout = 1.0;
+
+static void rspamadm_control (gint argc, gchar **argv);
+static const char *rspamadm_control_help (gboolean full_help);
+
+struct rspamadm_command control_command = {
+               .name = "control",
+               .flags = 0,
+               .help = rspamadm_control_help,
+               .run = rspamadm_control
+};
+
+static GOptionEntry entries[] = {
+               {"json", 'j', 0, G_OPTION_ARG_NONE, &json,
+                               "Output json",                    NULL},
+               {"ucl", 'u', 0, G_OPTION_ARG_NONE, &ucl,
+                               "Output UCL",     NULL},
+               {"compact", 'c', 0, G_OPTION_ARG_NONE, &compact,
+                               "Output compacted", NULL},
+               {"socket", 's', 0, G_OPTION_ARG_STRING, &control_path,
+                               "Use the following socket path", NULL},
+               {"timeout", 't', 0, G_OPTION_ARG_DOUBLE, &timeout,
+                               "Set IO timeout (1s by default)", NULL},
+               {NULL,  0,   0, G_OPTION_ARG_NONE, NULL, NULL, NULL}
+};
+
+static const char *
+rspamadm_control_help (gboolean full_help)
+{
+       const char *help_str;
+
+       if (full_help) {
+               help_str = "Manage rspamd main control interface\n\n"
+                               "Usage: rspamadm control [-c] [-j] [-u] [-s path] command\n"
+                               "Where options are:\n\n"
+                               "-c: output compacted json\n"
+                               "-j: output linted json\n"
+                               "-u: output ucl\n"
+                               "-s: use the following socket instead of " RSPAMD_DBDIR "/rspamd.sock\n"
+                               "-t: set IO timeout (1.0 seconds default)\n"
+                               "--help: shows available options and commands\n\n"
+                               "Supported commands:\n"
+                               "stat - show statistics\n"
+                               "reload - reload workers dynamic data\n";
+       }
+       else {
+               help_str = "Manage rspamd main control interface";
+       }
+
+       return help_str;
+}
+
+static void
+rspamd_control_error_handler (struct rspamd_http_connection *conn, GError *err)
+{
+       rspamd_fprintf (stderr, "Cannot make HTTP request: %e\n", err);
+}
+
+static gint
+rspamd_control_finish_handler (struct rspamd_http_connection *conn,
+               struct rspamd_http_message *msg)
+{
+       rspamd_fprintf (stdout, "Result: %V\n", msg->body);
+
+       return 0;
+}
+
+static void
+rspamadm_control (gint argc, gchar **argv)
+{
+       GOptionContext *context;
+       GError *error = NULL;
+       struct event_base *ev_base;
+       const gchar *cmd, *path = NULL;
+       struct rspamd_http_connection *conn;
+       struct rspamd_http_message *msg;
+       rspamd_inet_addr_t *addr;
+       struct timeval tv;
+       gint sock;
+
+       context = g_option_context_new (
+                       "keypair - create encryption keys");
+       g_option_context_set_summary (context,
+                       "Summary:\n  Rspamd administration utility version "
+                                       RVERSION
+                                       "\n  Release id: "
+                                       RID);
+       g_option_context_add_main_entries (context, entries, NULL);
+
+       if (!g_option_context_parse (context, &argc, &argv, &error)) {
+               rspamd_fprintf (stderr, "option parsing failed: %s\n", error->message);
+               g_error_free (error);
+               exit (1);
+       }
+
+       if (argc == 0) {
+               rspamd_fprintf (stderr, "command required\n");
+               exit (1);
+       }
+
+       cmd = argv[1];
+
+       if (g_ascii_strcasecmp (cmd, "stat") == 0) {
+               path = "/stat";
+       }
+       else if (g_ascii_strcasecmp (cmd, "reload") == 0) {
+               path = "/reload";
+       }
+       else {
+               rspamd_fprintf (stderr, "unknown command: %s\n", cmd);
+               exit (1);
+       }
+
+       if (!rspamd_parse_inet_address (&addr, control_path, 0)) {
+               rspamd_fprintf (stderr, "bad control path: %s\n", control_path);
+               exit (1);
+       }
+
+       ev_base = event_init ();
+       sock = rspamd_inet_address_connect (addr, SOCK_STREAM, TRUE);
+
+       if (sock == -1) {
+               rspamd_fprintf (stderr, "cannot connect to: %s\n", control_path);
+               rspamd_inet_address_destroy (addr);
+               exit (1);
+       }
+
+       conn = rspamd_http_connection_new (NULL, rspamd_control_error_handler,
+                       rspamd_control_finish_handler, RSPAMD_HTTP_CLIENT_SIMPLE,
+                       RSPAMD_HTTP_CLIENT, NULL);
+       msg = rspamd_http_new_message (HTTP_REQUEST);
+       msg->url = rspamd_fstring_new_init (path, strlen (path));
+       double_to_tv (timeout, &tv);
+
+       rspamd_http_connection_write_message (conn, msg, NULL, NULL, NULL, sock,
+                       &tv, ev_base);
+
+       event_base_loop (ev_base, 0);
+
+       rspamd_http_connection_unref (conn);
+       rspamd_inet_address_destroy (addr);
+       close (sock);
+}