You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

configtest.c 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*-
  2. * Copyright 2016 Vsevolod Stakhov
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "config.h"
  17. #include "rspamadm.h"
  18. #include "cfg_file.h"
  19. #include "cfg_rcl.h"
  20. #include "rspamd.h"
  21. #include "lua/lua_common.h"
  22. static gboolean quiet = FALSE;
  23. static gchar *config = NULL;
  24. static gboolean strict = FALSE;
  25. static gboolean skip_template = FALSE;
  26. extern struct rspamd_main *rspamd_main;
  27. /* Defined in modules.c */
  28. extern module_t *modules[];
  29. extern worker_t *workers[];
  30. static void rspamadm_configtest (gint argc, gchar **argv,
  31. const struct rspamadm_command *cmd);
  32. static const char *rspamadm_configtest_help (gboolean full_help,
  33. const struct rspamadm_command *cmd);
  34. struct rspamadm_command configtest_command = {
  35. .name = "configtest",
  36. .flags = 0,
  37. .help = rspamadm_configtest_help,
  38. .run = rspamadm_configtest,
  39. .lua_subrs = NULL,
  40. };
  41. static GOptionEntry entries[] = {
  42. {"quiet", 'q', 0, G_OPTION_ARG_NONE, &quiet,
  43. "Suppress output", NULL},
  44. {"config", 'c', 0, G_OPTION_ARG_STRING, &config,
  45. "Config file to test", NULL},
  46. {"strict", 's', 0, G_OPTION_ARG_NONE, &strict,
  47. "Stop on any error in config", NULL},
  48. {"skip-template", 'T', 0, G_OPTION_ARG_NONE, &skip_template,
  49. "Do not apply Jinja templates", NULL},
  50. {NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL}
  51. };
  52. static const char *
  53. rspamadm_configtest_help (gboolean full_help, const struct rspamadm_command *cmd)
  54. {
  55. const char *help_str;
  56. if (full_help) {
  57. help_str = "Perform configuration file test\n\n"
  58. "Usage: rspamadm configtest [-q -c <config_name>]\n"
  59. "Where options are:\n\n"
  60. "-q: quiet output\n"
  61. "-c: config file to test\n"
  62. "--help: shows available options and commands";
  63. }
  64. else {
  65. help_str = "Perform configuration file test";
  66. }
  67. return help_str;
  68. }
  69. static void
  70. config_logger (rspamd_mempool_t *pool, gpointer ud)
  71. {
  72. }
  73. static void
  74. rspamadm_configtest (gint argc, gchar **argv, const struct rspamadm_command *cmd)
  75. {
  76. GOptionContext *context;
  77. GError *error = NULL;
  78. const gchar *confdir;
  79. struct rspamd_config *cfg = rspamd_main->cfg;
  80. gboolean ret = TRUE;
  81. worker_t **pworker;
  82. const guint64 *log_cnt;
  83. context = g_option_context_new (
  84. "configtest - perform configuration file test");
  85. g_option_context_set_summary (context,
  86. "Summary:\n Rspamd administration utility version "
  87. RVERSION
  88. "\n Release id: "
  89. RID);
  90. g_option_context_add_main_entries (context, entries, NULL);
  91. if (!g_option_context_parse (context, &argc, &argv, &error)) {
  92. fprintf (stderr, "option parsing failed: %s\n", error->message);
  93. g_error_free (error);
  94. g_option_context_free (context);
  95. exit (EXIT_FAILURE);
  96. }
  97. g_option_context_free (context);
  98. if (config == NULL) {
  99. static gchar fbuf[PATH_MAX];
  100. if ((confdir = g_hash_table_lookup (ucl_vars, "CONFDIR")) == NULL) {
  101. confdir = RSPAMD_CONFDIR;
  102. }
  103. rspamd_snprintf (fbuf, sizeof (fbuf), "%s%c%s",
  104. confdir, G_DIR_SEPARATOR,
  105. "rspamd.conf");
  106. config = fbuf;
  107. }
  108. pworker = &workers[0];
  109. while (*pworker) {
  110. /* Init string quarks */
  111. (void) g_quark_from_static_string ((*pworker)->name);
  112. pworker++;
  113. }
  114. cfg->compiled_modules = modules;
  115. cfg->compiled_workers = workers;
  116. cfg->cfg_name = config;
  117. if (!rspamd_config_read (cfg, cfg->cfg_name, config_logger, rspamd_main,
  118. ucl_vars, skip_template, lua_env)) {
  119. ret = FALSE;
  120. }
  121. else {
  122. /* Do post-load actions */
  123. rspamd_lua_post_load_config (cfg);
  124. if (!rspamd_init_filters (rspamd_main->cfg, false, strict)) {
  125. ret = FALSE;
  126. }
  127. if (ret) {
  128. ret = rspamd_config_post_load (cfg, RSPAMD_CONFIG_INIT_SYMCACHE);
  129. }
  130. if (ret && !rspamd_symcache_validate (cfg->cache,
  131. cfg,
  132. FALSE)) {
  133. ret = FALSE;
  134. }
  135. }
  136. if (strict && ret) {
  137. log_cnt = rspamd_log_counters (rspamd_main->logger);
  138. if (log_cnt && log_cnt[0] > 0) {
  139. if (!quiet) {
  140. rspamd_printf ("%L errors found\n", log_cnt[0]);
  141. }
  142. ret = FALSE;
  143. }
  144. }
  145. if (!quiet) {
  146. rspamd_printf ("syntax %s\n", ret ? "OK" : "BAD");
  147. }
  148. if (!ret) {
  149. exit (EXIT_FAILURE);
  150. }
  151. }