diff --git a/NEWS b/NEWS index cefe2d7..6428edd 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,8 @@ - m-kress: -- Do not substitute trailing control characters of a log line, but eliminate them completelly. Be aware, that this change will break existing filters that rely on the trailing underscore! + -- note in config file and man page: comments must be started with # only at the beginning of a line + -- add "configdir" to config, which allows reading additional config files ending with *.conf * Version 20230707 - m-kress: diff --git a/man/metalog.conf.5.in b/man/metalog.conf.5.in index d4bfd4c..5489523 100644 --- a/man/metalog.conf.5.in +++ b/man/metalog.conf.5.in @@ -185,6 +185,11 @@ if the rate of messages has been well below the limit before. The specified message rate will not be exceeded. The default value of 1 disables special treatment for bursts. Values less than 1 are invalid and will be rejected. +.TP +\fBconfigdir = \fI"/path/to/directory/with/more/config/files"\fR +This optional directory can contain more config files that will get interpreted at +metalog start. Only file names ending with ".conf" are interpreted. This option is +only allowed once, all repetitions will be ignored. .SH "FILES" .LP Note that the exact paths depend on the build settings. These are the standard paths. diff --git a/metalog.conf b/metalog.conf index 3ad39b4..8f53b87 100644 --- a/metalog.conf +++ b/metalog.conf @@ -11,6 +11,9 @@ maxtime = 2592000 # Number of archive files per directory maxfiles = 5 +# directory with more config files to load; files names must end with ".conf" +#configdir = /etc/metalog.d + # Permissions for log directories. 0750 allows group to read logs. 0700 is default. #perms = 0750 diff --git a/src/metalog.c b/src/metalog.c index ecca219..ea04eb1 100644 --- a/src/metalog.c +++ b/src/metalog.c @@ -206,6 +206,17 @@ static int parseLine(char * const line, ConfigBlock **cur_block, (*cur_block)->output->perms = (*cur_block)->perms; } } + else if (strcasecmp(keyword, "configdir") == 0) { + /* allow only once to avoid recursion */ + if (config_dir != NULL) { + warnp("Ignore repeated \"configdir\" statement"); + } + else { + if ((config_dir = wstrdup(value)) == NULL) { + return -3; + } + } + } else if (strcasecmp(keyword, "logdir") == 0) { char *logdir = NULL; Output *outputs_scan = outputs; @@ -406,7 +417,7 @@ static int parseLine(char * const line, ConfigBlock **cur_block, static int configParser(const char * const file) { char line[LINE_MAX]; - FILE *fp; + FILE *fp = NULL; pcre2_code *re_newblock; pcre2_code *re_newstmt; pcre2_code *re_comment; @@ -459,6 +470,55 @@ static int configParser(const char * const file) break; } } + + /* read all config files of an eventually configured directory */ + if (config_dir != NULL) { + DIR *dp; + struct dirent *ep; + + dp = opendir(config_dir); + if (dp == NULL) { + retcode = -1; + goto rtn; + } + + /* config file names must end with ".conf" */ + while ((ep = readdir(dp)) != NULL) { + FILE *fp2 = NULL; + char *p = NULL; + char *file_path = NULL; + + p = strchr(ep->d_name, (int) '.'); + if (p == NULL || !strstr(p, ".conf")) { + continue; + } + + if ((file_path = wmalloc(strlen(ep->d_name) + strlen(config_dir) + 2)) == NULL) { + retcode = -1; + goto rtn; + } + sprintf(file_path, "%s/%s", config_dir, ep->d_name); + if ((fp2 = fopen(file_path, "r")) == NULL) { + warnp("Can't open the config file %s", file_path); + retcode = -1; + free(file_path); + goto rtn; + } + + while (fgets(line, sizeof line, fp2) != NULL) { + if ((retcode = parseLine(line, &cur_block, &default_block, + re_newblock, re_newstmt, + re_comment, re_null)) != 0) { + break; + } + } + + free(file_path); + fclose(fp2); + } + closedir(dp); + } + rtn: if (re_newblock != NULL) { pcre2_code_free(re_newblock); diff --git a/src/metalog_p.h b/src/metalog_p.h index 749fc11..3277c98 100644 --- a/src/metalog_p.h +++ b/src/metalog_p.h @@ -43,6 +43,7 @@ static bool do_kernel_log = true; static signed char daemonize; static const char *pid_file = DEFAULT_PID_FILE; static const char *config_file = DEFAULT_CONFIG_FILE; +static const char *config_dir = NULL; static const char *group_name = NULL; #endif