]> source.dussan.org Git - rspamd.git/commitdiff
Add support of path variables.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 13 Nov 2013 17:59:29 +0000 (17:59 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 13 Nov 2013 17:59:29 +0000 (17:59 +0000)
Support expanding of path variables in rspamd:
- $CONFDIR: configuration directory
- $LOCALSTATESDIR: local states directory
- $INSTALLPREFIX: installation prefix
- $VERSION: rspamd version

src/cfg_file.h
src/cfg_rcl.c
src/cfg_rcl.h
src/cfg_utils.c

index 9dec61bc3c7418f061abc7fa76d1fadb9648b9c3..b7deb1ca698567f2bf4b67025d7a723a5cf2b46e 100644 (file)
@@ -551,6 +551,15 @@ gboolean check_classifier_statfiles (struct classifier_config *cf);
  */
 struct classifier_config* find_classifier_conf (struct config_file *cfg, const gchar *name);
 
+/*
+ * Expand path that may contain configuration variables:
+ * $CONFDIR - configuration directory
+ * $LOCALSTATESDIR - local states directory
+ * $INSTALLPREFIX - installation prefix
+ * $VERSION - rspamd version
+ */
+const gchar* rspamd_expand_path (memory_pool_t *pool, const gchar *path);
+
 #endif /* ifdef CFG_FILE_H */
 /* 
  * vi:ts=4 
index 3f419ceb8bc3963eb47b7c5023a09c75f941223c..6fc92ed19fbeab75b50a6c8ffc0d755ab2b1a702 100644 (file)
@@ -563,7 +563,7 @@ static gboolean
 rspamd_rcl_lua_handler (struct config_file *cfg, ucl_object_t *obj,
                gpointer ud, struct rspamd_rcl_section *section, GError **err)
 {
-       const gchar *lua_src = ucl_object_tostring (obj);
+       const gchar *lua_src = rspamd_expand_path (cfg->cfg_pool, ucl_object_tostring (obj));
        gchar *cur_dir, *lua_dir, *lua_file, *tmp1, *tmp2;
        lua_State *L = cfg->lua_state;
 
@@ -687,14 +687,14 @@ rspamd_rcl_modules_handler (struct config_file *cfg, ucl_object_t *obj,
 
                LL_FOREACH (val, cur) {
                        if (ucl_object_tostring_safe (cur, &data)) {
-                               if (!rspamd_rcl_add_module_path (cfg, data, err)) {
+                               if (!rspamd_rcl_add_module_path (cfg, rspamd_expand_path (cfg->cfg_pool, data), err)) {
                                        return FALSE;
                                }
                        }
                }
        }
        else if (ucl_object_tostring_safe (obj, &data)) {
-               if (!rspamd_rcl_add_module_path (cfg, data, err)) {
+               if (!rspamd_rcl_add_module_path (cfg, rspamd_expand_path (cfg->cfg_pool, data), err)) {
                        return FALSE;
                }
        }
@@ -946,7 +946,7 @@ rspamd_rcl_config_init (void)
        rspamd_rcl_add_default_handler (sub, "statfile_pool_size", rspamd_rcl_parse_struct_integer,
                        G_STRUCT_OFFSET (struct config_file, max_statfile_size), RSPAMD_CL_FLAG_INT_SIZE);
        rspamd_rcl_add_default_handler (sub, "cache_file", rspamd_rcl_parse_struct_string,
-                       G_STRUCT_OFFSET (struct config_file, cache_filename), 0);
+                       G_STRUCT_OFFSET (struct config_file, cache_filename), RSPAMD_CL_FLAG_STRING_PATH);
        rspamd_rcl_add_default_handler (sub, "dns_nameserver", rspamd_rcl_parse_struct_string_list,
                        G_STRUCT_OFFSET (struct config_file, nameservers), 0);
        rspamd_rcl_add_default_handler (sub, "dns_timeout", rspamd_rcl_parse_struct_time,
@@ -960,9 +960,9 @@ rspamd_rcl_config_init (void)
        rspamd_rcl_add_default_handler (sub, "check_attachements", rspamd_rcl_parse_struct_boolean,
                        G_STRUCT_OFFSET (struct config_file, check_text_attachements), 0);
        rspamd_rcl_add_default_handler (sub, "tempdir", rspamd_rcl_parse_struct_string,
-                       G_STRUCT_OFFSET (struct config_file, temp_dir), 0);
+                       G_STRUCT_OFFSET (struct config_file, temp_dir), RSPAMD_CL_FLAG_STRING_PATH);
        rspamd_rcl_add_default_handler (sub, "pidfile", rspamd_rcl_parse_struct_string,
-                       G_STRUCT_OFFSET (struct config_file, pid_file), 0);
+                       G_STRUCT_OFFSET (struct config_file, pid_file), RSPAMD_CL_FLAG_STRING_PATH);
        rspamd_rcl_add_default_handler (sub, "filters", rspamd_rcl_parse_struct_string,
                        G_STRUCT_OFFSET (struct config_file, filters_str), 0);
        rspamd_rcl_add_default_handler (sub, "sync_interval", rspamd_rcl_parse_struct_time,
@@ -976,9 +976,9 @@ rspamd_rcl_config_init (void)
        rspamd_rcl_add_default_handler (sub, "dynamic_conf", rspamd_rcl_parse_struct_string,
                        G_STRUCT_OFFSET (struct config_file, dynamic_conf), 0);
        rspamd_rcl_add_default_handler (sub, "rrd", rspamd_rcl_parse_struct_string,
-                       G_STRUCT_OFFSET (struct config_file, rrd_file), 0);
+                       G_STRUCT_OFFSET (struct config_file, rrd_file), RSPAMD_CL_FLAG_STRING_PATH);
        rspamd_rcl_add_default_handler (sub, "history_file", rspamd_rcl_parse_struct_string,
-                       G_STRUCT_OFFSET (struct config_file, history_file), 0);
+                       G_STRUCT_OFFSET (struct config_file, history_file), RSPAMD_CL_FLAG_STRING_PATH);
        rspamd_rcl_add_default_handler (sub, "use_mlock", rspamd_rcl_parse_struct_boolean,
                        G_STRUCT_OFFSET (struct config_file, mlock_statfile_pool), 0);
 
@@ -1022,7 +1022,7 @@ rspamd_rcl_config_init (void)
        rspamd_rcl_add_default_handler (ssub, "symbol", rspamd_rcl_parse_struct_string,
                        G_STRUCT_OFFSET (struct statfile, symbol), 0);
        rspamd_rcl_add_default_handler (ssub, "path", rspamd_rcl_parse_struct_string,
-                       G_STRUCT_OFFSET (struct statfile, path), 0);
+                       G_STRUCT_OFFSET (struct statfile, path), RSPAMD_CL_FLAG_STRING_PATH);
        rspamd_rcl_add_default_handler (ssub, "label", rspamd_rcl_parse_struct_string,
                                G_STRUCT_OFFSET (struct statfile, label), 0);
        rspamd_rcl_add_default_handler (ssub, "size", rspamd_rcl_parse_struct_integer,
@@ -1171,6 +1171,10 @@ rspamd_rcl_parse_struct_string (struct config_file *cfg, ucl_object_t *obj,
                return FALSE;
        }
 
+       if (pd->flags & RSPAMD_CL_FLAG_STRING_PATH) {
+               *target = (gchar *)rspamd_expand_path (cfg->cfg_pool, *target);
+       }
+
        return TRUE;
 }
 
index 6949c48aa14d418b26c3bc23109c9578138b8ae3..272272ab40b75925e21295b40a64758e576ae35d 100644 (file)
@@ -50,7 +50,8 @@ struct rspamd_rcl_struct_parser {
                RSPAMD_CL_FLAG_INT_16 = 0x1 << 5,
                RSPAMD_CL_FLAG_INT_32 = 0x1 << 6,
                RSPAMD_CL_FLAG_INT_64 = 0x1 << 7,
-               RSPAMD_CL_FLAG_INT_SIZE = 0x1 << 8
+               RSPAMD_CL_FLAG_INT_SIZE = 0x1 << 8,
+               RSPAMD_CL_FLAG_STRING_PATH = 0x1 << 9
        } flags;
 };
 
index dd6b00dcd92e3c148292b6ff98b15fea05b866b2..6a9477e00c1ad342800407cbab4eb8a12efb56cf 100644 (file)
@@ -1150,6 +1150,139 @@ check_classifier_statfiles (struct classifier_config *cf)
        return res;
 }
 
+/*
+ * Variables:
+ * $CONFDIR - configuration directory
+ * $LOCALSTATESDIR - local states directory
+ * $INSTALLPREFIX - installation prefix
+ * $VERSION - rspamd version
+ */
+
+#define RSPAMD_CONFDIR_MACRO "CONFDIR"
+#define RSPAMD_LOCALSTATESDIR_MACRO "LOCALSTATESDIR"
+#define RSPAMD_INSTALLPREFIX_MACRO "INSTALLPREFIX"
+#define RSPAMD_VERSION_MACRO "VERSION"
+
+static const gchar *
+rspamd_check_path_variable (const gchar *in, gsize *len)
+{
+       switch (*in) {
+       case 'C':
+               if (strncmp (in, RSPAMD_CONFDIR_MACRO, sizeof (RSPAMD_CONFDIR_MACRO) - 1) == 0) {
+                       *len += sizeof (ETC_PREFIX) - 1;
+                       in += sizeof (RSPAMD_CONFDIR_MACRO) - 1;
+               }
+               break;
+       case 'L':
+               if (strncmp (in, RSPAMD_LOCALSTATESDIR_MACRO, sizeof (RSPAMD_LOCALSTATESDIR_MACRO) - 1) == 0) {
+                       *len += sizeof (LOCALSTATES_PREFIX) - 1;
+                       in += sizeof (RSPAMD_LOCALSTATESDIR_MACRO) - 1;
+               }
+               break;
+       case 'I':
+               if (strncmp (in, RSPAMD_INSTALLPREFIX_MACRO, sizeof (RSPAMD_INSTALLPREFIX_MACRO) - 1) == 0) {
+                       *len += sizeof (CMAKE_PREFIX) - 1;
+                       in += sizeof (RSPAMD_INSTALLPREFIX_MACRO) - 1;
+               }
+               break;
+       case 'V':
+               if (strncmp (in, RSPAMD_VERSION_MACRO, sizeof (RSPAMD_VERSION_MACRO) - 1) == 0) {
+                       *len += sizeof (RVERSION) - 1;
+                       in += sizeof (RSPAMD_VERSION_MACRO) - 1;
+               }
+               break;
+       }
+
+       return in;
+}
+
+static const gchar *
+rspamd_expand_path_variable (const gchar *in, gchar **dest)
+{
+       gchar *d = *dest;
+       const gchar *v = in + 1;
+
+       *d = *v;
+       in ++;
+
+       switch (*v) {
+       case 'C':
+               if (strncmp (v, RSPAMD_CONFDIR_MACRO, sizeof (RSPAMD_CONFDIR_MACRO) - 1) == 0) {
+                       memcpy (d, ETC_PREFIX, sizeof (ETC_PREFIX) - 1);
+                       d += sizeof (ETC_PREFIX) - 1;
+                       in += sizeof (RSPAMD_CONFDIR_MACRO) - 1;
+               }
+               break;
+       case 'L':
+               if (strncmp (v, RSPAMD_LOCALSTATESDIR_MACRO, sizeof (RSPAMD_LOCALSTATESDIR_MACRO) - 1) == 0) {
+                       memcpy (d, LOCALSTATES_PREFIX, sizeof (LOCALSTATES_PREFIX) - 1);
+                       d += sizeof (LOCALSTATES_PREFIX) - 1;
+                       in += sizeof (RSPAMD_LOCALSTATESDIR_MACRO) - 1;
+               }
+               break;
+       case 'I':
+               if (strncmp (v, RSPAMD_INSTALLPREFIX_MACRO, sizeof (RSPAMD_INSTALLPREFIX_MACRO) - 1) == 0) {
+                       memcpy (d, CMAKE_PREFIX, sizeof (CMAKE_PREFIX) - 1);
+                       d += sizeof (CMAKE_PREFIX) - 1;
+                       in += sizeof (RSPAMD_INSTALLPREFIX_MACRO) - 1;
+               }
+               break;
+       case 'V':
+               if (strncmp (v, RSPAMD_VERSION_MACRO, sizeof (RSPAMD_VERSION_MACRO) - 1) == 0) {
+                       memcpy (d, RVERSION, sizeof (RVERSION) - 1);
+                       d += sizeof (RVERSION) - 1;
+                       in += sizeof (RSPAMD_VERSION_MACRO) - 1;
+               }
+               break;
+       }
+
+       *dest = d;
+       return in;
+}
+
+const gchar*
+rspamd_expand_path (memory_pool_t *pool, const gchar *path)
+{
+       const gchar *p = path;
+       gchar *dest, *d;
+       gsize len = 0, orig_len = 0;
+
+       while (*p != '\0') {
+               if (*p == '$') {
+                       len ++;
+                       p = rspamd_check_path_variable (p + 1, &len);
+               }
+               else {
+                       len ++;
+               }
+               orig_len ++;
+               p ++;
+       }
+
+       if (len == orig_len) {
+               return path;
+       }
+
+       dest = memory_pool_alloc (pool, len + 1);
+       p = path;
+       d = dest;
+
+       while (*p != '\0') {
+               if (*p == '$') {
+                       p = rspamd_expand_path_variable (p, &d);
+               }
+               else {
+                       *d++ = *p++;
+               }
+       }
+
+       *d = '\0';
+
+       msg_debug ("expanded %s to %s", path, dest);
+
+       return dest;
+}
+
 /*
  * vi:ts=4
  */