diff -Naur unbound-1.4.18-orig/util/config_file.c unbound-1.4.18/util/config_file.c --- unbound-1.4.18-orig/util/config_file.c 2012-06-18 10:22:29.000000000 -0400 +++ unbound-1.4.18/util/config_file.c 2012-09-26 00:45:37.509190970 -0400 @@ -53,6 +53,10 @@ #include "util/regional.h" #include "util/fptr_wlist.h" #include "util/data/dname.h" +#ifdef HAVE_GLOB_H +# include +#endif + /** global config during parsing */ struct config_parser_state* cfg_parser = 0; /** lex in file */ @@ -689,6 +693,65 @@ char *fname = (char*)filename; if(!fname) return 1; + + /* check for wildcards */ +#ifdef HAVE_GLOB + glob_t g; + size_t i; + int r, flags; + if(!(!strchr(fname, '*') && !strchr(fname, '?') && !strchr(fname, '[') && + !strchr(fname, '{') && !strchr(fname, '~'))) { + verbose(VERB_QUERY, "wildcard found, processing %s", fname); + flags = 0 +#ifdef GLOB_ERR + | GLOB_ERR +#endif +#ifdef GLOB_NOSORT + | GLOB_NOSORT +#endif +#ifdef GLOB_BRACE + | GLOB_BRACE +#endif +#ifdef GLOB_TILDE + | GLOB_TILDE +#endif + ; + memset(&g, 0, sizeof(g)); + r = glob(fname, flags, NULL, &g); + if(r) { + /* some error */ + if(r == GLOB_NOMATCH) { + verbose(VERB_QUERY, "include: " + "no matches for %s", fname); + return 1; + } else if(r == GLOB_NOSPACE) { + log_err("include: %s: " + "fnametern out of memory", fname); + } else if(r == GLOB_ABORTED) { + log_err("wildcard include: %s: expansion " + "aborted (%s)", fname, strerror(errno)); + } else { + log_err("wildcard include: %s: expansion " + "failed (%s)", fname, strerror(errno)); + } + /* ignore globs that yield no files */ + return 1; + } + /* process files found, if any */ + for(i=0; i<(size_t)g.gl_pathc; i++) { + if(!config_read(cfg, g.gl_pathv[i], chroot)) { + log_err("error reading wildcard " + "include: %s", g.gl_pathv[i]); + globfree(&g); + return 0; + } + } + globfree(&g); + return 1; + } +#endif + + in = fopen(fname, "r"); if(!in) { log_err("Could not open %s: %s", fname, strerror(errno)); diff -Naur unbound-1.4.18-orig/util/configlexer.c unbound-1.4.18/util/configlexer.c --- unbound-1.4.18-orig/util/configlexer.c 2012-08-02 03:26:14.000000000 -0400 +++ unbound-1.4.18/util/configlexer.c 2012-09-26 00:47:40.856511450 -0400 @@ -22,6 +22,10 @@ #include #include #include +#ifdef HAVE_GLOB_H +# include +#endif + /* end standard C headers. */ @@ -1827,7 +1831,7 @@ } input = fopen(filename, "r"); if(!input) { - ub_c_error_msg("cannot open include file '%s': %s", + ub_c_error_msg("(c)cannot open include file '%s': %s", filename, strerror(errno)); return; } @@ -1841,6 +1845,46 @@ ++config_include_stack_ptr; } +static void config_start_include_glob(const char* filename) +{ +#ifdef HAVE_GLOB + glob_t g; + size_t i; + int r, flags; + if(!(!strchr(filename, '*') && !strchr(filename, '?') && !strchr(filename, '[') && + !strchr(filename, '{') && !strchr(filename, '~'))) { + /* verbose(VERB_QUERY, "wildcard found, processing %s", filename); */ + flags = 0 +#ifdef GLOB_ERR + | GLOB_ERR +#endif +#ifdef GLOB_NOSORT + | GLOB_NOSORT +#endif +#ifdef GLOB_BRACE + | GLOB_BRACE +#endif +#ifdef GLOB_TILDE + | GLOB_TILDE +#endif + ; + memset(&g, 0, sizeof(g)); + r = glob(filename, flags, NULL, &g); + if(r) { + /* some error */ + return; + } + /* process files found, if any */ + for(i=0; i<(size_t)g.gl_pathc; i++) { + config_start_include(g.gl_pathv[i]); + } + globfree(&g); + return; + } +#endif + config_start_include(filename); +} + static void config_end_include(void) { --config_include_stack_ptr; @@ -2875,7 +2919,7 @@ #line 300 "util/configlexer.lex" { LEXOUT(("Iunquotedstr(%s) ", yytext)); - config_start_include(yytext); + config_start_include_glob(yytext); BEGIN(inc_prev); } YY_BREAK @@ -2904,7 +2948,7 @@ { LEXOUT(("IQE ")); yytext[yyleng - 1] = '\0'; - config_start_include(yytext); + config_start_include_glob(yytext); BEGIN(inc_prev); } YY_BREAK diff -Naur unbound-1.4.18-orig/util/configlexer.lex unbound-1.4.18/util/configlexer.lex --- unbound-1.4.18-orig/util/configlexer.lex 2012-04-10 05:16:39.000000000 -0400 +++ unbound-1.4.18/util/configlexer.lex 2012-09-26 00:46:59.135064805 -0400 @@ -11,6 +11,9 @@ #include #include #include +#ifdef HAVE_GLOB_H +# include +#endif #include "util/config_file.h" #include "util/configparser.h" @@ -43,6 +46,7 @@ static int inc_prev = 0; static int num_args = 0; + static void config_start_include(const char* filename) { FILE *input; @@ -60,7 +64,7 @@ } input = fopen(filename, "r"); if(!input) { - ub_c_error_msg("cannot open include file '%s': %s", + ub_c_error_msg("(lex)cannot open include file '%s': %s", filename, strerror(errno)); return; } @@ -74,6 +78,48 @@ ++config_include_stack_ptr; } +static void config_start_include_glob(const char* filename) +{ + + /* check for wildcards */ +#ifdef HAVE_GLOB + glob_t g; + size_t i; + int r, flags; + if(!(!strchr(filename, '*') && !strchr(filename, '?') && !strchr(filename, '[') && + !strchr(filename, '{') && !strchr(filename, '~'))) { + /* verbose(VERB_QUERY, "wildcard found, processing %s", filename); */ + flags = 0 +#ifdef GLOB_ERR + | GLOB_ERR +#endif +#ifdef GLOB_NOSORT + | GLOB_NOSORT +#endif +#ifdef GLOB_BRACE + | GLOB_BRACE +#endif +#ifdef GLOB_TILDE + | GLOB_TILDE +#endif + ; + memset(&g, 0, sizeof(g)); + r = glob(filename, flags, NULL, &g); + if(r) { + /* some error */ + return config_start_include(filename); /* let original deal with it */ + } + /* process files found, if any */ + for(i=0; i<(size_t)g.gl_pathc; i++) { + config_start_include(g.gl_pathv[i]); + } + globfree(&g); + return 1; + } +#endif + + config_start_include(filename); +} static void config_end_include(void) { --config_include_stack_ptr; @@ -299,7 +345,7 @@ \" { LEXOUT(("IQS ")); BEGIN(include_quoted); } {UNQUOTEDLETTER}* { LEXOUT(("Iunquotedstr(%s) ", yytext)); - config_start_include(yytext); + config_start_include_glob(yytext); BEGIN(inc_prev); } <> { @@ -312,7 +358,7 @@ \" { LEXOUT(("IQE ")); yytext[yyleng - 1] = '\0'; - config_start_include(yytext); + config_start_include_glob(yytext); BEGIN(inc_prev); } <> {