Permalink
Browse files

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>
  • Loading branch information...
1 parent ce15af4 commit a1567ce7c320c42d65456b6b9123bdcfdecbde00 @algernon committed Mar 30, 2012
Showing with 54 additions and 0 deletions.
  1. +54 −0 lib/cfg-lexer.c
View
@@ -31,6 +31,7 @@
#include "misc.h"
#include <string.h>
+#include <glob.h>
#include <sys/stat.h>
struct _CfgArgs
@@ -474,6 +475,56 @@ cfg_lexer_include_file_simple(CfgLexer *self, const 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;
+ int r;
+
+ 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++)
+ 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_)
{
@@ -492,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")),

0 comments on commit a1567ce

Please sign in to comment.