From d2e2f5ec1a54c6e7c2348d204b3fc3a09849003d Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Thu, 8 Apr 2010 21:22:13 +0400 Subject: [PATCH] * Handle and dump factors correctly * Many fixes to processes spawning * Implement rereading of config * Fix stupid yacc with its stupid global vars --- src/cfg_file.l | 17 +--- src/cfg_file.y | 254 +++++++++++++++++++++++------------------------ src/cfg_xml.c | 44 +++++++-- src/main.c | 260 ++++++++++++++++++++++++++----------------------- src/main.h | 2 +- 5 files changed, 307 insertions(+), 270 deletions(-) diff --git a/src/cfg_file.l b/src/cfg_file.l index 83c35290c..542488e2f 100644 --- a/src/cfg_file.l +++ b/src/cfg_file.l @@ -1,6 +1,5 @@ %x incl %x module_lex_state -%x lua_lex_state %x worker_lex_state %x classifier_lex_state @@ -10,11 +9,6 @@ #include "config.h" #include "cfg_file.h" #include "cfg_yacc.h" -#ifdef WITH_LUA -extern void add_luabuf (const char *line); -#else -#define add_luabuf(x) yyerror ("lua support diabled") -#endif #define ECHO do {} while(0) @@ -23,7 +17,7 @@ YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; int line_stack[MAX_INCLUDE_DEPTH]; int include_stack_ptr = 0; int nested_depth = 0; -extern struct config_file *cfg; +extern struct config_file *yacc_cfg; %} @@ -34,7 +28,6 @@ extern struct config_file *cfg; [ \t]*#.* /* ignore comments */; .include BEGIN(incl); .module BEGIN(module_lex_state); -.lua BEGIN(lua_lex_state); worker BEGIN(worker_lex_state); return WORKER; composites BEGIN(module_lex_state);return COMPOSITES; tempdir return TEMPDIR; @@ -133,7 +126,7 @@ yes|YES|no|NO|[yY]|[nN] yylval.flag=parse_flag(yytext); return FLAG; /* Handle XML case */ int len = strlen (yytext); if (strcmp (yytext + len - 4, ".xml") == 0) { - if (!read_xml_config (cfg, yytext)) { + if (!read_xml_config (yacc_cfg, yytext)) { yyerror ("invalid xml detected"); } BEGIN(INITIAL); @@ -233,12 +226,6 @@ yes|YES|no|NO|[yY]|[nN] yylval.flag=parse_flag(yytext); return FLAG; [a-zA-Z0-9_%-]+ yylval.string=strdup(yytext); return PARAM; \".+[^\\]\" yylval.string=strdup(yytext + 1); yylval.string[strlen(yylval.string) - 1] = '\0'; unescape_quotes(yylval.string); return QUOTEDSTRING; -\n /* ignore EOL */; -[ \t]+ /* ignore whitespace */; -[ \t]*#.* /* ignore comments */; -^.endlua$ BEGIN(INITIAL); -.* add_luabuf(yytext); return LUACODE; - %% /* * vi:ts=4 diff --git a/src/cfg_file.y b/src/cfg_file.y index 07853bfa5..13902c6ae 100644 --- a/src/cfg_file.y +++ b/src/cfg_file.y @@ -17,7 +17,7 @@ #endif #define YYDEBUG 1 -extern struct config_file *cfg; +extern struct config_file *yacc_cfg; extern int yylineno; extern char *yytext; @@ -116,16 +116,16 @@ tempdir : yyerror ("yyparse: \"%s\" is not a directory", $3); YYERROR; } - cfg->temp_dir = memory_pool_strdup (cfg->cfg_pool, $3); + yacc_cfg->temp_dir = memory_pool_strdup (yacc_cfg->cfg_pool, $3); free ($3); } ; pidfile : PIDFILE EQSIGN QUOTEDSTRING { - if (cfg->pid_file == NULL) { + if (yacc_cfg->pid_file == NULL) { /* Allow override this value from command line */ - cfg->pid_file = $3; + yacc_cfg->pid_file = $3; } } ; @@ -133,7 +133,7 @@ pidfile : filters: FILTERS EQSIGN QUOTEDSTRING { - cfg->filters_str = memory_pool_strdup (cfg->cfg_pool, $3); + yacc_cfg->filters_str = memory_pool_strdup (yacc_cfg->cfg_pool, $3); free ($3); } ; @@ -167,7 +167,7 @@ memcached_server: memcached_params: memcached_hosts { - if (!add_memcached_server (cfg, $1)) { + if (!add_memcached_server (yacc_cfg, $1)) { yyerror ("yyparse: add_memcached_server"); YYERROR; } @@ -182,32 +182,32 @@ memcached_hosts: ; memcached_error_time: ERROR_TIME EQSIGN NUMBER { - cfg->memcached_error_time = $3; + yacc_cfg->memcached_error_time = $3; } ; memcached_dead_time: DEAD_TIME EQSIGN NUMBER { - cfg->memcached_dead_time = $3; + yacc_cfg->memcached_dead_time = $3; } ; memcached_maxerrors: MAXERRORS EQSIGN NUMBER { - cfg->memcached_maxerrors = $3; + yacc_cfg->memcached_maxerrors = $3; } ; memcached_connect_timeout: CONNECT_TIMEOUT EQSIGN SECONDS { - cfg->memcached_connect_timeout = $3; + yacc_cfg->memcached_connect_timeout = $3; } ; memcached_protocol: PROTOCOL EQSIGN STRING { if (strncasecmp ($3, "udp", sizeof ("udp") - 1) == 0) { - cfg->memcached_protocol = UDP_TEXT; + yacc_cfg->memcached_protocol = UDP_TEXT; } else if (strncasecmp ($3, "tcp", sizeof ("tcp") - 1) == 0) { - cfg->memcached_protocol = TCP_TEXT; + yacc_cfg->memcached_protocol = TCP_TEXT; } else { yyerror ("yyparse: cannot recognize protocol: %s", $3); @@ -219,7 +219,7 @@ memcached_protocol: /* Workers section */ worker: WORKER OBRACE workerbody EBRACE { - cfg->workers = g_list_prepend (cfg->workers, cur_worker); + yacc_cfg->workers = g_list_prepend (yacc_cfg->workers, cur_worker); cur_worker = NULL; } ; @@ -240,9 +240,9 @@ workercmd: bindsock: BINDSOCK EQSIGN bind_cred { - cur_worker = check_worker_conf (cfg, cur_worker); + cur_worker = check_worker_conf (yacc_cfg, cur_worker); - if (!parse_bind_line (cfg, cur_worker, $3)) { + if (!parse_bind_line (yacc_cfg, cur_worker, $3)) { yyerror ("yyparse: parse_bind_line"); YYERROR; } @@ -270,7 +270,7 @@ bind_cred: workertype: TYPE EQSIGN QUOTEDSTRING { - cur_worker = check_worker_conf (cfg, cur_worker); + cur_worker = check_worker_conf (yacc_cfg, cur_worker); if (g_ascii_strcasecmp ($3, "normal") == 0) { cur_worker->type = TYPE_WORKER; cur_worker->has_socket = TRUE; @@ -296,7 +296,7 @@ workertype: workercount: COUNT EQSIGN NUMBER { - cur_worker = check_worker_conf (cfg, cur_worker); + cur_worker = check_worker_conf (yacc_cfg, cur_worker); if ($3 > 0) { cur_worker->count = $3; @@ -310,21 +310,21 @@ workercount: workerlimitfiles: MAXFILES EQSIGN NUMBER { - cur_worker = check_worker_conf (cfg, cur_worker); + cur_worker = check_worker_conf (yacc_cfg, cur_worker); cur_worker->rlimit_nofile = $3; } ; workerlimitcore: MAXCORE EQSIGN NUMBER { - cur_worker = check_worker_conf (cfg, cur_worker); + cur_worker = check_worker_conf (yacc_cfg, cur_worker); cur_worker->rlimit_maxcore = $3; } ; workerparam: STRING EQSIGN QUOTEDSTRING { - cur_worker = check_worker_conf (cfg, cur_worker); + cur_worker = check_worker_conf (yacc_cfg, cur_worker); g_hash_table_insert (cur_worker->params, $1, $3); } @@ -338,8 +338,8 @@ metric: if (cur_metric->classifier == NULL) { cur_metric->classifier = get_classifier ("winnow"); } - g_hash_table_insert (cfg->metrics, cur_metric->name, cur_metric); - cfg->metrics_list = g_list_prepend (cfg->metrics_list, cur_metric); + g_hash_table_insert (yacc_cfg->metrics, cur_metric->name, cur_metric); + yacc_cfg->metrics_list = g_list_prepend (yacc_cfg->metrics_list, cur_metric); cur_metric = NULL; } ; @@ -359,18 +359,18 @@ metriccmd: metricname: NAME EQSIGN QUOTEDSTRING { if (cur_metric == NULL) { - cur_metric = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct metric)); + cur_metric = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct metric)); } - cur_metric->name = memory_pool_strdup (cfg->cfg_pool, $3); + cur_metric->name = memory_pool_strdup (yacc_cfg->cfg_pool, $3); } ; metricfunction: FUNCTION EQSIGN QUOTEDSTRING { if (cur_metric == NULL) { - cur_metric = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct metric)); + cur_metric = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct metric)); } - cur_metric->func_name = memory_pool_strdup (cfg->cfg_pool, $3); + cur_metric->func_name = memory_pool_strdup (yacc_cfg->cfg_pool, $3); #ifdef WITH_LUA cur_metric->func = lua_consolidation_func; #elif !defined(WITHOUT_PERL) @@ -384,13 +384,13 @@ metricfunction: metricscore: REQUIRED_SCORE EQSIGN NUMBER { if (cur_metric == NULL) { - cur_metric = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct metric)); + cur_metric = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct metric)); } cur_metric->required_score = $3; } | REQUIRED_SCORE EQSIGN FRACT { if (cur_metric == NULL) { - cur_metric = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct metric)); + cur_metric = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct metric)); } cur_metric->required_score = $3; } @@ -399,13 +399,13 @@ metricscore: metricrjscore: REJECT_SCORE EQSIGN NUMBER { if (cur_metric == NULL) { - cur_metric = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct metric)); + cur_metric = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct metric)); } cur_metric->reject_score = $3; } | REJECT_SCORE EQSIGN FRACT { if (cur_metric == NULL) { - cur_metric = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct metric)); + cur_metric = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct metric)); } cur_metric->reject_score = $3; } @@ -414,9 +414,9 @@ metricrjscore: metriccache: CACHE_FILE EQSIGN QUOTEDSTRING { if (cur_metric == NULL) { - cur_metric = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct metric)); + cur_metric = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct metric)); } - cur_metric->cache_filename = memory_pool_strdup (cfg->cfg_pool, $3); + cur_metric->cache_filename = memory_pool_strdup (yacc_cfg->cfg_pool, $3); } ; @@ -431,20 +431,20 @@ factorsbody: factorparam: QUOTEDSTRING EQSIGN FRACT { - double *tmp = memory_pool_alloc (cfg->cfg_pool, sizeof (double)); + double *tmp = memory_pool_alloc (yacc_cfg->cfg_pool, sizeof (double)); *tmp = $3; - g_hash_table_insert (cfg->factors, $1, tmp); + g_hash_table_insert (yacc_cfg->factors, $1, tmp); } | QUOTEDSTRING EQSIGN NUMBER { - double *tmp = memory_pool_alloc (cfg->cfg_pool, sizeof (double)); + double *tmp = memory_pool_alloc (yacc_cfg->cfg_pool, sizeof (double)); *tmp = $3; - g_hash_table_insert (cfg->factors, $1, tmp); + g_hash_table_insert (yacc_cfg->factors, $1, tmp); } | GROW_FACTOR EQSIGN FRACT { - cfg->grow_factor = $3; + yacc_cfg->grow_factor = $3; } | GROW_FACTOR EQSIGN NUMBER { - cfg->grow_factor = $3; + yacc_cfg->grow_factor = $3; } modules: @@ -477,13 +477,13 @@ modulescmd: if (glob(pattern, GLOB_DOOFFS, NULL, &globbuf) == 0) { for (i = 0; i < globbuf.gl_pathc; i ++) { - cur = memory_pool_alloc (cfg->cfg_pool, sizeof (struct script_module)); + cur = memory_pool_alloc (yacc_cfg->cfg_pool, sizeof (struct script_module)); if (cur == NULL) { yyerror ("yyparse: g_malloc: %s", strerror(errno)); YYERROR; } - cur->path = memory_pool_strdup (cfg->cfg_pool, globbuf.gl_pathv[i]); - cfg->script_modules = g_list_prepend (cfg->script_modules, cur); + cur->path = memory_pool_strdup (yacc_cfg->cfg_pool, globbuf.gl_pathv[i]); + yacc_cfg->script_modules = g_list_prepend (yacc_cfg->script_modules, cur); } globfree (&globbuf); } @@ -507,16 +507,16 @@ compositesbody: compositescmd: PARAM EQSIGN QUOTEDSTRING { struct expression *expr; - if ((expr = parse_expression (cfg->cfg_pool, $3)) == NULL) { + if ((expr = parse_expression (yacc_cfg->cfg_pool, $3)) == NULL) { yyerror ("yyparse: cannot parse composite expression: %s", $3); YYERROR; } - g_hash_table_insert (cfg->composite_symbols, $1, expr); + g_hash_table_insert (yacc_cfg->composite_symbols, $1, expr); } ; module_opt: MODULE_OPT OBRACE moduleoptbody EBRACE { - g_hash_table_insert (cfg->modules_opts, $1, cur_module_opt); + g_hash_table_insert (yacc_cfg->modules_opts, $1, cur_module_opt); cur_module_opt = NULL; } ; @@ -529,19 +529,19 @@ moduleoptbody: optcmd: PARAM EQSIGN QUOTEDSTRING { struct module_opt *mopt; - mopt = memory_pool_alloc (cfg->cfg_pool, sizeof (struct module_opt)); + mopt = memory_pool_alloc (yacc_cfg->cfg_pool, sizeof (struct module_opt)); mopt->param = $1; mopt->value = $3; cur_module_opt = g_list_prepend (cur_module_opt, mopt); } | VARIABLE EQSIGN QUOTEDSTRING { - g_hash_table_insert (cfg->variables, $1, $3); + g_hash_table_insert (yacc_cfg->variables, $1, $3); } ; variable: VARIABLE EQSIGN QUOTEDSTRING { - g_hash_table_insert (cfg->variables, $1, $3); + g_hash_table_insert (yacc_cfg->variables, $1, $3); } ; @@ -566,71 +566,71 @@ loggingcmd: loggingtype: LOG_TYPE EQSIGN LOG_TYPE_CONSOLE { - cfg->log_type = RSPAMD_LOG_CONSOLE; + yacc_cfg->log_type = RSPAMD_LOG_CONSOLE; } | LOG_TYPE EQSIGN LOG_TYPE_SYSLOG { - cfg->log_type = RSPAMD_LOG_SYSLOG; + yacc_cfg->log_type = RSPAMD_LOG_SYSLOG; } | LOG_TYPE EQSIGN LOG_TYPE_FILE { - cfg->log_type = RSPAMD_LOG_FILE; + yacc_cfg->log_type = RSPAMD_LOG_FILE; } ; logginglevel: LOG_LEVEL EQSIGN LOG_LEVEL_DEBUG { - cfg->log_level = G_LOG_LEVEL_DEBUG; + yacc_cfg->log_level = G_LOG_LEVEL_DEBUG; } | LOG_LEVEL EQSIGN LOG_LEVEL_INFO { - cfg->log_level = G_LOG_LEVEL_INFO | G_LOG_LEVEL_MESSAGE; + yacc_cfg->log_level = G_LOG_LEVEL_INFO | G_LOG_LEVEL_MESSAGE; } | LOG_LEVEL EQSIGN LOG_LEVEL_WARNING { - cfg->log_level = G_LOG_LEVEL_WARNING; + yacc_cfg->log_level = G_LOG_LEVEL_WARNING; } | LOG_LEVEL EQSIGN LOG_LEVEL_ERROR { - cfg->log_level = G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL; + yacc_cfg->log_level = G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL; } ; loggingfacility: LOG_FACILITY EQSIGN QUOTEDSTRING { if (strncasecmp ($3, "LOG_AUTH", sizeof ("LOG_AUTH") - 1) == 0) { - cfg->log_facility = LOG_AUTH; + yacc_cfg->log_facility = LOG_AUTH; } else if (strncasecmp ($3, "LOG_CRON", sizeof ("LOG_CRON") - 1) == 0) { - cfg->log_facility = LOG_CRON; + yacc_cfg->log_facility = LOG_CRON; } else if (strncasecmp ($3, "LOG_DAEMON", sizeof ("LOG_DAEMON") - 1) == 0) { - cfg->log_facility = LOG_DAEMON; + yacc_cfg->log_facility = LOG_DAEMON; } else if (strncasecmp ($3, "LOG_MAIL", sizeof ("LOG_MAIL") - 1) == 0) { - cfg->log_facility = LOG_MAIL; + yacc_cfg->log_facility = LOG_MAIL; } else if (strncasecmp ($3, "LOG_USER", sizeof ("LOG_USER") - 1) == 0) { - cfg->log_facility = LOG_USER; + yacc_cfg->log_facility = LOG_USER; } else if (strncasecmp ($3, "LOG_LOCAL0", sizeof ("LOG_LOCAL0") - 1) == 0) { - cfg->log_facility = LOG_LOCAL0; + yacc_cfg->log_facility = LOG_LOCAL0; } else if (strncasecmp ($3, "LOG_LOCAL1", sizeof ("LOG_LOCAL1") - 1) == 0) { - cfg->log_facility = LOG_LOCAL1; + yacc_cfg->log_facility = LOG_LOCAL1; } else if (strncasecmp ($3, "LOG_LOCAL2", sizeof ("LOG_LOCAL2") - 1) == 0) { - cfg->log_facility = LOG_LOCAL2; + yacc_cfg->log_facility = LOG_LOCAL2; } else if (strncasecmp ($3, "LOG_LOCAL3", sizeof ("LOG_LOCAL3") - 1) == 0) { - cfg->log_facility = LOG_LOCAL3; + yacc_cfg->log_facility = LOG_LOCAL3; } else if (strncasecmp ($3, "LOG_LOCAL4", sizeof ("LOG_LOCAL4") - 1) == 0) { - cfg->log_facility = LOG_LOCAL4; + yacc_cfg->log_facility = LOG_LOCAL4; } else if (strncasecmp ($3, "LOG_LOCAL5", sizeof ("LOG_LOCAL5") - 1) == 0) { - cfg->log_facility = LOG_LOCAL5; + yacc_cfg->log_facility = LOG_LOCAL5; } else if (strncasecmp ($3, "LOG_LOCAL6", sizeof ("LOG_LOCAL6") - 1) == 0) { - cfg->log_facility = LOG_LOCAL6; + yacc_cfg->log_facility = LOG_LOCAL6; } else if (strncasecmp ($3, "LOG_LOCAL7", sizeof ("LOG_LOCAL7") - 1) == 0) { - cfg->log_facility = LOG_LOCAL7; + yacc_cfg->log_facility = LOG_LOCAL7; } else { yyerror ("yyparse: invalid logging facility: %s", $3); @@ -643,7 +643,7 @@ loggingfacility: loggingfile: LOG_FILENAME EQSIGN QUOTEDSTRING { - cfg->log_file = memory_pool_strdup (cfg->cfg_pool, $3); + yacc_cfg->log_file = memory_pool_strdup (yacc_cfg->cfg_pool, $3); free ($3); } @@ -652,7 +652,7 @@ loggingfile: loggingurls: LOG_URLS EQSIGN FLAG { if ($3 != 0) { - cfg->log_urls = TRUE; + yacc_cfg->log_urls = TRUE; } } ; @@ -660,14 +660,14 @@ loggingurls: loggingbuffer: LOG_BUFFER EQSIGN NUMBER | LOG_BUFFER EQSIGN SIZELIMIT { - cfg->log_buf_size = $3; - cfg->log_buffered = TRUE; + yacc_cfg->log_buf_size = $3; + yacc_cfg->log_buffered = TRUE; } ; loggingdebugip: DEBUG_IP EQSIGN QUOTEDSTRING { - cfg->debug_ip_map = $3; + yacc_cfg->debug_ip_map = $3; } ; @@ -684,7 +684,7 @@ classifier: cur_classifier->tokenizer = get_tokenizer ("osb-text"); } - cfg->classifiers = g_list_prepend (cfg->classifiers, cur_classifier); + yacc_cfg->classifiers = g_list_prepend (yacc_cfg->classifiers, cur_classifier); cur_classifier = NULL; } ; @@ -704,7 +704,7 @@ classifiercmd: classifiertype: TYPE EQSIGN QUOTEDSTRING { - cur_classifier = check_classifier_cfg (cfg, cur_classifier); + cur_classifier = check_classifier_cfg (yacc_cfg, cur_classifier); if ((cur_classifier->classifier = get_classifier ($3)) == NULL) { yyerror ("yyparse: unknown classifier type: %s", $3); YYERROR; @@ -713,7 +713,7 @@ classifiertype: ; classifiertokenizer: TOKENIZER EQSIGN QUOTEDSTRING { - cur_classifier = check_classifier_cfg (cfg, cur_classifier); + cur_classifier = check_classifier_cfg (yacc_cfg, cur_classifier); if ((cur_classifier->tokenizer = get_tokenizer ($3)) == NULL) { yyerror ("yyparse: unknown tokenizer %s", $3); YYERROR; @@ -723,18 +723,18 @@ classifiertokenizer: classifiermetric: METRIC EQSIGN QUOTEDSTRING { - cur_classifier = check_classifier_cfg (cfg, cur_classifier); + cur_classifier = check_classifier_cfg (yacc_cfg, cur_classifier); cur_classifier->metric = $3; - memory_pool_add_destructor (cfg->cfg_pool, g_free, cur_classifier->metric); + memory_pool_add_destructor (yacc_cfg->cfg_pool, g_free, cur_classifier->metric); } ; classifieroption: PARAM EQSIGN QUOTEDSTRING { - cur_classifier = check_classifier_cfg (cfg, cur_classifier); + cur_classifier = check_classifier_cfg (yacc_cfg, cur_classifier); g_hash_table_insert (cur_classifier->opts, $1, $3); - memory_pool_add_destructor (cfg->cfg_pool, g_free, $1); - memory_pool_add_destructor (cfg->cfg_pool, g_free, $3); + memory_pool_add_destructor (yacc_cfg->cfg_pool, g_free, $1); + memory_pool_add_destructor (yacc_cfg->cfg_pool, g_free, $3); }; statfile: @@ -743,9 +743,9 @@ statfile: yyerror ("yyparse: not enough arguments in statfile definition"); YYERROR; } - cur_classifier = check_classifier_cfg (cfg, cur_classifier); + cur_classifier = check_classifier_cfg (yacc_cfg, cur_classifier); cur_classifier->statfiles = g_list_prepend (cur_classifier->statfiles, cur_statfile); - cfg->statfiles = g_list_prepend (cfg->statfiles, cur_statfile); + yacc_cfg->statfiles = g_list_prepend (yacc_cfg->statfiles, cur_statfile); cur_statfile = NULL; } ; @@ -769,21 +769,21 @@ statfilecmd: statfilesymbol: SYMBOL EQSIGN QUOTEDSTRING { - cur_classifier = check_classifier_cfg (cfg, cur_classifier); + cur_classifier = check_classifier_cfg (yacc_cfg, cur_classifier); if (cur_statfile == NULL) { - cur_statfile = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile)); + cur_statfile = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile)); } - cur_statfile->symbol = memory_pool_strdup (cfg->cfg_pool, $3); - g_hash_table_insert (cfg->classifiers_symbols, $3, cur_classifier); + cur_statfile->symbol = memory_pool_strdup (yacc_cfg->cfg_pool, $3); + g_hash_table_insert (yacc_cfg->classifiers_symbols, $3, cur_classifier); } ; statfilepath: PATH EQSIGN QUOTEDSTRING { if (cur_statfile == NULL) { - cur_statfile = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile)); + cur_statfile = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile)); } - cur_statfile->path = memory_pool_strdup (cfg->cfg_pool, $3); + cur_statfile->path = memory_pool_strdup (yacc_cfg->cfg_pool, $3); } ; @@ -791,13 +791,13 @@ statfilepath: statfilesize: SIZE EQSIGN NUMBER { if (cur_statfile == NULL) { - cur_statfile = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile)); + cur_statfile = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile)); } cur_statfile->size = $3; } | SIZE EQSIGN SIZELIMIT { if (cur_statfile == NULL) { - cur_statfile = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile)); + cur_statfile = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile)); } cur_statfile->size = $3; } @@ -808,7 +808,7 @@ statfilesize: statfilesection: SECTION OBRACE sectionbody EBRACE { if (cur_statfile == NULL) { - cur_statfile = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile)); + cur_statfile = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile)); } if (cur_section == NULL || cur_section->code == 0) { yyerror ("yyparse: error in section definition"); @@ -833,7 +833,7 @@ sectioncmd: sectionname: NAME EQSIGN QUOTEDSTRING { if (cur_section == NULL) { - cur_section = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile_section)); + cur_section = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile_section)); } cur_section->code = statfile_get_section_by_name ($3); } @@ -842,13 +842,13 @@ sectionname: sectionsize: SIZE EQSIGN NUMBER { if (cur_section == NULL) { - cur_section = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile_section)); + cur_section = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile_section)); } cur_section->size = $3; } | SIZE EQSIGN SIZELIMIT { if (cur_section == NULL) { - cur_section = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile_section)); + cur_section = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile_section)); } cur_section->size = $3; } @@ -857,13 +857,13 @@ sectionsize: sectionweight: WEIGHT EQSIGN NUMBER { if (cur_section == NULL) { - cur_section = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile_section)); + cur_section = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile_section)); } cur_section->weight = $3; } | WEIGHT EQSIGN FRACT { if (cur_section == NULL) { - cur_section = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile_section)); + cur_section = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile_section)); } cur_section->weight = $3; } @@ -872,7 +872,7 @@ sectionweight: statfileautolearn: AUTOLEARN OBRACE autolearnbody EBRACE { if (cur_statfile == NULL) { - cur_statfile = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile)); + cur_statfile = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile)); } if (cur_autolearn == NULL) { yyerror ("yyparse: error in autolearn definition"); @@ -898,22 +898,22 @@ autolearncmd: autolearnmetric: METRIC EQSIGN QUOTEDSTRING { if (cur_autolearn == NULL) { - cur_autolearn = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile_autolearn_params)); + cur_autolearn = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile_autolearn_params)); } - cur_autolearn->metric = memory_pool_strdup (cfg->cfg_pool, $3); + cur_autolearn->metric = memory_pool_strdup (yacc_cfg->cfg_pool, $3); } ; autolearnmin: MIN_MARK EQSIGN NUMBER { if (cur_autolearn == NULL) { - cur_autolearn = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile_autolearn_params)); + cur_autolearn = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile_autolearn_params)); } cur_autolearn->threshold_min = $3; } | MIN_MARK EQSIGN FRACT { if (cur_autolearn == NULL) { - cur_autolearn = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile_autolearn_params)); + cur_autolearn = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile_autolearn_params)); } cur_autolearn->threshold_min = $3; } @@ -922,13 +922,13 @@ autolearnmin: autolearnmax: MAX_MARK EQSIGN NUMBER { if (cur_autolearn == NULL) { - cur_autolearn = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile_autolearn_params)); + cur_autolearn = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile_autolearn_params)); } cur_autolearn->threshold_max = $3; } | MAX_MARK EQSIGN FRACT { if (cur_autolearn == NULL) { - cur_autolearn = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile_autolearn_params)); + cur_autolearn = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile_autolearn_params)); } cur_autolearn->threshold_max = $3; } @@ -937,19 +937,19 @@ autolearnmax: autolearnsymbols: SYMBOLS EQSIGN QUOTEDSTRING { if (cur_autolearn == NULL) { - cur_autolearn = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile_autolearn_params)); + cur_autolearn = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile_autolearn_params)); } - cur_autolearn->symbols = parse_comma_list (cfg->cfg_pool, $3); + cur_autolearn->symbols = parse_comma_list (yacc_cfg->cfg_pool, $3); } ; statfilebinlog: BINLOG EQSIGN QUOTEDSTRING { if (cur_statfile == NULL) { - cur_statfile = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile)); + cur_statfile = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile)); } if (cur_statfile->binlog == NULL) { - cur_statfile->binlog = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile_binlog_params)); + cur_statfile->binlog = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile_binlog_params)); } if (g_ascii_strcasecmp ($3, "master") == 0) { cur_statfile->binlog->affinity = AFFINITY_MASTER; @@ -966,10 +966,10 @@ statfilebinlog: statfilebinlogrotate: BINLOG_ROTATE EQSIGN QUOTEDSTRING { if (cur_statfile == NULL) { - cur_statfile = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile)); + cur_statfile = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile)); } if (cur_statfile->binlog == NULL) { - cur_statfile->binlog = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile_binlog_params)); + cur_statfile->binlog = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile_binlog_params)); } cur_statfile->binlog->rotate_time = parse_seconds ($3); } @@ -978,10 +978,10 @@ statfilebinlogrotate: statfilebinlogmaster: BINLOG_MASTER EQSIGN QUOTEDSTRING { if (cur_statfile == NULL) { - cur_statfile = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile)); + cur_statfile = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile)); } if (cur_statfile->binlog == NULL) { - cur_statfile->binlog = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile_binlog_params)); + cur_statfile->binlog = memory_pool_alloc0 (yacc_cfg->cfg_pool, sizeof (struct statfile_binlog_params)); } if (!parse_host_port ($3, &cur_statfile->binlog->master_addr, &cur_statfile->binlog->master_port)) { YYERROR; @@ -991,21 +991,21 @@ statfilebinlogmaster: statfilenormalizer: NORMALIZER EQSIGN QUOTEDSTRING { - if (!parse_normalizer (cfg, cur_statfile, $3)) { + if (!parse_normalizer (yacc_cfg, cur_statfile, $3)) { yyerror ("cannot parse normalizer string: %s", $3); YYERROR; } - cur_statfile->normalizer_str = memory_pool_strdup (cfg->cfg_pool, $3); + cur_statfile->normalizer_str = memory_pool_strdup (yacc_cfg->cfg_pool, $3); } ; statfile_pool_size: STATFILE_POOL_SIZE EQSIGN SIZELIMIT { - cfg->max_statfile_size = $3; + yacc_cfg->max_statfile_size = $3; } | STATFILE_POOL_SIZE EQSIGN NUMBER { - cfg->max_statfile_size = $3; + yacc_cfg->max_statfile_size = $3; } ; @@ -1016,14 +1016,14 @@ luacode: raw_mode: RAW_MODE EQSIGN FLAG { - cfg->raw_mode = $3; + yacc_cfg->raw_mode = $3; } ; profile_file: PROFILE_FILE EQSIGN QUOTEDSTRING { #ifdef WITH_GPREF_TOOLS - cfg->profile_path = $3; + yacc_cfg->profile_path = $3; #else yywarn ("yyparse: profile_file directive is ignored as gperf support is not enabled"); #endif @@ -1036,7 +1036,7 @@ view: yyerror ("yyparse: not enough arguments in view definition"); YYERROR; } - cfg->views = g_list_prepend (cfg->views, cur_view); + yacc_cfg->views = g_list_prepend (yacc_cfg->views, cur_view); cur_view = NULL; } ; @@ -1057,7 +1057,7 @@ viewcmd: viewip: IP EQSIGN QUOTEDSTRING { if (cur_view == NULL) { - cur_view = init_view (cfg->cfg_pool); + cur_view = init_view (yacc_cfg->cfg_pool); } if (!add_view_ip (cur_view, $3)) { yyerror ("yyparse: invalid ip line in view definition: ip = '%s'", $3); @@ -1069,7 +1069,7 @@ viewip: viewclientip: CLIENT_IP EQSIGN QUOTEDSTRING { if (cur_view == NULL) { - cur_view = init_view (cfg->cfg_pool); + cur_view = init_view (yacc_cfg->cfg_pool); } if (!add_view_client_ip (cur_view, $3)) { yyerror ("yyparse: invalid ip line in view definition: ip = '%s'", $3); @@ -1081,7 +1081,7 @@ viewclientip: viewfrom: FROM EQSIGN QUOTEDSTRING { if (cur_view == NULL) { - cur_view = init_view (cfg->cfg_pool); + cur_view = init_view (yacc_cfg->cfg_pool); } if (!add_view_from (cur_view, $3)) { yyerror ("yyparse: invalid from line in view definition: from = '%s'", $3); @@ -1092,7 +1092,7 @@ viewfrom: viewsymbols: SYMBOLS EQSIGN QUOTEDSTRING { if (cur_view == NULL) { - cur_view = init_view (cfg->cfg_pool); + cur_view = init_view (yacc_cfg->cfg_pool); } if (!add_view_symbols (cur_view, $3)) { yyerror ("yyparse: invalid symbols line in view definition: symbols = '%s'", $3); @@ -1103,7 +1103,7 @@ viewsymbols: viewskipcheck: SKIP_CHECK EQSIGN FLAG { if (cur_view == NULL) { - cur_view = init_view (cfg->cfg_pool); + cur_view = init_view (yacc_cfg->cfg_pool); } cur_view->skip_check = $3; } @@ -1125,20 +1125,20 @@ settingscmd: usersettings: USER_SETTINGS EQSIGN QUOTEDSTRING { - if (!read_settings ($3, cfg, cfg->user_settings)) { + if (!read_settings ($3, yacc_cfg, yacc_cfg->user_settings)) { yyerror ("yyparse: cannot read settings %s", $3); YYERROR; } - cfg->user_settings_str = memory_pool_strdup (cfg->cfg_pool, $3); + yacc_cfg->user_settings_str = memory_pool_strdup (yacc_cfg->cfg_pool, $3); } ; domainsettings: DOMAIN_SETTINGS EQSIGN QUOTEDSTRING { - if (!read_settings ($3, cfg, cfg->domain_settings)) { + if (!read_settings ($3, yacc_cfg, yacc_cfg->domain_settings)) { yyerror ("yyparse: cannot read settings %s", $3); YYERROR; } - cfg->domain_settings_str = memory_pool_strdup (cfg->cfg_pool, $3); + yacc_cfg->domain_settings_str = memory_pool_strdup (yacc_cfg->cfg_pool, $3); } ; %% diff --git a/src/cfg_xml.c b/src/cfg_xml.c index 16ff9dc8a..3f278f790 100644 --- a/src/cfg_xml.c +++ b/src/cfg_xml.c @@ -331,14 +331,15 @@ static struct xml_parser_rule grammar[] = { G_STRUCT_OFFSET (struct config_file, grow_factor), NULL }, + { + "factor", + handle_factor, + 0, + NULL + }, NULL_ATTR }, - { - NULL, - handle_factor, - 0, - NULL - } + NULL_ATTR }, { XML_SECTION_MODULE, { NULL_ATTR @@ -1409,7 +1410,7 @@ rspamd_xml_text (GMarkupParseContext *context, const gchar *text, gsize text_len } break; case XML_READ_FACTORS: - if (!call_param_handler (ud, ud->section_name, val, cfg, XML_SECTION_CLASSIFIER)) { + if (!call_param_handler (ud, ud->section_name, val, cfg, XML_SECTION_FACTORS)) { *error = g_error_new (xml_error_quark (), XML_EXTRA_ELEMENT, "cannot parse tag '%s' data: %s", ud->section_name, val); ud->state = XML_ERROR; } @@ -1577,6 +1578,33 @@ xml_dump_variables (struct config_file *cfg, FILE *f) return TRUE; } +/* Dump factors section */ +static void +xml_factors_callback (gpointer key, gpointer value, gpointer user_data) +{ + FILE *f = user_data; + char *escaped_key; + + escaped_key = g_markup_escape_text (key, -1); + fprintf (f, " %.2f" EOL, escaped_key, *(double *)value); + g_free (escaped_key); +} + +static gboolean +xml_dump_factors (struct config_file *cfg, FILE *f) +{ + /* Print header comment */ + fprintf (f, "" EOL "" EOL ); + + /* Iterate through variables */ + g_hash_table_foreach (cfg->factors, xml_factors_callback, (gpointer)f); + + /* Print footer comment */ + fprintf (f, "" EOL "" EOL EOL); + + return TRUE; +} + /* Composites section */ static void xml_composite_callback (gpointer key, gpointer value, gpointer user_data) @@ -1932,6 +1960,8 @@ xml_dump_config (struct config_file *cfg, const char *filename) CHECK_RES; res = xml_dump_variables (cfg, f); CHECK_RES; + res = xml_dump_factors (cfg, f); + CHECK_RES; res = xml_dump_composites (cfg, f); CHECK_RES; res = xml_dump_workers (cfg, f); diff --git a/src/main.c b/src/main.c index 442e09de9..e3bf1738d 100644 --- a/src/main.c +++ b/src/main.c @@ -48,11 +48,12 @@ /* 2 seconds to fork new process in place of dead one */ #define SOFT_FORK_TIME 2 -struct config_file *cfg; rspamd_hash_t *counters; static struct rspamd_worker *fork_worker (struct rspamd_main *, struct worker_conf *); +static gboolean load_rspamd_config (struct config_file *cfg); +static void init_metrics_cache (struct config_file *cfg); sig_atomic_t do_restart; sig_atomic_t do_terminate; @@ -63,8 +64,10 @@ sig_atomic_t got_alarm; GQueue *signals_info; #endif +/* Yacc vars */ extern int yynerrs; extern FILE *yyin; +struct config_file *yacc_cfg; static gboolean config_test; static gboolean no_fork; @@ -76,14 +79,12 @@ static gchar *convert_config; static gboolean dump_vars; static gboolean dump_cache; -#ifndef WITHOUT_PERL -extern void xs_init (pTHX); -extern PerlInterpreter *perl_interpreter; -#endif - /* List of workers that are pending to start */ static GList *workers_pending = NULL; +/* List of active listen sockets indexed by worker type */ +static GHashTable *listen_sockets; + /* Commandline options */ static GOptionEntry entries[] = { @@ -252,7 +253,8 @@ reread_config (struct rspamd_main *rspamd) { struct config_file *tmp_cfg; char *cfg_file; - FILE *f; + GList *l; + struct filter *filt; tmp_cfg = (struct config_file *)g_malloc (sizeof (struct config_file)); if (tmp_cfg) { @@ -260,29 +262,34 @@ reread_config (struct rspamd_main *rspamd) tmp_cfg->cfg_pool = memory_pool_new (memory_pool_get_size ()); init_defaults (tmp_cfg); cfg_file = memory_pool_strdup (tmp_cfg->cfg_pool, rspamd->cfg->cfg_name); - f = fopen (rspamd->cfg->cfg_name, "r"); - if (f == NULL) { - msg_warn ("cannot open file: %s", rspamd->cfg->cfg_name); + /* Save some variables */ + tmp_cfg->cfg_name = cfg_file; + tmp_cfg->lua_state = rspamd->cfg->lua_state; + + if (! load_rspamd_config (tmp_cfg)) { + msg_err ("cannot parse new config file, revert to old one"); + free_config (tmp_cfg); } else { - yyin = f; - yyrestart (yyin); + msg_debug ("replacing config"); + free_config (rspamd->cfg); + close_log (); + g_free (rspamd->cfg); + rspamd->cfg = tmp_cfg; + post_load_config (rspamd->cfg); + config_logger (rspamd, FALSE); + /* Perform modules configuring */ + l = g_list_first (rspamd->cfg->filters); - if (yyparse () != 0 || yynerrs > 0) { - msg_warn ("yyparse: cannot parse config file, %d errors", yynerrs); - fclose (f); - } - else { - msg_debug ("replacing config"); - free_config (rspamd->cfg); - close_log (); - g_free (rspamd->cfg); - rspamd->cfg = tmp_cfg; - rspamd->cfg->cfg_name = cfg_file; - config_logger (rspamd, FALSE); - open_log (); - msg_info ("config rereaded successfully"); + while (l) { + filt = l->data; + if (filt->module) { + (void)filt->module->module_config_func (rspamd->cfg); + } + l = g_list_next (l); } + init_metrics_cache (rspamd->cfg); + msg_info ("config rereaded successfully"); } } } @@ -320,18 +327,18 @@ fork_worker (struct rspamd_main *rspamd, struct worker_conf *cf) cur = (struct rspamd_worker *)g_malloc (sizeof (struct rspamd_worker)); if (cur) { bzero (cur, sizeof (struct rspamd_worker)); - g_queue_push_head (cf->active_workers, cur); cur->srv = rspamd; cur->type = cf->type; cur->pid = fork (); - cur->cf = cf; + cur->cf = g_malloc (sizeof (struct worker_conf)); + memcpy (cur->cf, cf, sizeof (struct worker_conf)); cur->pending = FALSE; switch (cur->pid) { case 0: /* Update pid for logging */ update_log_pid (); /* Drop privilleges */ - drop_priv (cfg); + drop_priv (rspamd->cfg); /* Set limits */ set_worker_limits (cf); switch (cf->type) { @@ -410,7 +417,7 @@ dump_all_variables (gpointer key, gpointer value, gpointer data) static void -dump_cfg_vars () +dump_cfg_vars (struct config_file *cfg) { g_hash_table_foreach (cfg->variables, dump_all_variables, NULL); } @@ -459,22 +466,30 @@ fork_delayed (struct rspamd_main *rspamd) } static void -spawn_workers (struct rspamd_main *rspamd, gboolean make_sockets) +spawn_workers (struct rspamd_main *rspamd) { GList *cur; struct worker_conf *cf; int i, listen_sock; + gpointer p; - cur = cfg->workers; + cur = rspamd->cfg->workers; while (cur) { cf = cur->data; - if (make_sockets && cf->has_socket) { - /* Create listen socket */ - listen_sock = create_listen_socket (&cf->bind_addr, cf->bind_port, cf->bind_family, cf->bind_host); - if (listen_sock == -1) { - exit (-errno); + if (cf->has_socket) { + if ((p = g_hash_table_lookup (listen_sockets, GINT_TO_POINTER (cf->type))) == NULL) { + /* Create listen socket */ + listen_sock = create_listen_socket (&cf->bind_addr, cf->bind_port, cf->bind_family, cf->bind_host); + if (listen_sock == -1) { + exit (-errno); + } + g_hash_table_insert (listen_sockets, GINT_TO_POINTER (cf->type), GINT_TO_POINTER (listen_sock)); + } + else { + /* We had socket for this type of worker */ + listen_sock = GPOINTER_TO_INT (p); } cf->listen_sock = listen_sock; } @@ -532,6 +547,7 @@ wait_for_workers (gpointer key, gpointer value, gpointer unused) waitpid (w->pid, &res, 0); msg_debug ("%s process %P terminated", get_process_type (w->type), w->pid); + g_free (w->cf); g_free (w); return TRUE; @@ -548,7 +564,8 @@ convert_old_config (struct rspamd_main *rspamd) return EBADF; } yyin = f; - + + yacc_cfg = rspamd->cfg; if (yyparse () != 0 || yynerrs > 0) { msg_err ("cannot parse config file, %d errors", yynerrs); return EBADF; @@ -579,39 +596,37 @@ convert_old_config (struct rspamd_main *rspamd) } static gboolean -load_rspamd_config (struct rspamd_main *rspamd) +load_rspamd_config (struct config_file *cfg) { GList *l; struct filter *filt; struct module_ctx *cur_module = NULL; - if (! read_xml_config (rspamd->cfg, rspamd->cfg->cfg_name)) { + if (! read_xml_config (cfg, cfg->cfg_name)) { return FALSE; } /* Strictly set temp dir */ - if (!rspamd->cfg->temp_dir) { + if (!cfg->temp_dir) { msg_warn ("tempdir is not set, trying to use $TMPDIR"); - rspamd->cfg->temp_dir = memory_pool_strdup (rspamd->cfg->cfg_pool, getenv ("TMPDIR")); + cfg->temp_dir = memory_pool_strdup (cfg->cfg_pool, getenv ("TMPDIR")); - if (!rspamd->cfg->temp_dir) { + if (!cfg->temp_dir) { msg_warn ("$TMPDIR is empty too, using /tmp as default"); - rspamd->cfg->temp_dir = memory_pool_strdup (rspamd->cfg->cfg_pool, "/tmp"); + cfg->temp_dir = memory_pool_strdup (cfg->cfg_pool, "/tmp"); } } /* Do post-load actions */ - post_load_config (rspamd->cfg); - /* Init counters */ - counters = rspamd_hash_new_shared (rspamd->server_pool, g_str_hash, g_str_equal, 64); + post_load_config (cfg); /* Init C modules */ - l = g_list_first (rspamd->cfg->filters); + l = g_list_first (cfg->filters); while (l) { filt = l->data; if (filt->module) { - cur_module = memory_pool_alloc (rspamd->cfg->cfg_pool, sizeof (struct module_ctx)); + cur_module = memory_pool_alloc (cfg->cfg_pool, sizeof (struct module_ctx)); if (filt->module->module_init_func (cfg, &cur_module) == 0) { g_hash_table_insert (cfg->c_modules, (gpointer) filt->module->name, cur_module); } @@ -622,22 +637,64 @@ load_rspamd_config (struct rspamd_main *rspamd) return TRUE; } +static void +init_metrics_cache (struct config_file *cfg) +{ + struct metric *metric; + GList *l; + + /* Init symbols cache for each metric */ + l = g_list_first (cfg->metrics_list); + while (l) { + metric = l->data; + if (metric->cache && !init_symbols_cache (cfg->cfg_pool, metric->cache, metric->cache_filename)) { + exit (EXIT_FAILURE); + } + l = g_list_next (l); + } +} + +static void +print_metrics_cache (struct config_file *cfg) +{ + struct metric *metric; + GList *l; + struct cache_item *item; + int i; + + l = g_list_first (cfg->metrics_list); + while (l) { + metric = l->data; + if (!init_symbols_cache (cfg->cfg_pool, metric->cache, metric->cache_filename)) { + exit (EXIT_FAILURE); + } + if (metric->cache) { + printf ("Cache for metric: %s\n", metric->name); + printf ("-----------------------------------------------------------------\n"); + printf ("| Pri | Symbol | Weight | Frequency | Avg. time |\n"); + for (i = 0; i < metric->cache->used_items; i++) { + item = &metric->cache->items[i]; + printf ("-----------------------------------------------------------------\n"); + printf ("| %3d | %22s | %6.1f | %9d | %9.3f |\n", i, item->s->symbol, item->s->weight, item->s->frequency, item->s->avg_time); + + } + printf ("-----------------------------------------------------------------\n"); + } + l = g_list_next (l); + } +} + int main (int argc, char **argv, char **env) { struct rspamd_main *rspamd; - int res = 0, i; + int res = 0; struct sigaction signals; struct rspamd_worker *cur; struct rlimit rlim; - struct metric *metric; - struct cache_item *item; struct filter *filt; pid_t wrk; GList *l; -#ifndef WITHOUT_PERL - char *args[] = { "", "-e", "0", NULL }; -#endif #ifdef HAVE_SA_SIGINFO signals_info = g_queue_new (); @@ -645,8 +702,7 @@ main (int argc, char **argv, char **env) rspamd = (struct rspamd_main *)g_malloc (sizeof (struct rspamd_main)); bzero (rspamd, sizeof (struct rspamd_main)); rspamd->server_pool = memory_pool_new (memory_pool_get_size ()); - cfg = (struct config_file *)g_malloc (sizeof (struct config_file)); - rspamd->cfg = cfg; + rspamd->cfg = (struct config_file *)g_malloc (sizeof (struct config_file)); if (!rspamd || !rspamd->cfg) { fprintf (stderr, "Cannot allocate memory\n"); exit (-errno); @@ -657,6 +713,10 @@ main (int argc, char **argv, char **env) child_dead = 0; do_reopen_log = 0; +#ifndef HAVE_SETPROCTITLE + init_title (argc, argv, environ); +#endif + rspamd->stat = memory_pool_alloc_shared (rspamd->server_pool, sizeof (struct rspamd_stat)); bzero (rspamd->stat, sizeof (struct rspamd_stat)); @@ -671,11 +731,11 @@ main (int argc, char **argv, char **env) rspamd->cfg->cfg_name = FIXED_CONFIG_FILE; } - if (cfg->config_test) { - cfg->log_level = G_LOG_LEVEL_DEBUG; + if (rspamd->cfg->config_test) { + rspamd->cfg->log_level = G_LOG_LEVEL_DEBUG; } else { - cfg->log_level = G_LOG_LEVEL_CRITICAL; + rspamd->cfg->log_level = G_LOG_LEVEL_CRITICAL; } #ifdef HAVE_SETLOCALE @@ -689,12 +749,14 @@ main (int argc, char **argv, char **env) /* First set logger to console logger */ rspamd_set_logger (RSPAMD_LOG_CONSOLE, rspamd->cfg); (void)open_log (); - g_log_set_default_handler (rspamd_glib_log_function, cfg); + g_log_set_default_handler (rspamd_glib_log_function, rspamd->cfg); -#ifndef HAVE_SETPROCTITLE - init_title (argc, argv, environ); -#endif - init_lua (cfg); + init_lua (rspamd->cfg); + + /* Init counters */ + counters = rspamd_hash_new_shared (rspamd->server_pool, g_str_hash, g_str_equal, 64); + /* Init listen sockets hash */ + listen_sockets = g_hash_table_new (g_direct_hash, g_direct_equal); if (convert_config != NULL) { if (! convert_old_config (rspamd)) { @@ -702,11 +764,11 @@ main (int argc, char **argv, char **env) } } - if (! load_rspamd_config (rspamd)) { + if (! load_rspamd_config (rspamd->cfg)) { exit (EXIT_FAILURE); } - if (cfg->config_test || dump_vars || dump_cache) { + if (rspamd->cfg->config_test || dump_vars || dump_cache) { /* Init events to test modules */ event_init (); res = TRUE; @@ -716,37 +778,18 @@ main (int argc, char **argv, char **env) while (l) { filt = l->data; if (filt->module) { - if (!filt->module->module_config_func (cfg)) { + if (!filt->module->module_config_func (rspamd->cfg)) { res = FALSE; } } l = g_list_next (l); } - init_lua_filters (cfg); + init_lua_filters (rspamd->cfg); if (dump_vars) { - dump_cfg_vars (); + dump_cfg_vars (rspamd->cfg); } if (dump_cache) { - l = g_list_first (cfg->metrics_list); - while (l) { - metric = l->data; - if (!init_symbols_cache (cfg->cfg_pool, metric->cache, metric->cache_filename)) { - exit (EXIT_FAILURE); - } - if (metric->cache) { - printf ("Cache for metric: %s\n", metric->name); - printf ("-----------------------------------------------------------------\n"); - printf ("| Pri | Symbol | Weight | Frequency | Avg. time |\n"); - for (i = 0; i < metric->cache->used_items; i++) { - item = &metric->cache->items[i]; - printf ("-----------------------------------------------------------------\n"); - printf ("| %3d | %22s | %6.1f | %9d | %9.3f |\n", i, item->s->symbol, item->s->weight, item->s->frequency, item->s->avg_time); - - } - printf ("-----------------------------------------------------------------\n"); - } - l = g_list_next (l); - } + print_metrics_cache (rspamd->cfg); exit (EXIT_SUCCESS); } fprintf (stderr, "syntax %s\n", res ? "OK" : "BAD"); @@ -784,7 +827,7 @@ main (int argc, char **argv, char **env) setproctitle ("main process"); /* Init statfile pool */ - rspamd->statfile_pool = statfile_pool_new (cfg->max_statfile_size); + rspamd->statfile_pool = statfile_pool_new (rspamd->cfg->max_statfile_size); event_init (); g_mime_init (0); @@ -795,45 +838,22 @@ main (int argc, char **argv, char **env) while (l) { filt = l->data; if (filt->module) { - if (!filt->module->module_config_func (cfg)) { + if (!filt->module->module_config_func (rspamd->cfg)) { res = FALSE; } } l = g_list_next (l); } -#ifndef WITHOUT_PERL - /* Init perl interpreter */ - dTHXa (perl_interpreter); - PERL_SYS_INIT3 (&argc, &argv, &env); - perl_interpreter = perl_alloc (); - if (perl_interpreter == NULL) { - msg_err ("cannot allocate perl interpreter, %s", strerror (errno)); - exit (-errno); - } - - PERL_SET_CONTEXT (perl_interpreter); - perl_construct (perl_interpreter); - perl_parse (perl_interpreter, xs_init, 3, args, NULL); - init_perl_filters (cfg); -#endif - - init_lua_filters (cfg); + init_lua_filters (rspamd->cfg); /* Init symbols cache for each metric */ - l = g_list_first (cfg->metrics_list); - while (l) { - metric = l->data; - if (metric->cache && !init_symbols_cache (cfg->cfg_pool, metric->cache, metric->cache_filename)) { - exit (EXIT_FAILURE); - } - l = g_list_next (l); - } + init_metrics_cache (rspamd->cfg); flush_log_buf (); rspamd->workers = g_hash_table_new (g_direct_hash, g_direct_equal); - spawn_workers (rspamd, TRUE); + spawn_workers (rspamd); /* Signal processing cycle */ for (;;) { @@ -857,7 +877,6 @@ main (int argc, char **argv, char **env) /* Unlink dead process from queue and hash table */ g_hash_table_remove (rspamd->workers, GSIZE_TO_POINTER (wrk)); - g_queue_remove (cur->cf->active_workers, cur); if (WIFEXITED (res) && WEXITSTATUS (res) == 0) { /* Normal worker termination, do not fork one more */ @@ -886,7 +905,8 @@ main (int argc, char **argv, char **env) msg_info ("rspamd " RVERSION " is restarting"); g_hash_table_foreach (rspamd->workers, kill_old_workers, NULL); - spawn_workers (rspamd, FALSE); + reread_config (rspamd); + spawn_workers (rspamd); } if (got_alarm) { diff --git a/src/main.h b/src/main.h index f79c7cd65..028954c71 100644 --- a/src/main.h +++ b/src/main.h @@ -21,7 +21,7 @@ #include "logger.h" /* Default values */ -#define FIXED_CONFIG_FILE ETC_PREFIX "/rspamd.conf" +#define FIXED_CONFIG_FILE ETC_PREFIX "/rspamd.xml" /* Time in seconds to exit for old worker */ #define SOFT_SHUTDOWN_TIME 10 /* Default metric name */ -- 2.39.5