]> source.dussan.org Git - rspamd.git/commitdiff
* Handle and dump factors correctly
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Thu, 8 Apr 2010 17:22:13 +0000 (21:22 +0400)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Thu, 8 Apr 2010 17:22:13 +0000 (21:22 +0400)
* Many fixes to processes spawning
* Implement rereading of config
* Fix stupid yacc with its stupid global vars

src/cfg_file.l
src/cfg_file.y
src/cfg_xml.c
src/main.c
src/main.h

index 83c35290ccdc38dedc85c7881521cbdac891679b..542488e2f1d196c8d2c3b1e761661bf7049fca04 100644 (file)
@@ -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;
 <classifier_lex_state>[a-zA-Z0-9_%-]+                  yylval.string=strdup(yytext); return PARAM;
 <classifier_lex_state>\".+[^\\]\"      yylval.string=strdup(yytext + 1); yylval.string[strlen(yylval.string) - 1] = '\0'; unescape_quotes(yylval.string); return QUOTEDSTRING;
 
-<lua_lex_state>\n                                                                      /* ignore EOL */;
-<lua_lex_state>[ \t]+                                                          /* ignore whitespace */;
-<lua_lex_state>[ \t]*#.*                                                       /* ignore comments */;
-<lua_lex_state>^.endlua$                                                       BEGIN(INITIAL);
-<lua_lex_state>.*                                                                      add_luabuf(yytext); return LUACODE;
-
 %%
 /* 
  * vi:ts=4 
index 07853bfa5a77ef0d211a4a07f1cdf85393654a5c..13902c6ae7013405d84f4547015ac018e8674485 100644 (file)
@@ -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);
     }
     ;
 %%
index 16ff9dc8ac129862c86fde7b884c67b4378a0001..3f278f7903228e536e5a76b7cc32a5dc675304e4 100644 (file)
@@ -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,  " <factor name=\"%s\">%.2f</factor>" 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, "<!-- Factors section -->" EOL "<factors>" EOL );
+
+       /* Iterate through variables */
+       g_hash_table_foreach (cfg->factors, xml_factors_callback, (gpointer)f);
+
+       /* Print footer comment */
+       fprintf (f, "</factors>" EOL "<!-- End of factors section -->" 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);
index 442e09de91cf1593bb61eba007306f59640691bc..e3bf1738d86d2aa2987bfb5a0eae5a3ac1ae023f 100644 (file)
 /* 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) {
index f79c7cd6553aad5df7b57be27457771a169c38ea..028954c71111ebc07a67b2a8286d9544b0fa759c 100644 (file)
@@ -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 */