+/*
+ * Copyright 2023 Vsevolod Stakhov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
/* Copyright (c) 2014, Vsevolod Stakhov
* All rights reserved.
*
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+#include "ucl.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/* Include C++ guard as Lua headers miss one */
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
-#include "ucl.h"
/**
* Closure structure for lua function storing inside UCL
/**
* Initialize lua UCL API
*/
-UCL_EXTERN int luaopen_ucl (lua_State *L);
+UCL_EXTERN int luaopen_ucl(lua_State *L);
/**
* Import UCL object from lua state
* @param idx index of object at the lua stack to convert to UCL
* @return new UCL object or NULL, the caller should unref object after using
*/
-UCL_EXTERN ucl_object_t* ucl_object_lua_import (lua_State *L, int idx);
+UCL_EXTERN ucl_object_t *ucl_object_lua_import(lua_State *L, int idx);
/**
* Import UCL object from lua state, escaping JSON strings
* @param idx index of object at the lua stack to convert to UCL
* @return new UCL object or NULL, the caller should unref object after using
*/
-UCL_EXTERN ucl_object_t* ucl_object_lua_import_escape (lua_State *L, int idx);
+UCL_EXTERN ucl_object_t *ucl_object_lua_import_escape(lua_State *L, int idx);
/**
* Push an object to lua
* @param obj object to push
* @param allow_array traverse over implicit arrays
*/
-UCL_EXTERN int ucl_object_push_lua (lua_State *L,
- const ucl_object_t *obj, bool allow_array);
+UCL_EXTERN int ucl_object_push_lua(lua_State *L,
+ const ucl_object_t *obj, bool allow_array);
/**
* Push an object to lua replacing all ucl.null with `false`
* @param L lua state
* @param obj object to push
* @param allow_array traverse over implicit arrays
*/
-UCL_EXTERN int ucl_object_push_lua_filter_nil (lua_State *L,
- const ucl_object_t *obj,
- bool allow_array);
+UCL_EXTERN int ucl_object_push_lua_filter_nil(lua_State *L,
+ const ucl_object_t *obj,
+ bool allow_array);
-UCL_EXTERN struct ucl_lua_funcdata* ucl_object_toclosure (const ucl_object_t *obj);
+UCL_EXTERN struct ucl_lua_funcdata *ucl_object_toclosure(const ucl_object_t *obj);
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
#endif /* LUA_UCL_H_ */
cfg->cfg_pool->tag.tagname, cfg->checksum, \
RSPAMD_LOG_FUNC, \
__VA_ARGS__)
-#define msg_err_config_forced(...) rspamd_default_log_function(G_LOG_LEVEL_CRITICAL | RSPAMD_LOG_FORCED, \
- cfg->cfg_pool->tag.tagname, cfg->checksum, \
- RSPAMD_LOG_FUNC, \
+#define msg_err_config_forced(...) rspamd_default_log_function((gint) G_LOG_LEVEL_CRITICAL | (gint) RSPAMD_LOG_FORCED, \
+ cfg->cfg_pool->tag.tagname, cfg->checksum, \
+ RSPAMD_LOG_FUNC, \
__VA_ARGS__)
#define msg_warn_config(...) rspamd_default_log_function(G_LOG_LEVEL_WARNING, \
cfg->cfg_pool->tag.tagname, cfg->checksum, \
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
+#include "lua/lua_common.h"
#include "cfg_rcl.h"
#include "rspamd.h"
#include "cfg_file_private.h"
#include "utlist.h"
#include "cfg_file.h"
-#include "lua/lua_common.h"
#include "expression.h"
#include "src/libserver/composites/composites.h"
#include "libserver/worker_util.h"
#include <string>
#include <filesystem>
#include <memory>
-#include <algorithm>
#include "contrib/ankerl/unordered_dense.h"
#include "fmt/core.h"
#include "libutil/cxx/util.hxx"
struct rspamd_rcl_sections_map;
struct rspamd_rcl_section {
- struct rspamd_rcl_sections_map *top;
+ struct rspamd_rcl_sections_map *top{};
std::string name; /**< name of section */
std::optional<std::string> key_attr;
std::optional<std::string> default_key;
- rspamd_rcl_handler_t handler; /**< handler of section attributes */
- enum ucl_type type; /**< type of attribute */
- bool required; /**< whether this param is required */
- bool strict_type; /**< whether we need strict type */
- mutable bool processed; /**< whether this section was processed */
+ rspamd_rcl_handler_t handler{}; /**< handler of section attributes */
+ enum ucl_type type; /**< type of attribute */
+ bool required{}; /**< whether this param is required */
+ bool strict_type{}; /**< whether we need strict type */
+ mutable bool processed{}; /**< whether this section was processed */
ankerl::unordered_dense::map<std::string, std::shared_ptr<struct rspamd_rcl_section>> subsections;
ankerl::unordered_dense::map<std::string, struct rspamd_rcl_default_handler_data> default_parser; /**< generic parsing fields */
- rspamd_rcl_section_fin_t fin; /** called at the end of section parsing */
- gpointer fin_ud;
- ucl_object_t *doc_ref; /**< reference to the section's documentation */
+ rspamd_rcl_section_fin_t fin{}; /** called at the end of section parsing */
+ gpointer fin_ud{};
+ ucl_object_t *doc_ref{}; /**< reference to the section's documentation */
};
struct rspamd_worker_param_parser {
};
struct rspamd_worker_cfg_parser {
- ankerl::unordered_dense::map<std::pair<std::string, gpointer>, rspamd_worker_param_parser> parsers; /**< parsers hash */
- gint type; /**< workers quark */
- gboolean (*def_obj_parser)(ucl_object_t *obj, gpointer ud); /**<
- default object parser */
+ struct pair_hash {
+ using is_avalanching = void;
+ template<class T1, class T2>
+ std::size_t operator()(const std::pair<T1, T2> &pair) const
+ {
+ return ankerl::unordered_dense::hash<T1>()(pair.first) ^ ankerl::unordered_dense::hash<T2>()(pair.second);
+ }
+ };
+ ankerl::unordered_dense::map<std::pair<std::string, gpointer>,
+ rspamd_worker_param_parser, pair_hash>
+ parsers; /**< parsers hash */
+ gint type; /**< workers quark */
+ gboolean (*def_obj_parser)(ucl_object_t *obj, gpointer ud); /**< default object parser */
gpointer def_ud;
};
*/
#include "config.h"
+#include "lua/lua_common.h"
+#include "lua/lua_thread_pool.h"
+
#include "cfg_file.h"
#include "rspamd.h"
#include "cfg_file_private.h"
-#include "scan_result.h"
-#include "lua/lua_common.h"
-#include "lua/lua_thread_pool.h"
+
#include "maps/map.h"
#include "maps/map_helpers.h"
#include "maps/map_private.h"
-/*-
- * Copyright 2016 Vsevolod Stakhov
+/*
+ * Copyright 2023 Vsevolod Stakhov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
return TRUE;
}
-static struct rspamd_rcl_section *control_parser = NULL;
+static struct rspamd_rcl_sections_map *control_parser = NULL;
-static void
-rspamd_protocol_control_parser_init(void)
+RSPAMD_CONSTRUCTOR(rspamd_protocol_control_parser_ctor)
{
- struct rspamd_rcl_section *sub;
-
- if (control_parser == NULL) {
- sub = rspamd_rcl_add_section(&control_parser,
- "*",
- NULL,
- NULL,
- UCL_OBJECT,
- FALSE,
- TRUE);
- /* Default handlers */
- rspamd_rcl_add_default_handler(sub,
- "ip",
- rspamd_rcl_parse_struct_addr,
- G_STRUCT_OFFSET(struct rspamd_task, from_addr),
- 0,
- NULL);
- rspamd_rcl_add_default_handler(sub,
- "from",
- rspamd_rcl_parse_struct_mime_addr,
- G_STRUCT_OFFSET(struct rspamd_task, from_envelope),
- 0,
- NULL);
- rspamd_rcl_add_default_handler(sub,
- "rcpt",
- rspamd_rcl_parse_struct_mime_addr,
- G_STRUCT_OFFSET(struct rspamd_task, rcpt_envelope),
- 0,
- NULL);
- rspamd_rcl_add_default_handler(sub,
- "helo",
- rspamd_rcl_parse_struct_string,
- G_STRUCT_OFFSET(struct rspamd_task, helo),
- 0,
- NULL);
- rspamd_rcl_add_default_handler(sub,
- "user",
- rspamd_rcl_parse_struct_string,
- G_STRUCT_OFFSET(struct rspamd_task, auth_user),
- 0,
- NULL);
- rspamd_rcl_add_default_handler(sub,
- "pass_all",
- rspamd_protocol_parse_task_flags,
- G_STRUCT_OFFSET(struct rspamd_task, flags),
- 0,
- NULL);
- rspamd_rcl_add_default_handler(sub,
- "json",
- rspamd_protocol_parse_task_flags,
- G_STRUCT_OFFSET(struct rspamd_task, flags),
- 0,
- NULL);
- }
+
+ struct rspamd_rcl_section *sub = rspamd_rcl_add_section(&control_parser, NULL,
+ "*",
+ NULL,
+ NULL,
+ UCL_OBJECT,
+ FALSE,
+ TRUE);
+ /* Default handlers */
+ rspamd_rcl_add_default_handler(sub,
+ "ip",
+ rspamd_rcl_parse_struct_addr,
+ G_STRUCT_OFFSET(struct rspamd_task, from_addr),
+ 0,
+ NULL);
+ rspamd_rcl_add_default_handler(sub,
+ "from",
+ rspamd_rcl_parse_struct_mime_addr,
+ G_STRUCT_OFFSET(struct rspamd_task, from_envelope),
+ 0,
+ NULL);
+ rspamd_rcl_add_default_handler(sub,
+ "rcpt",
+ rspamd_rcl_parse_struct_mime_addr,
+ G_STRUCT_OFFSET(struct rspamd_task, rcpt_envelope),
+ 0,
+ NULL);
+ rspamd_rcl_add_default_handler(sub,
+ "helo",
+ rspamd_rcl_parse_struct_string,
+ G_STRUCT_OFFSET(struct rspamd_task, helo),
+ 0,
+ NULL);
+ rspamd_rcl_add_default_handler(sub,
+ "user",
+ rspamd_rcl_parse_struct_string,
+ G_STRUCT_OFFSET(struct rspamd_task, auth_user),
+ 0,
+ NULL);
+ rspamd_rcl_add_default_handler(sub,
+ "pass_all",
+ rspamd_protocol_parse_task_flags,
+ G_STRUCT_OFFSET(struct rspamd_task, flags),
+ 0,
+ NULL);
+ rspamd_rcl_add_default_handler(sub,
+ "json",
+ rspamd_protocol_parse_task_flags,
+ G_STRUCT_OFFSET(struct rspamd_task, flags),
+ 0,
+ NULL);
+}
+
+RSPAMD_DESTRUCTOR(rspamd_protocol_control_parser_dtor)
+{
+ rspamd_rcl_sections_free(control_parser);
}
gboolean
{
GError *err = NULL;
- rspamd_protocol_control_parser_init();
-
if (!rspamd_rcl_parse(control_parser, task->cfg, task, task->task_pool,
control, &err)) {
msg_warn_protocol("cannot parse control block: %e", err);
{
LUA_TRACE_POINT;
struct rspamd_config *cfg = NULL, **pcfg;
- struct rspamd_rcl_section *top;
+ struct rspamd_rcl_sections_map *top;
GError *err = NULL;
ucl_object_t *obj;
const char *str_options = NULL;
rspamd_lua_setclass(L, "rspamd{config}", -1);
*pcfg = cfg;
}
+
+ rspamd_rcl_sections_free(top);
}
return 1;
rspamd_rcl_config_init(cfg, NULL);
lua_pushboolean(cfg->lua_state, true);
lua_setglobal(cfg->lua_state, "confighelp");
- rspamd_rcl_add_lua_plugins_path(cfg, plugins_path, FALSE, NULL, NULL);
+ rspamd_rcl_add_lua_plugins_path(cfg->rcl_top_section, cfg, plugins_path, FALSE, NULL);
/* Init modules to get documentation strings */
i = 0;