XML_SECTION_CLASSIFIER,
XML_SECTION_STATFILE,
XML_SECTION_MODULE,
+ XML_SECTION_MODULE_META,
XML_SECTION_MODULES,
XML_SECTION_VIEW
};
NULL
}
},
+ { XML_SECTION_MODULE, {
+ {
+ "name",
+ xml_handle_string,
+ G_STRUCT_OFFSET (struct module_meta_opt, name),
+ NULL
+ },
+ NULL_ATTR
+ },
+ {
+ handle_module_meta,
+ 0,
+ NULL
+ }
+ },
{ XML_SECTION_MODULE, {
NULL_ATTR
},
return "read param";
case XML_READ_MODULE:
return "read module section";
+ case XML_READ_MODULE_META:
+ return "read module meta section";
case XML_READ_OPTIONS:
return "read options section";
case XML_READ_MODULES:
return TRUE;
}
+gboolean
+handle_module_meta (struct config_file *cfg, struct rspamd_xml_userdata *ctx, const gchar *tag, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset)
+{
+ gchar *val;
+ struct module_opt *cur;
+ struct module_meta_opt *meta;
+ gboolean is_lua = FALSE;
+ const gchar *name;
+
+ if (g_ascii_strcasecmp (tag, "option") == 0 || g_ascii_strcasecmp (tag, "param") == 0) {
+ if ((name = g_hash_table_lookup (attrs, "name")) == NULL) {
+ msg_err ("worker param tag must have \"name\" attribute");
+ return FALSE;
+ }
+ }
+ else {
+ name = memory_pool_strdup (cfg->cfg_pool, tag);
+ }
+
+ meta = ctx->section_pointer;
+ cur = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct module_opt));
+ /* Check for options */
+ if (attrs != NULL) {
+ if ((val = g_hash_table_lookup (attrs, "lua")) != NULL && g_ascii_strcasecmp (val, "yes") == 0) {
+ is_lua = TRUE;
+ }
+ if ((val = g_hash_table_lookup (attrs, "description")) != NULL) {
+ cur->description = memory_pool_strdup (cfg->cfg_pool, val);
+ }
+ if ((val = g_hash_table_lookup (attrs, "group")) != NULL) {
+ cur->group = memory_pool_strdup (cfg->cfg_pool, val);
+ }
+ }
+ /*
+ * XXX: in fact we cannot check for lua modules and need to do it in post-config procedure
+ * so just insert any options provided and try to handle them in further process
+ */
+
+ /* Insert option */
+ cur->param = (char *)name;
+ cur->value = data;
+ cur->is_lua = is_lua;
+ meta->options = g_list_prepend (meta->options, cur);
+
+ return TRUE;
+}
+
static void
set_lua_globals (struct config_file *cfg, lua_State *L)
{
if (g_ascii_strcasecmp (element_name, "module") == 0) {
/* Read module data */
if (extract_attr ("name", attribute_names, attribute_values, &res)) {
- ud->parent_pointer = memory_pool_strdup (ud->cfg->cfg_pool, res);
+ ud->parent_pointer[0] = memory_pool_strdup (ud->cfg->cfg_pool, res);
/* Empty list */
ud->section_pointer = NULL;
ud->state = XML_READ_MODULE;
ud->state = XML_READ_STATFILE;
/* Now section pointer is statfile and parent pointer is classifier */
- ud->parent_pointer = ud->section_pointer;
+ ud->parent_pointer[0] = ud->section_pointer;
ud->section_pointer = check_statfile_conf (ud->cfg, NULL);
}
else {
/* Do nothing */
return;
case XML_READ_MODULE:
+ if (g_ascii_strcasecmp (element_name, "meta") == 0) {
+ ud->parent_pointer[1] = ud->section_pointer;
+ ud->state = XML_READ_MODULE_META;
+ ud->section_pointer = memory_pool_alloc0 (ud->cfg->cfg_pool, sizeof (struct module_meta_opt));
+ }
+ else {
+ rspamd_strlcpy (ud->section_name, element_name, sizeof (ud->section_name));
+ /* Save attributes */
+ ud->cur_attrs = process_attrs (ud->cfg, attribute_names, attribute_values);
+ }
+ break;
+ case XML_READ_MODULE_META:
case XML_READ_METRIC:
case XML_READ_MODULES:
case XML_READ_STATFILE:
}
switch (ud->state) {
+ case XML_READ_MODULE_META:
+ CHECK_TAG ("meta", FALSE);
+ if (res) {
+ if (ud->section_pointer != NULL) {
+ struct module_meta_opt *meta = ud->section_pointer;
+ if (meta->name == NULL) {
+ msg_err ("module %s has unnamed meta option, skip it", ud->parent_pointer[0]);
+ }
+ else {
+ g_hash_table_insert (ud->cfg->modules_metas, ud->parent_pointer[0], meta);
+ }
+ if (meta->options != NULL) {
+ memory_pool_add_destructor (ud->cfg->cfg_pool, (pool_destruct_func)g_list_free, meta->options);
+ }
+ }
+ ud->section_pointer = ud->parent_pointer[1];
+ ud->parent_pointer[1] = NULL;
+ ud->state = XML_READ_MODULE;
+ }
+ break;
case XML_READ_MODULE:
CHECK_TAG ("module", FALSE);
if (res) {
if (ud->section_pointer != NULL) {
- g_hash_table_insert (ud->cfg->modules_opts, ud->parent_pointer, ud->section_pointer);
- ud->parent_pointer = NULL;
+ g_hash_table_insert (ud->cfg->modules_opts, ud->parent_pointer[0], ud->section_pointer);
+ memory_pool_add_destructor (ud->cfg->cfg_pool, (pool_destruct_func)g_list_free, ud->section_pointer);
+ ud->parent_pointer[0] = NULL;
ud->section_pointer = NULL;
}
}
case XML_READ_STATFILE:
CHECK_TAG ("statfile", FALSE);
if (res) {
- ccf = ud->parent_pointer;
+ ccf = ud->parent_pointer[0];
st = ud->section_pointer;
/* Check statfile and insert it into classifier */
if (st->path == NULL || st->size == 0 || st->symbol == NULL) {
}
}
ud->section_pointer = ccf;
- ud->parent_pointer = NULL;
+ ud->parent_pointer[0] = NULL;
ud->state = XML_READ_CLASSIFIER;
}
break;
ud->state = XML_ERROR;
}
break;
+ case XML_READ_MODULE_META:
+ if (!call_param_handler (ud, ud->section_name, val, ud->section_pointer, XML_SECTION_MODULE_META)) {
+ *error = g_error_new (xml_error_quark (), XML_EXTRA_ELEMENT, "cannot parse tag '%s' data: %s", ud->section_name, val);
+ ud->state = XML_ERROR;
+ }
+ break;
case XML_READ_MODULES:
if (!call_param_handler (ud, ud->section_name, val, cfg, XML_SECTION_MODULES)) {
*error = g_error_new (xml_error_quark (), XML_EXTRA_ELEMENT, "cannot parse tag '%s' data: %s", ud->section_name, val);
#define XML_UNMATCHED_TAG 4
#define XML_INVALID_ATTR 5
+#define MAX_INHERIT 5
+
enum xml_read_state {
XML_READ_START,
XML_READ_PARAM,
XML_READ_MODULE,
+ XML_READ_MODULE_META,
XML_READ_MODULES,
XML_READ_CLASSIFIER,
XML_READ_STATFILE,
struct config_file *cfg; /*< configuration object */
gchar section_name[MAX_NAME]; /*< current section */
gpointer section_pointer; /*< pointer to object related with section */
- gpointer parent_pointer; /*< parent's section object */
+ gpointer parent_pointer[MAX_INHERIT]; /*< parent's section object */
GHashTable *cur_attrs; /*< attributes of current tag */
GQueue *if_stack; /*< stack of if elements */
};
/* Handle common module option */
gboolean handle_module_opt (struct config_file *cfg, struct rspamd_xml_userdata *ctx, const gchar *tag, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset);
+gboolean handle_module_meta (struct config_file *cfg, struct rspamd_xml_userdata *ctx, const gchar *tag, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset);
/* Handle loging params */
gboolean handle_log_type (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset);