If a string after "include" keyword points to a directory instead of a file, consider the directory to contain only nft rule files and try to load them all. This helps with a use case where services drop their own firewall configuration files into a directory and nft needs to include those without knowing the exact file names. Signed-off-by: Ismo Puustinen <ismo.puustinen@xxxxxxxxx> --- src/main.c | 4 ++-- src/scanner.l | 73 +++++++++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 61 insertions(+), 16 deletions(-) diff --git a/src/main.c b/src/main.c index 7bbcfc4..395bde2 100644 --- a/src/main.c +++ b/src/main.c @@ -36,8 +36,8 @@ unsigned int handle_output; unsigned int debug_level; #endif -const char *include_paths[INCLUDE_PATHS_MAX] = { DEFAULT_INCLUDE_PATH }; -static unsigned int num_include_paths = 1; +const char *include_paths[INCLUDE_PATHS_MAX] = { DEFAULT_INCLUDE_PATH, "." }; +static unsigned int num_include_paths = 2; enum opt_vals { OPT_HELP = 'h', diff --git a/src/scanner.l b/src/scanner.l index a0dee47..58ecd71 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -10,6 +10,8 @@ %{ +#include <dirent.h> +#include <libgen.h> #include <limits.h> #include <netinet/in.h> #include <arpa/inet.h> @@ -620,26 +622,69 @@ int scanner_include_file(void *scanner, const char *filename, f = NULL; for (i = 0; i < INCLUDE_PATHS_MAX; i++) { + DIR *directory = NULL; + if (include_paths[i] == NULL) break; snprintf(buf, sizeof(buf), "%s/%s", include_paths[i], filename); - f = fopen(buf, "r"); - if (f != NULL) + + directory = opendir(buf); + + if (directory == NULL && errno != ENOTDIR) { + /* Could not access the directory or file. */ + continue; + } + else if (directory != NULL) { + struct dirent *de; + + /* If the path is a directory, assume that all files there need + * to be included. */ + while ((de = readdir(directory))) { + char dirbuf[PATH_MAX]; + + snprintf(dirbuf, sizeof(dirbuf), "%s/%s", buf, de->d_name); + + if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) + continue; + + f = fopen(dirbuf, "r"); + + if (f == NULL) { + erec = error(loc, "Could not open file \"%s\": %s\n", + filename, strerror(errno)); + closedir(directory); + goto err; + } + name = de->d_name; + + erec = scanner_push_file(scanner, name, f, loc); + if (erec != NULL) { + closedir(directory); + goto err; + } + } + + closedir(directory); break; - } - if (f == NULL) { - f = fopen(filename, "r"); - if (f == NULL) { - erec = error(loc, "Could not open file \"%s\": %s\n", - filename, strerror(errno)); - goto err; } - name = filename; - } + else { + /* A simple include file. */ + f = fopen(buf, "r"); + if (f == NULL) { + erec = error(loc, "Could not open file \"%s\": %s\n", + filename, strerror(errno)); + goto err; + } - erec = scanner_push_file(scanner, name, f, loc); - if (erec != NULL) - goto err; + if (strcmp(".", dirname(buf)) == 0) + name = filename; + + erec = scanner_push_file(scanner, name, f, loc); + if (erec != NULL) + goto err; + break; + } + } return 0; err: -- 2.5.0 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html