From d0681272065a04de5e8249b782ac7f9efa938555 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Thu, 15 Jan 2009 17:32:15 +0300 Subject: [PATCH] * Add new system of getting and setting config parameters from perl code --- perl/rspamd.pm | 2 +- perl/rspamd.xs | 250 +++++++++++++++++++++++++++++++++++++++--------- perl/typemap | 3 +- src/cfg_file.h | 19 ++++ src/cfg_utils.c | 49 +++++++++- 5 files changed, 276 insertions(+), 47 deletions(-) diff --git a/perl/rspamd.pm b/perl/rspamd.pm index 99e0e4908..d3b2fac0e 100644 --- a/perl/rspamd.pm +++ b/perl/rspamd.pm @@ -21,7 +21,7 @@ rspamd - Perl interface to the rspamd API =head1 SYNOPSIS - use rpspamd; + use rspamd; =head1 DESCRIPTION diff --git a/perl/rspamd.xs b/perl/rspamd.xs index c96401033..7020e3463 100644 --- a/perl/rspamd.xs +++ b/perl/rspamd.xs @@ -17,19 +17,22 @@ #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; diff --git a/perl/typemap b/perl/typemap index 17a1b16eb..cdf52b17c 100644 --- a/perl/typemap +++ b/perl/typemap @@ -1,3 +1,4 @@ TYPEMAP -rspamd T_PTROBJ +rspamd_task T_PTROBJ +rspamd_config T_PTROBJ diff --git a/src/cfg_file.h b/src/cfg_file.h index 4a2fb824d..bb934134c 100644 --- a/src/cfg_file.h +++ b/src/cfg_file.h @@ -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); diff --git a/src/cfg_utils.c b/src/cfg_utils.c index fd3f4503f..2231a2d96 100644 --- a/src/cfg_utils.c +++ b/src/cfg_utils.c @@ -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); } /* -- 2.39.5