]> source.dussan.org Git - rspamd.git/commitdiff
Add rspamadm routine.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 24 Sep 2015 16:09:35 +0000 (17:09 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 24 Sep 2015 16:09:35 +0000 (17:09 +0100)
src/CMakeLists.txt
src/rspamadm/CMakeLists.txt [new file with mode: 0644]
src/rspamadm/commands.c [new file with mode: 0644]
src/rspamadm/rspamadm.c [new file with mode: 0644]
src/rspamadm/rspamadm.h [new file with mode: 0644]

index f86c45b4057871a602b0b5f648c7a4a541da0763..3d3d887e4a8c6f423d0b1b293c4fa244604da93b 100644 (file)
@@ -70,6 +70,7 @@ ADD_SUBDIRECTORY(libserver)
 ADD_SUBDIRECTORY(libmime)
 ADD_SUBDIRECTORY(libstat)
 ADD_SUBDIRECTORY(client)
+ADD_SUBDIRECTORY(rspamadm)
                                
 SET(RSPAMDSRC  controller.c
                                fuzzy_storage.c
diff --git a/src/rspamadm/CMakeLists.txt b/src/rspamadm/CMakeLists.txt
new file mode 100644 (file)
index 0000000..ba9814f
--- /dev/null
@@ -0,0 +1,13 @@
+SET(RSPAMADMSRC rspamadm.c commands.c)
+
+ADD_EXECUTABLE(rspamadm ${RSPAMADMSRC})
+TARGET_LINK_LIBRARIES(rspamadm rspamd-server)
+TARGET_LINK_LIBRARIES(rspamadm ${RSPAMD_REQUIRED_LIBRARIES})
+TARGET_LINK_LIBRARIES(rspamadm stemmer)
+TARGET_LINK_LIBRARIES(rspamadm rspamd-actrie)
+
+IF (NOT DEBIAN_BUILD)
+    SET_TARGET_PROPERTIES(rspamadm PROPERTIES VERSION ${RSPAMD_VERSION})
+ENDIF (NOT DEBIAN_BUILD)
+
+INSTALL(TARGETS rspamadm RUNTIME DESTINATION bin)
\ No newline at end of file
diff --git a/src/rspamadm/commands.c b/src/rspamadm/commands.c
new file mode 100644 (file)
index 0000000..26f6b02
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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 "rspamadm.h"
+
+const struct rspamadm_command *commands[] = {
+       &help_command,
+       NULL
+};
+
+
+const struct rspamadm_command *
+rspamadm_search_command (const gchar *name)
+{
+       const struct rspamadm_command *ret = NULL;
+       guint i;
+
+       if (name == NULL) {
+               name = "help";
+       }
+
+       for (i = 0; i < G_N_ELEMENTS (commands); i ++) {
+               if (commands[i] != NULL) {
+                       if (strcmp (name, commands[i]->name) == 0) {
+                               ret = commands[i];
+                               break;
+                       }
+               }
+       }
+
+       return ret;
+}
\ No newline at end of file
diff --git a/src/rspamadm/rspamadm.c b/src/rspamadm/rspamadm.c
new file mode 100644 (file)
index 0000000..0a6ecc7
--- /dev/null
@@ -0,0 +1,290 @@
+/*
+ * 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 "rspamd.h"
+#include "ottery.h"
+
+static gboolean verbose = FALSE;
+static gboolean list_commands = FALSE;
+static gboolean show_help = FALSE;
+static gboolean show_version = FALSE;
+GHashTable *ucl_vars = NULL;
+
+static void rspamadm_help (gint argc, gchar **argv);
+static const char* rspamadm_help_help (gboolean full_help);
+
+struct rspamadm_command help_command = {
+       .name = "help",
+       .flags = RSPAMADM_FLAG_NOHELP,
+       .help = rspamadm_help_help,
+       .run = rspamadm_help
+};
+
+static gboolean rspamadm_parse_ucl_var (const gchar *option_name,
+               const gchar *value, gpointer data,
+               GError **error);
+
+static GOptionEntry entries[] = {
+       {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
+                       "Enable verbose logging", NULL},
+       {"list-commands", 'l', 0, G_OPTION_ARG_NONE, &list_commands,
+                       "List available commands", NULL},
+       {"var", 0, 0, G_OPTION_ARG_CALLBACK, rspamadm_parse_ucl_var,
+                       "Redefine UCL variable", NULL},
+       {"help", 'h', 0, G_OPTION_ARG_NONE, &show_help,
+                       "Show help", NULL},
+       {"version", 'h', 0, G_OPTION_ARG_NONE, &show_version,
+                       "Show version", NULL},
+       {NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL}
+};
+
+GQuark
+rspamadm_error (void)
+{
+       return g_quark_from_static_string ("rspamadm");
+}
+
+static void
+rspamadm_version (void)
+{
+       printf ("Rspamadm %s\n", RVERSION);
+       exit (EXIT_SUCCESS);
+}
+
+static void
+rspamadm_usage (GOptionContext *context)
+{
+       gchar *help_str;
+
+       help_str = g_option_context_get_help (context, TRUE, NULL);
+       printf ("%s", help_str);
+
+       exit (EXIT_SUCCESS);
+}
+
+static void
+rspamadm_commands (GOptionContext *context)
+{
+       gchar *help_str;
+       const struct rspamadm_command **cmd;
+
+       printf ("Rspamadm %s\n", RVERSION);
+       printf ("Usage: rspamadm [global_options] command [command_options]\n");
+       printf ("\nAvailable commands:\n");
+
+       cmd = commands;
+
+       while (*cmd) {
+               printf ("  %-18s %-60s\n", (*cmd)->name, (*cmd)->help (FALSE));
+               cmd ++;
+       }
+
+       exit (EXIT_SUCCESS);
+}
+
+static const char *
+rspamadm_help_help (gboolean full_help)
+{
+       const char *help_str;
+
+       if (full_help) {
+               help_str = "Shows help for a specified command\n"
+                               "Usage: rspamadm help <command>";
+       }
+       else {
+               help_str = "Shows help for a specified command";
+       }
+
+       return help_str;
+}
+
+static void
+rspamadm_help (gint argc, gchar **argv)
+{
+       const gchar *cmd_name;
+       const struct rspamadm_command *cmd;
+
+       if (argc == 0) {
+               cmd_name = "help";
+       }
+       else {
+               cmd_name = argv[1];
+       }
+
+       cmd = rspamadm_search_command (cmd_name);
+
+       if (cmd == NULL) {
+               fprintf (stderr, "Invalid command name: %s\n", cmd_name);
+               exit (EXIT_FAILURE);
+       }
+
+       printf ("%s\n", cmd->help (TRUE));
+}
+
+static gboolean
+rspamadm_parse_ucl_var (const gchar *option_name,
+               const gchar *value, gpointer data,
+               GError **error)
+{
+       gchar *k, *v, *t;
+
+       t = strchr (value, '=');
+
+       if (t != NULL) {
+               k = g_strdup (value);
+               t = k + (t - value);
+               v = g_strdup (t + 1);
+               *t = '\0';
+
+               g_hash_table_insert (ucl_vars, k, v);
+       }
+       else {
+               g_set_error (error, rspamadm_error (), EINVAL,
+                               "Bad variable format: %s", value);
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+gint
+main (gint argc, gchar **argv, gchar **env)
+{
+       GError *error = NULL;
+       GOptionContext *context;
+       GOptionGroup *og;
+       struct rspamd_config *cfg;
+       struct rspamd_main *rspamd_main;
+       GQuark process_quark;
+       gchar **nargv;
+       const gchar *cmd_name;
+       const struct rspamadm_command *cmd;
+       gint i, nargc;
+
+       ucl_vars = g_hash_table_new_full (rspamd_strcase_hash,
+               rspamd_strcase_equal, g_free, g_free);
+       ottery_init (NULL);
+       process_quark = g_quark_from_static_string ("rspamadm");
+       cfg = g_slice_alloc0 (sizeof (*cfg));
+       rspamd_main = g_slice_alloc0 (sizeof (*rspamd_main));
+       rspamd_init_libs ();
+       rspamd_init_cfg (cfg, TRUE);
+       rspamd_main->cfg = cfg;
+       rspamd_main->pid = getpid ();
+       rspamd_main->type = process_quark;
+       rspamd_main->server_pool = rspamd_mempool_new (rspamd_mempool_suggest_size (),
+                       "rspamadm");
+
+       /* Setup logger */
+       if (verbose) {
+               cfg->log_level = G_LOG_LEVEL_DEBUG;
+       }
+       else {
+               cfg->log_level = G_LOG_LEVEL_INFO;
+       }
+
+       cfg->log_type = RSPAMD_LOG_CONSOLE;
+       rspamd_set_logger (cfg, process_quark, rspamd_main);
+       (void) rspamd_log_open (rspamd_main->logger);
+       g_log_set_default_handler (rspamd_glib_log_function, rspamd_main->logger);
+       g_set_printerr_handler (rspamd_glib_printerr_function);
+
+       gperf_profiler_init (cfg, "rspamadm");
+       setproctitle ("rspamdadm");
+
+       /* Now read options and store everything till the first non-dash argument */
+       nargv = g_slice_alloc0 (sizeof (gchar *) * (argc + 1));
+       nargv[0] = g_strdup (argv[0]);
+
+       for (i = 1, nargc = 1; i < argc; i ++) {
+               if (argv[i] && argv[i][0] == '-') {
+                       /* Copy to nargv */
+                       nargv[nargc] = g_strdup (argv[i]);
+                       nargc ++;
+               }
+               else {
+                       break;
+               }
+       }
+
+       context = g_option_context_new ("command - rspamd administration utility");
+       og = g_option_group_new ("global", "global options", "global options",
+                       NULL, NULL);
+       g_option_context_set_help_enabled (context, FALSE);
+       g_option_group_add_entries (og, entries);
+       g_option_context_set_summary (context,
+                       "Summary:\n  Rspamd administration utility version "
+                                       RVERSION
+                                       "\n  Release id: "
+                                       RID);
+       g_option_context_set_main_group (context, og);
+
+       if (!g_option_context_parse (context, &nargc, &nargv, &error)) {
+               fprintf (stderr, "option parsing failed: %s\n", error->message);
+               g_error_free (error);
+               exit (1);
+       }
+
+       if (show_version) {
+               rspamadm_version ();
+       }
+       if (show_help) {
+               rspamadm_usage (context);
+       }
+       if (list_commands) {
+               rspamadm_commands (context);
+       }
+
+       cmd_name = argv[nargc];
+
+       if (cmd_name == NULL) {
+               cmd_name = "help";
+       }
+
+       cmd = rspamadm_search_command (cmd_name);
+
+       if (cmd == NULL) {
+               fprintf (stderr, "Invalid command name: %s\n", cmd_name);
+               exit (EXIT_FAILURE);
+       }
+
+       if (nargc < argc) {
+               cmd->run (argc - nargc - 1, &argv[nargc]);
+       }
+       else {
+               cmd->run (0, NULL);
+       }
+
+       rspamd_log_close (rspamd_main->logger);
+       rspamd_config_free (rspamd_main->cfg);
+       g_free (rspamd_main->cfg);
+       g_free (rspamd_main);
+
+       g_mime_shutdown ();
+
+       return 0;
+}
+
diff --git a/src/rspamadm/rspamadm.h b/src/rspamadm/rspamadm.h
new file mode 100644 (file)
index 0000000..e7a90b5
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+#ifndef RSPAMD_RSPAMDADM_H
+#define RSPAMD_RSPAMDADM_H
+
+#include "config.h"
+
+extern GHashTable *ucl_vars;
+
+GQuark rspamadm_error (void);
+
+typedef const gchar* (*rspamadm_help_func) (gboolean full_help);
+typedef void (*rspamadm_run_func) (gint argc, gchar **argv);
+
+#define RSPAMADM_FLAG_NOHELP (1 << 0)
+
+struct rspamadm_command {
+       const gchar *name;
+       guint flags;
+       rspamadm_help_func help;
+       rspamadm_run_func run;
+};
+
+extern const struct rspamadm_command *commands[];
+extern struct rspamadm_command help_command;
+
+const struct rspamadm_command *rspamadm_search_command (const gchar *name);
+
+#endif