]> source.dussan.org Git - rspamd.git/commitdiff
* Add new system of getting and setting config parameters from perl code
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Thu, 15 Jan 2009 14:32:15 +0000 (17:32 +0300)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Thu, 15 Jan 2009 14:32:15 +0000 (17:32 +0300)
perl/rspamd.pm
perl/rspamd.xs
perl/typemap
src/cfg_file.h
src/cfg_utils.c

index 99e0e490846562bc8baedd0c97dfc67c1034cb4e..d3b2fac0e9c97aa9de32fc7126881d9e8c6b748c 100644 (file)
@@ -21,7 +21,7 @@ rspamd - Perl interface to the rspamd API
 
 =head1 SYNOPSIS
 
-  use rpspamd;
+  use rspamd;
 
 =head1 DESCRIPTION
 
index c96401033c3cb2f063b2f546f1162805d1281145..7020e34635a0fd322540d6a4927eea51146fbe88 100644 (file)
 #include "../src/perl.h"
 #include "../src/mem_pool.h"
 
-#define perl_set_session(r)                                                                                                    \
+#define perl_set_session(r)                                                                                                        \
        r = INT2PTR(struct worker_task *, SvIV((SV *) SvRV(ST(0))))
 
+#define perl_set_config(r)                                                      \
+    r = INT2PTR(struct config_file *, SvIV((SV *) SvRV(ST(0))))
+
 #define perl_set_targ(p, len)                                                                                                  \
        SvUPGRADE(TARG, SVt_PV);                                                                                                        \
        SvPOK_on(TARG);                                                                                                                         \
        sv_setpvn(TARG, (char *) p, len)
 
-MODULE = rspamd        PACKAGE = rspamd
+MODULE = rspamd   PACKAGE = rspamd_task PREFIX = rspamd_task_
 PROTOTYPES: DISABLE
 
 void
-get_header (r, header)
+rspamd_task_get_header (r, header)
        CODE:
        dXSTARG;
        struct worker_task *r;
@@ -50,12 +53,12 @@ get_header (r, header)
                XSRETURN_UNDEF;
        }
        else {
-               ngx_http_perl_set_targ (s, strlen (s));
+               perl_set_targ (s, strlen (s));
                ST(0) = TARG;
        }
 
 void
-get_part_num (r)
+rspamd_task_get_part_num (r)
        CODE:
        dXSTARG;
        struct worker_task *r;
@@ -68,7 +71,7 @@ get_part_num (r)
 
 
 HV *
-get_part (r, num)
+rspamd_task_get_part (r, num)
        CODE:
        struct worker_task *r;
        SV *num;
@@ -103,7 +106,7 @@ get_part (r, num)
        RETVAL
 
 void
-ip (r)
+rspamd_task_ip (r)
        CODE:
        dXSTARG;
        struct worker_task *r;
@@ -116,7 +119,7 @@ ip (r)
        ST(0) = TARG;
 
 void
-from (r)
+rspamd_task_from (r)
        CODE:
        dXSTARG;
        struct worker_task *r;
@@ -130,7 +133,7 @@ from (r)
        ST(0) = TARG;
 
 void
-save_point (r)
+rspamd_task_save_point (r)
     CODE:
        struct worker_task *r;
 
@@ -138,7 +141,7 @@ save_point (r)
     r->save.saved = 1;
 
 void
-recall_filter (r)
+rspamd_task_recall_filter (r)
     CODE:
     struct worker_task *r;
 
@@ -146,50 +149,28 @@ recall_filter (r)
     process_filters (r);
 
 void
-insert_result (r, metric, symbol, flag)
+rspamd_task_insert_result (r, metric, symbol, flag)
        CODE:
        struct worker_task *r;
        char *metric, *symbol;
        int flag;
-       STRLEN metriclen, symbollen;
 
        perl_set_session (r);
-       metric = (char *) SvPV (ST(1), metriclen);
-       symbol = (char *) SvPV (ST(2), symbollen);
+       metric = (char *) SvPV_nolen (ST(1));
+       symbol = (char *) SvPV_nolen (ST(2));
        flag = (int) SvIV (ST(3));
 
        insert_result (r, metric, symbol, flag);
 
-void
-get_module_param (r, modulename, paramname)
-       CODE:
-       struct worker_task *r;
-       char *module, *param, *value;
-       STRLEN modulelen, paramlen;
-
-       dXSTARG;
-       perl_set_session (r);
-       module = (char *) SvPV (ST(1), modulelen);
-       param = (char *) SvPV (ST(2), paramlen);
-
-       value = get_module_opt (r->worker->srv->cfg, module, param);
-       if (value == NULL) {
-               XSRETURN_UNDEF;
-       }
 
-       sv_upgrade(TARG, SVt_PV);
-       sv_setpv(TARG, value);
-
-       ST(0) = TARG;
 
 void
-read_memcached_key (r, key, datalen, callback)
+rspamd_task_read_memcached_key (r, key, datalen, callback)
     CODE:
     struct worker_task *r;
     char *key;
     unsigned int datalen;
     SV *callback;
-    STRLEN keylen;
     struct _param {
         SV *callback;
         struct worker_task *task;
@@ -198,7 +179,7 @@ read_memcached_key (r, key, datalen, callback)
     memcached_param_t param;
 
     perl_set_session (r);
-    key = (char *) SvPV (ST(1), keylen);
+    key = (char *) SvPV_nolen (ST(1));
     datalen = (unsigned int) SvIV (ST(2));
     callback = SvRV(ST(3));
 
@@ -232,12 +213,12 @@ read_memcached_key (r, key, datalen, callback)
     XSRETURN_EMPTY;
 
 void
-write_memcached_key (r, key, data, expire, callback)
+rspamd_task_write_memcached_key (r, key, data, expire, callback)
     CODE:
     struct worker_task *r;
     char *key, *data;
     SV *callback;
-    STRLEN keylen, datalen;
+    STRLEN datalen;
     int expire;
     struct _param {
         SV *callback;
@@ -247,7 +228,7 @@ write_memcached_key (r, key, data, expire, callback)
     memcached_param_t param;
 
     perl_set_session (r);
-    key = (char *) SvPV (ST(1), keylen);
+    key = (char *) SvPV_nolen (ST(1));
     data = (char *) SvPV (ST(2), datalen);
     expire = (int) SvIV (ST(3));
     callback = SvRV(ST(4));
@@ -280,12 +261,11 @@ write_memcached_key (r, key, data, expire, callback)
     XSRETURN_EMPTY;
 
 void
-delete_memcached_key (r, key, callback)
+rspamd_task_delete_memcached_key (r, key, callback)
     CODE:
     struct worker_task *r;
     char *key;
     SV *callback;
-    STRLEN keylen;
     struct _param {
         SV *callback;
         struct worker_task *task;
@@ -294,8 +274,8 @@ delete_memcached_key (r, key, callback)
     memcached_param_t param;
 
     perl_set_session (r);
-    key = (char *) SvPV (ST(1), keylen);
-    callback = SvRV(ST(2));
+    key = (char *) SvPV_nolen (ST(1));
+    callback = SvRV (ST(2));
 
     /* Copy old ctx to new one */
     ctx = memory_pool_alloc (r->task_pool, sizeof (memcached_ctx_t));
@@ -324,3 +304,185 @@ delete_memcached_key (r, key, callback)
     r->save.saved = 1;
     XSRETURN_EMPTY;
 
+void
+rspamd_task_get_conf (r)
+CODE:
+    struct worker_task *r;
+       dXSTARG;
+
+    perl_set_session (r);
+
+       sv_setref_pv (TARG, "rspamd_config", r->cfg);
+       ST(0) = TARG;
+
+
+MODULE = rspamd   PACKAGE = rspamd_config PREFIX = rspamd_config_
+PROTOTYPES: DISABLE
+
+void
+rspamd_config_get_scalar (r, param)
+CODE:
+    struct config_file *r;
+    struct config_scalar *sc;
+    char *param;
+    int val;
+       dXSTARG;
+
+    perl_set_config (r);
+    param = (char *) SvPV_nolen (ST(1));
+
+    sc = g_hash_table_lookup (r->cfg_params, param);
+    if (sc == NULL) {
+        XSRETURN_UNDEF;
+    }
+    else {
+        switch (sc->type) {
+            case SCALAR_TYPE_SIZE:
+                val = (int)(*(size_t *)sc->pointer);
+                sv_upgrade (TARG, SVt_IV);
+                   sv_setiv (TARG, val);
+                break;
+            case SCALAR_TYPE_INT:
+            case SCALAR_TYPE_UINT:
+                val = *(int *)sc->pointer;
+                sv_upgrade (TARG, SVt_IV);
+                   sv_setiv (TARG, val);
+                break;
+            case SCALAR_TYPE_STR:
+                sv_upgrade (TARG, SVt_PV);
+                SvPOK_on(TARG);
+                   sv_setpv (TARG, (char *)sc->pointer);
+                break;
+        }
+    }
+       ST(0) = TARG;
+
+void
+rspamd_config_set_scalar (r, param, value)
+CODE:
+    struct config_file *r;
+    struct config_scalar *sc;
+    char *param, *charval;
+    int intval;
+       dXSTARG;
+
+    perl_set_config (r);
+    param = (char *) SvPV_nolen (ST(1));
+
+    sc = g_hash_table_lookup (r->cfg_params, param);
+    if (sc == NULL) {
+        XSRETURN_UNDEF;
+    }
+    else {
+        switch (sc->type) {
+            case SCALAR_TYPE_SIZE:
+                intval = (int)SvIV (ST(2));
+                *((size_t *)sc->pointer) = intval;
+                sv_upgrade (TARG, SVt_IV);
+                   sv_setiv (TARG, intval);
+                break;
+            case SCALAR_TYPE_INT:
+            case SCALAR_TYPE_UINT:
+                intval = (int)SvIV (ST(2));
+                *((int *)sc->pointer) = intval;
+                sv_upgrade (TARG, SVt_IV);
+                   sv_setiv (TARG, intval);
+                break;
+            case SCALAR_TYPE_STR:
+                charval = (char *)SvPVX (ST(2));
+                *((char **)sc->pointer) = charval;
+                sv_upgrade (TARG, SVt_PV);
+                   sv_setpv (TARG, charval);
+                break;
+        }
+    }
+       ST(0) = TARG;
+
+HV *
+rspamd_config_set_metric (r, name)
+CODE:
+    struct config_file *r;
+    struct metric *val;
+    char *name;
+    
+    perl_set_config (r);
+    name = (char *) SvPV_nolen (ST(1));
+
+    val = g_hash_table_lookup (r->metrics, name);
+    if (val == NULL) {
+        XSRETURN_UNDEF;
+    }
+    else {
+       RETVAL = newHV();
+
+           (void)hv_store_ent (RETVAL, 
+                               newSVpv ("name", sizeof ("name") - 1), 
+                               newSVpv (val->name, strlen (val->name)), 0);
+           (void)hv_store_ent (RETVAL, 
+                               newSVpv ("func_name", sizeof ("func_name") - 1), 
+                               newSVpv (val->func_name, strlen (val->func_name)), 0);
+           (void)hv_store_ent (RETVAL, 
+                               newSVpv ("required_score", sizeof ("required_score") - 1), 
+                               newSVnv (val->required_score), 0);
+        sv_2mortal((SV*)RETVAL);
+    }
+OUTPUT:
+    RETVAL
+
+HV *
+rspamd_config_set_statfile (r, name)
+CODE:
+    struct config_file *r;
+    struct statfile *val;
+    char *name;
+    
+    perl_set_config (r);
+    name = (char *) SvPV_nolen (ST(1));
+
+    val = g_hash_table_lookup (r->statfiles, name);
+    if (val == NULL) {
+        XSRETURN_UNDEF;
+    }
+    else {
+       RETVAL = newHV();
+
+           (void)hv_store_ent (RETVAL, 
+                               newSVpv ("alias", sizeof ("alias") - 1), 
+                               newSVpv (val->alias, strlen (val->alias)), 0);
+           (void)hv_store_ent (RETVAL, 
+                               newSVpv ("pattern", sizeof ("pattern") - 1), 
+                               newSVpv (val->pattern, strlen (val->pattern)), 0);
+           (void)hv_store_ent (RETVAL, 
+                               newSVpv ("metric", sizeof ("metric") - 1), 
+                               newSVpv (val->metric, strlen (val->metric)), 0);
+           (void)hv_store_ent (RETVAL, 
+                               newSVpv ("weight", sizeof ("weight") - 1), 
+                               newSVnv (val->weight), 0);
+           (void)hv_store_ent (RETVAL, 
+                               newSVpv ("size", sizeof ("size") - 1), 
+                               newSViv (val->size), 0);
+        sv_2mortal((SV*)RETVAL);
+    }
+OUTPUT:
+    RETVAL
+
+void
+rspamd_task_get_module_param (r, modulename, paramname)
+       CODE:
+       struct config_file *r;
+       char *module, *param, *value;
+
+       dXSTARG;
+       perl_set_config (r);
+       module = (char *) SvPV_nolen (ST(1));
+       param = (char *) SvPV_nolen (ST(2));
+
+       value = get_module_opt (r, module, param);
+       if (value == NULL) {
+               XSRETURN_UNDEF;
+       }
+
+       sv_upgrade(TARG, SVt_PV);
+       sv_setpv(TARG, value);
+
+       ST(0) = TARG;
index 17a1b16eb76b4f85884a2b99d2748b9e454a5183..cdf52b17c72fac6b516d75f56428fbf0d1bee535 100644 (file)
@@ -1,3 +1,4 @@
 TYPEMAP
 
-rspamd   T_PTROBJ
+rspamd_task   T_PTROBJ
+rspamd_config   T_PTROBJ
index 4a2fb824d141072813b508eecef76d17efe457ef..bb934134cc1d8a7a5ade2d88b6f7ac79b833a9b8 100644 (file)
@@ -106,6 +106,16 @@ struct statfile {
        struct classifier *classifier;
 };
 
+struct config_scalar {
+    void *pointer;
+    enum {
+        SCALAR_TYPE_INT,
+        SCALAR_TYPE_UINT,
+        SCALAR_TYPE_STR,
+        SCALAR_TYPE_SIZE,
+    } type;
+};
+
 struct config_file {
        memory_pool_t *cfg_pool;
        char *cfg_name;
@@ -151,13 +161,22 @@ struct config_file {
        char *mime_filters_str;
        char *message_filters_str;
        char *url_filters_str;
+    /* Options for all modules */
        GHashTable* modules_opts;
+    /* Variables, defined in config */
        GHashTable* variables;
+    /* Metrics */
        GHashTable* metrics;
+    /* Factors */
        GHashTable* factors;
+    /* C modules, enabled in config */
        GHashTable* c_modules;
+    /* Composite symbols */
        GHashTable* composite_symbols;
+    /* Statfiles, described in config */
        GHashTable* statfiles;
+    /* All cfg file scalars to access fields in structure */
+    GHashTable* cfg_params;
 };
 
 int add_memcached_server (struct config_file *cf, char *str);
index fd3f4503f6a2081be2f840a608b0ec57cd48db43..2231a2d9615a22fdcb367e31b938ab54925d3a7a 100644 (file)
@@ -177,6 +177,7 @@ init_defaults (struct config_file *cfg)
        cfg->c_modules = g_hash_table_new (g_str_hash, g_str_equal);
        cfg->composite_symbols = g_hash_table_new (g_str_hash, g_str_equal);
        cfg->statfiles = g_hash_table_new (g_str_hash, g_str_equal);
+       cfg->cfg_params = g_hash_table_new (g_str_hash, g_str_equal);
 
        LIST_INIT (&cfg->perl_modules);
 }
@@ -198,6 +199,8 @@ free_config (struct config_file *cfg)
        g_hash_table_unref (cfg->composite_symbols);
        g_hash_table_remove_all (cfg->statfiles);
        g_hash_table_unref (cfg->statfiles);
+       g_hash_table_remove_all (cfg->cfg_params);
+       g_hash_table_unref (cfg->cfg_params);
        memory_pool_delete (cfg->cfg_pool);
 }
 
@@ -436,8 +439,51 @@ parse_filters_str (struct config_file *cfg, const char *str, enum script_type ty
        g_strfreev (strvec);
 }
 
+/*
+ * Place pointers to cfg_file structure to hash cfg_params
+ */
+static void
+fill_cfg_params (struct config_file *cfg)
+{
+    struct config_scalar *scalars;
+
+    scalars = memory_pool_alloc (cfg->cfg_pool, 10 * sizeof (struct config_scalar));
+
+    scalars[0].type = SCALAR_TYPE_STR;
+    scalars[0].pointer = &cfg->cfg_name;
+    g_hash_table_insert (cfg->cfg_params, "cfg_name", &scalars[0]);
+    scalars[1].type = SCALAR_TYPE_STR;
+    scalars[1].pointer = &cfg->pid_file;
+    g_hash_table_insert (cfg->cfg_params, "pid_file", &scalars[1]);
+    scalars[2].type = SCALAR_TYPE_STR;
+    scalars[2].pointer = &cfg->temp_dir;
+    g_hash_table_insert (cfg->cfg_params, "temp_dir", &scalars[2]);
+    scalars[3].type = SCALAR_TYPE_STR;
+    scalars[3].pointer = &cfg->bind_host;
+    g_hash_table_insert (cfg->cfg_params, "bind_host", &scalars[3]);
+    scalars[4].type = SCALAR_TYPE_STR;
+    scalars[4].pointer = &cfg->control_host;
+    g_hash_table_insert (cfg->cfg_params, "control_host", &scalars[4]);
+    scalars[5].type = SCALAR_TYPE_INT;
+    scalars[5].pointer = &cfg->controller_enabled;
+    g_hash_table_insert (cfg->cfg_params, "controller_enabled", &scalars[5]);
+    scalars[6].type = SCALAR_TYPE_STR;
+    scalars[6].pointer = &cfg->control_password;
+    g_hash_table_insert (cfg->cfg_params, "control_password", &scalars[6]);
+    scalars[7].type = SCALAR_TYPE_INT;
+    scalars[7].pointer = &cfg->no_fork;
+    g_hash_table_insert (cfg->cfg_params, "no_fork", &scalars[7]);
+    scalars[8].type = SCALAR_TYPE_UINT;
+    scalars[8].pointer = &cfg->workers_number;
+    g_hash_table_insert (cfg->cfg_params, "workers_number", &scalars[8]);
+    scalars[9].type = SCALAR_TYPE_SIZE;
+    scalars[9].pointer = &cfg->max_statfile_size;
+    g_hash_table_insert (cfg->cfg_params, "max_statfile_size", &scalars[9]);
+
+}
+
 /* 
- * Substitute all variables in strings
+ * Perform post load actions
  */
 void
 post_load_config (struct config_file *cfg)
@@ -448,6 +494,7 @@ post_load_config (struct config_file *cfg)
        parse_filters_str (cfg, cfg->mime_filters_str, SCRIPT_MIME);
        parse_filters_str (cfg, cfg->message_filters_str, SCRIPT_MESSAGE);
        parse_filters_str (cfg, cfg->url_filters_str, SCRIPT_URL);
+    fill_cfg_params (cfg);
 }
 
 /*