[PATCH 1/2] cfg-lexer: Split cfg_lexer_include_file() into two functions
To be able to keep the code simple in the future, split cfg_lexer_include_file() into two: the intent is that we'll check if the file exists, and if not, try the same thing as a glob, otherwise continue as we did before. This would nest too deep, so split out the current bulk into a separate function. Signed-off-by: Gergely Nagy <algernon@balabit.hu> --- lib/cfg-lexer.c | 59 +++++++++++++++++++++++++++++++++++------------------- 1 files changed, 38 insertions(+), 21 deletions(-) diff --git a/lib/cfg-lexer.c b/lib/cfg-lexer.c index 6143a27..cfe229f 100644 --- a/lib/cfg-lexer.c +++ b/lib/cfg-lexer.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2002-2010 BalaBit IT Ltd, Budapest, Hungary - * Copyright (c) 1998-2010 Balázs Scheidler + * Copyright (c) 2002-2012 BalaBit IT Ltd, Budapest, Hungary + * Copyright (c) 1998-2012 Balázs Scheidler * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -379,32 +379,18 @@ cfg_lexer_start_next_include(CfgLexer *self) return TRUE; } -gboolean -cfg_lexer_include_file(CfgLexer *self, const gchar *filename_) +static gboolean +cfg_lexer_include_file_simple(CfgLexer *self, gchar *filename) { - struct stat st; CfgIncludeLevel *level; - gchar *filename; + struct stat st; - if (self->include_depth >= MAX_INCLUDE_DEPTH - 1) + if (stat(filename, &st) < 0) { - msg_error("Include file depth is too deep, increase MAX_INCLUDE_DEPTH and recompile", - evt_tag_str("filename", filename_), - evt_tag_int("depth", self->include_depth), - NULL); + g_free(filename); return FALSE; } - filename = find_file_in_path(cfg_args_get(self->globals, "include-path"), filename_, G_FILE_TEST_EXISTS); - if (!filename || stat(filename, &st) < 0) - { - msg_error("Include file/directory not found", - evt_tag_str("filename", filename_), - evt_tag_str("include-path", cfg_args_get(self->globals, "include-path")), - evt_tag_errno("error", errno), - NULL); - return FALSE; - } self->include_depth++; level = &self->include_stack[self->include_depth]; level->include_type = CFGI_FILE; @@ -488,10 +474,41 @@ cfg_lexer_include_file(CfgLexer *self, const gchar *filename_) g_slist_foreach(level->file.files, (GFunc) g_free, NULL); g_slist_free(level->file.files); level->file.files = NULL; + return FALSE; } gboolean +cfg_lexer_include_file(CfgLexer *self, const gchar *filename_) +{ + struct stat st; + CfgIncludeLevel *level; + gchar *filename; + + if (self->include_depth >= MAX_INCLUDE_DEPTH - 1) + { + msg_error("Include file depth is too deep, increase MAX_INCLUDE_DEPTH and recompile", + evt_tag_str("filename", filename_), + evt_tag_int("depth", self->include_depth), + NULL); + return FALSE; + } + + filename = find_file_in_path(cfg_args_get(self->globals, "include-path"), filename_, G_FILE_TEST_EXISTS); + if (!filename || stat(filename, &st) < 0) + { + msg_error("Include file/directory not found", + evt_tag_str("filename", filename_), + evt_tag_str("include-path", cfg_args_get(self->globals, "include-path")), + evt_tag_errno("error", errno), + NULL); + return FALSE; + } + else + return cfg_lexer_include_file_simple(self, filename); +} + +gboolean cfg_lexer_include_buffer(CfgLexer *self, const gchar *name, gchar *buffer, gsize length) { CfgIncludeLevel *level; -- 1.7.9
Both for distributions and otherwise, the ability to limit what kind of files are included, especially when doing a directory include is very important. This patch implements just that, by extending cfg_lexer_include_file() to try and resolve globs, if it can't find a file otherwise. Files included this way still respect the global include-path setting, so @include "foo.d/*.conf" will still work. Signed-off-by: Gergely Nagy <algernon@balabit.hu> --- lib/cfg-lexer.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 49 insertions(+), 0 deletions(-) diff --git a/lib/cfg-lexer.c b/lib/cfg-lexer.c index cfe229f..9469cbf 100644 --- a/lib/cfg-lexer.c +++ b/lib/cfg-lexer.c @@ -31,6 +31,7 @@ #include "misc.h" #include <string.h> +#include <glob.h> #include <sys/stat.h> struct _CfgArgs @@ -478,6 +479,51 @@ cfg_lexer_include_file_simple(CfgLexer *self, gchar *filename) return FALSE; } +static gboolean +cfg_lexer_include_file_glob_at(CfgLexer *self, const gchar *pattern) +{ + glob_t globbuf; + size_t i; + gboolean status = FALSE; + + if (glob(pattern, 0, NULL, &globbuf) != 0) + return FALSE; + + for (i = 0; i < globbuf.gl_pathc; i++) + status |= cfg_lexer_include_file(self, globbuf.gl_pathv[i]); + + globfree(&globbuf); + + return status; +} + +static gboolean +cfg_lexer_include_file_glob(CfgLexer *self, const gchar *filename_) +{ + const gchar *path = cfg_args_get(self->globals, "include-path"); + + if (filename_[0] == '/' || !path) + return cfg_lexer_include_file_glob_at(self, filename_); + else + { + gchar **dirs; + gchar *cf; + gint i = 0; + gboolean status = FALSE; + + dirs = g_strsplit(path, G_SEARCHPATH_SEPARATOR_S, 0); + while (dirs && dirs[i]) + { + cf = g_build_filename(dirs[i], filename_, NULL); + status |= cfg_lexer_include_file_glob_at(self, cf); + g_free(cf); + i++; + } + g_strfreev(dirs); + return status; + } +} + gboolean cfg_lexer_include_file(CfgLexer *self, const gchar *filename_) { @@ -497,6 +543,9 @@ cfg_lexer_include_file(CfgLexer *self, const gchar *filename_) filename = find_file_in_path(cfg_args_get(self->globals, "include-path"), filename_, G_FILE_TEST_EXISTS); if (!filename || stat(filename, &st) < 0) { + if (cfg_lexer_include_file_glob(self, filename_)) + return TRUE; + msg_error("Include file/directory not found", evt_tag_str("filename", filename_), evt_tag_str("include-path", cfg_args_get(self->globals, "include-path")), -- 1.7.9
@include "dir/" does not treat an empty directory as an error, nor should @include "*pattern*" error out if it found no matches. Signed-off-by: Gergely Nagy <algernon@balabit.hu> --- lib/cfg-lexer.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-) diff --git a/lib/cfg-lexer.c b/lib/cfg-lexer.c index 9469cbf..5badde1 100644 --- a/lib/cfg-lexer.c +++ b/lib/cfg-lexer.c @@ -485,8 +485,13 @@ cfg_lexer_include_file_glob_at(CfgLexer *self, const gchar *pattern) glob_t globbuf; size_t i; gboolean status = FALSE; + int r; - if (glob(pattern, 0, NULL, &globbuf) != 0) + r = glob(pattern, 0, NULL, &globbuf); + + if (r == GLOB_NOMATCH) + return TRUE; + if (r != 0) return FALSE; for (i = 0; i < globbuf.gl_pathc; i++) -- 1.7.9
Hi, See my notes in the bugzilla, about this one. A slightly changed version was commited and the 4 patches were folded into two. commit 7fdca91fd9c1aae5c9d0aa97a732cef32970aa15 Author: Gergely Nagy <algernon@balabit.hu> Date: Fri Mar 30 11:42:07 2012 +0200 cfg-lexer: Implement glob-based @include. Both for distributions and otherwise, the ability to limit what kind of files are included, especially when doing a directory include is very important. This patch implements just that, by extending cfg_lexer_include_file() to try and resolve globs, if it can't find a file otherwise. Files included this way still respect the global include-path setting, so @include "foo.d/*.conf" will still work. Signed-off-by: Gergely Nagy <algernon@balabit.hu> commit fe5f2b89e0c49dfd7d9a89c55304cb205da253ea Author: Balazs Scheidler <bazsi@balabit.hu> Date: Sat Mar 31 21:59:39 2012 +0200 cfg-lexer: Split cfg_lexer_include_file() into two functions To be able to keep the code simple in the future, split cfg_lexer_include_file() into two: the intent is that we'll check if the file exists, and if not, try the same thing as a glob, otherwise continue as we did before. This would nest too deep, so split out the current bulk into a separate function. Signed-off-by: Gergely Nagy <algernon@balabit.hu> Signed-off-by: Balazs Scheidler <bazsi@balabit.hu> On Fri, 2012-03-30 at 11:46 +0200, Gergely Nagy wrote:
To be able to keep the code simple in the future, split cfg_lexer_include_file() into two: the intent is that we'll check if the file exists, and if not, try the same thing as a glob, otherwise continue as we did before.
This would nest too deep, so split out the current bulk into a separate function.
Signed-off-by: Gergely Nagy <algernon@balabit.hu> --- lib/cfg-lexer.c | 59 +++++++++++++++++++++++++++++++++++------------------- 1 files changed, 38 insertions(+), 21 deletions(-)
diff --git a/lib/cfg-lexer.c b/lib/cfg-lexer.c index 6143a27..cfe229f 100644 --- a/lib/cfg-lexer.c +++ b/lib/cfg-lexer.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2002-2010 BalaBit IT Ltd, Budapest, Hungary - * Copyright (c) 1998-2010 Balázs Scheidler + * Copyright (c) 2002-2012 BalaBit IT Ltd, Budapest, Hungary + * Copyright (c) 1998-2012 Balázs Scheidler * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -379,32 +379,18 @@ cfg_lexer_start_next_include(CfgLexer *self) return TRUE; }
-gboolean -cfg_lexer_include_file(CfgLexer *self, const gchar *filename_) +static gboolean +cfg_lexer_include_file_simple(CfgLexer *self, gchar *filename) { - struct stat st; CfgIncludeLevel *level; - gchar *filename; + struct stat st;
- if (self->include_depth >= MAX_INCLUDE_DEPTH - 1) + if (stat(filename, &st) < 0) { - msg_error("Include file depth is too deep, increase MAX_INCLUDE_DEPTH and recompile", - evt_tag_str("filename", filename_), - evt_tag_int("depth", self->include_depth), - NULL); + g_free(filename); return FALSE; }
- filename = find_file_in_path(cfg_args_get(self->globals, "include-path"), filename_, G_FILE_TEST_EXISTS); - if (!filename || stat(filename, &st) < 0) - { - msg_error("Include file/directory not found", - evt_tag_str("filename", filename_), - evt_tag_str("include-path", cfg_args_get(self->globals, "include-path")), - evt_tag_errno("error", errno), - NULL); - return FALSE; - } self->include_depth++; level = &self->include_stack[self->include_depth]; level->include_type = CFGI_FILE; @@ -488,10 +474,41 @@ cfg_lexer_include_file(CfgLexer *self, const gchar *filename_) g_slist_foreach(level->file.files, (GFunc) g_free, NULL); g_slist_free(level->file.files); level->file.files = NULL; + return FALSE; }
gboolean +cfg_lexer_include_file(CfgLexer *self, const gchar *filename_) +{ + struct stat st; + CfgIncludeLevel *level; + gchar *filename; + + if (self->include_depth >= MAX_INCLUDE_DEPTH - 1) + { + msg_error("Include file depth is too deep, increase MAX_INCLUDE_DEPTH and recompile", + evt_tag_str("filename", filename_), + evt_tag_int("depth", self->include_depth), + NULL); + return FALSE; + } + + filename = find_file_in_path(cfg_args_get(self->globals, "include-path"), filename_, G_FILE_TEST_EXISTS); + if (!filename || stat(filename, &st) < 0) + { + msg_error("Include file/directory not found", + evt_tag_str("filename", filename_), + evt_tag_str("include-path", cfg_args_get(self->globals, "include-path")), + evt_tag_errno("error", errno), + NULL); + return FALSE; + } + else + return cfg_lexer_include_file_simple(self, filename); +} + +gboolean cfg_lexer_include_buffer(CfgLexer *self, const gchar *name, gchar *buffer, gsize length) { CfgIncludeLevel *level;
-- Bazsi
participants (2)
-
Balazs Scheidler
-
Gergely Nagy