From 9a1ba2296dd152c8eb7d19a70de51721be836baa Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Mon, 1 Dec 2008 19:15:52 +0300 Subject: [PATCH] * Add config routines for stat files * Add function to resolve stat file name --- src/cfg_file.h | 7 ++++++ src/cfg_file.l | 6 +++++ src/cfg_file.y | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ src/cfg_utils.c | 3 +++ src/util.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ src/util.h | 4 ++++ 6 files changed, 138 insertions(+) diff --git a/src/cfg_file.h b/src/cfg_file.h index 1eb71476d..c1c95b620 100644 --- a/src/cfg_file.h +++ b/src/cfg_file.h @@ -92,6 +92,12 @@ struct module_opt { LIST_ENTRY (module_opt) next; }; +struct statfile { + char *alias; + char *pattern; + double weight; +}; + struct config_file { memory_pool_t *cfg_pool; char *cfg_name; @@ -142,6 +148,7 @@ struct config_file { GHashTable* factors; GHashTable* c_modules; GHashTable* composite_symbols; + GHashTable* statfiles; }; int add_memcached_server (struct config_file *cf, char *str); diff --git a/src/cfg_file.l b/src/cfg_file.l index fefd11237..582784971 100644 --- a/src/cfg_file.l +++ b/src/cfg_file.l @@ -49,6 +49,12 @@ required_score return REQUIRED_SCORE; function return FUNCTION; control return CONTROL; password return PASSWORD; + +statfile return STATFILE; +alias return ALIAS; +pattern return PATTERN; +weight return WEIGHT; + logging return LOGGING; log_type return LOG_TYPE; diff --git a/src/cfg_file.y b/src/cfg_file.y index dbbdd4e63..62f247485 100644 --- a/src/cfg_file.y +++ b/src/cfg_file.y @@ -27,6 +27,7 @@ extern char *yytext; LIST_HEAD (moduleoptq, module_opt) *cur_module_opt = NULL; struct metric *cur_metric = NULL; +struct statfile *cur_statfile = NULL; %} @@ -52,6 +53,7 @@ struct metric *cur_metric = NULL; %token REQUIRED_SCORE FUNCTION FRACT COMPOSITES CONTROL PASSWORD %token LOGGING LOG_TYPE LOG_TYPE_CONSOLE LOG_TYPE_SYSLOG LOG_TYPE_FILE %token LOG_LEVEL LOG_LEVEL_DEBUG LOG_LEVEL_INFO LOG_LEVEL_WARNING LOG_LEVEL_ERROR LOG_FACILITY LOG_FILENAME +%token STATFILE ALIAS PATTERN WEIGHT %type STRING %type VARIABLE @@ -91,6 +93,7 @@ command : | metric | composites | logging + | statfile ; tempdir : @@ -539,6 +542,62 @@ loggingfile: } ; +statfile: + STATFILE OBRACE statfilebody EBRACE { + if (cur_statfile == NULL || cur_statfile->alias == NULL || cur_statfile->pattern == NULL || cur_statfile->weight == 0) { + yyerror ("yyparse: not enough arguments in statfile definition"); + YYERROR; + } + g_hash_table_insert (cfg->statfiles, cur_statfile->alias, cur_statfile); + cur_statfile = NULL; + } + ; + +statfilebody: + | statfilecmd SEMICOLON + | statfilebody statfilecmd SEMICOLON + ; + +statfilecmd: + | statfilealias + | statfilepattern + | statfileweight + ; + +statfilealias: + ALIAS EQSIGN QUOTEDSTRING { + if (cur_statfile == NULL) { + cur_statfile = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile)); + } + cur_statfile->alias = memory_pool_strdup (cfg->cfg_pool, $3); + } + ; + +statfilepattern: + PATTERN EQSIGN QUOTEDSTRING { + if (cur_statfile == NULL) { + cur_statfile = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile)); + } + cur_statfile->pattern = memory_pool_strdup (cfg->cfg_pool, $3); + } + ; + +statfileweight: + WEIGHT EQSIGN NUMBER { + if (cur_statfile == NULL) { + cur_statfile = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile)); + } + cur_statfile->weight = $3; + } + | WEIGHT EQSIGN FRACT { + if (cur_statfile == NULL) { + cur_statfile = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile)); + } + cur_statfile->weight = $3; + } + ; + + %% /* * vi:ts=4 diff --git a/src/cfg_utils.c b/src/cfg_utils.c index 9fa7aac47..25e03c2a0 100644 --- a/src/cfg_utils.c +++ b/src/cfg_utils.c @@ -169,6 +169,7 @@ init_defaults (struct config_file *cfg) cfg->factors = g_hash_table_new (g_str_hash, g_str_equal); cfg->c_modules = g_hash_table_new (g_str_hash, g_str_equal); cfg->composite_symbols = g_hash_table_new (g_str_hash, g_str_equal); + cfg->statfiles = g_hash_table_new (g_str_hash, g_str_equal); LIST_INIT (&cfg->perl_modules); } @@ -188,6 +189,8 @@ free_config (struct config_file *cfg) g_hash_table_unref (cfg->c_modules); g_hash_table_remove_all (cfg->composite_symbols); g_hash_table_unref (cfg->composite_symbols); + g_hash_table_remove_all (cfg->statfiles); + g_hash_table_unref (cfg->statfiles); memory_pool_delete (cfg->cfg_pool); } diff --git a/src/util.c b/src/util.c index 90a536359..828c3d518 100644 --- a/src/util.c +++ b/src/util.c @@ -829,6 +829,65 @@ file_log_function (const gchar *log_domain, GLogLevelFlags log_level, const gcha writev (cfg->log_fd, out, sizeof (out) / sizeof (out[0])); } } + +/* Replace %r with rcpt value and %f with from value, new string is allocated in pool */ +char * +resolve_stat_filename (memory_pool_t *pool, char *pattern, char *rcpt, char *from) +{ + int need_to_format = 0, len = 0; + int rcptlen = strlen (rcpt); + int fromlen = strlen (from); + char *c = pattern, *new, *s; + + /* Calculate length */ + while (*c++) { + if (*c == '%' && *(c + 1) == 'r') { + len += rcptlen; + c += 2; + need_to_format = 1; + continue; + } + else if (*c == '%' && *(c + 1) == 'f') { + len += fromlen; + c += 2; + need_to_format = 1; + continue; + } + len ++; + } + + /* Do not allocate extra memory if we do not need to format string */ + if (!need_to_format) { + return pattern; + } + + /* Allocate new string */ + new = memory_pool_alloc (pool, len); + c = pattern; + s = new; + + /* Format string */ + while (*c ++) { + if (*c == '%' && *(c + 1) == 'r') { + c += 2; + memcpy (s, rcpt, rcptlen); + s += rcptlen; + continue; + } + else if (*c == '%' && *(c + 1) == 'r') { + c += 2; + memcpy (s, from, fromlen); + s += fromlen; + continue; + } + *s ++ = *c; + } + + *s = '\0'; + + return new; +} + /* * vi:ts=4 */ diff --git a/src/util.h b/src/util.h index 1791f4635..9c05a2a27 100644 --- a/src/util.h +++ b/src/util.h @@ -57,4 +57,8 @@ int reopen_log (struct config_file *cfg); void syslog_log_function (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer arg); void file_log_function (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer arg); +/* Replace %r with rcpt value and %f with from value, new string is allocated in pool */ +char* resolve_stat_filename (memory_pool_t *pool, char *pattern, char *rcpt, char *from); + + #endif -- 2.39.5