@@ -0,0 +1,151 @@
+From 82fc4b1f47e3de4900aed6b06168fdf8d81ea9de Mon Sep 17 00:00:00 2001
+From: Joe Gooch <mrwizard@k12system.com>
+Date: Tue, 2 Feb 2010 11:33:59 -0500
+Subject: IncludeDir directive - includes a directory of config files (a la conf.d)
+
+---
+ config.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ pound.8 | 9 ++++++++
+ pound.h | 1 +
+ 3 files changed, 75 insertions(+), 1 deletions(-)
+
+diff --git a/config.c b/config.c
+index 347ed67..722caca 100644
+--- a/config.c
++++ b/config.c
+@@ -78,7 +78,7 @@ static regex_t Service, ServiceName, URL, HeadRequire, HeadDeny, BackEnd, Emerg
+ static regex_t Redirect, RedirectN, TimeOut, Session, Type, TTL, ID, DynScale;
+ static regex_t ClientCert, AddHeader, Ciphers, CAlist, VerifyList, CRLlist, NoHTTPS11;
+ static regex_t ForceHTTP10, SSLUncleanShutdown;
+-static regex_t Grace, Include, ConnTO, IgnoreCase, HTTPS, HTTPSCert;
++static regex_t Grace, Include, IncludeDir, ConnTO, IgnoreCase, HTTPS, HTTPSCert;
+
+ static regmatch_t matches[5];
+
+@@ -128,6 +128,63 @@ conf_err(const char *msg)
+ exit(1);
+ }
+
++static void include_dir(const char *conf_path) {
++ DIR * dp;
++ struct dirent *de;
++
++ char buf[512];
++ char *files[200], *cp;
++ int filecnt = 0;
++ int idx,use;
++
++ logmsg(LOG_DEBUG, "Including Dir %s", conf_path);
++
++ if((dp = opendir(conf_path)) == NULL) {
++ conf_err("can't open IncludeDir directory");
++ exit(1);
++ }
++
++ while((de = readdir(dp))!=NULL) {
++ if (de->d_name[0] == '.') continue;
++ if ( (strlen(de->d_name) >= 5 && !strncmp(de->d_name + strlen(de->d_name) - 4, ".cfg", 4)) ||
++ (strlen(de->d_name) >= 6 && !strncmp(de->d_name + strlen(de->d_name) - 5, ".conf", 5))
++ ){
++ snprintf(buf, sizeof(buf), "%s%s%s", conf_path, (conf_path[strlen(conf_path)-1]=='/')?"":"/", de->d_name);
++ buf[sizeof(buf)-1] = 0;
++ if (filecnt == sizeof(files)/sizeof(*files)) {
++ conf_err("Max config files per directory reached");
++ }
++ if ((files[filecnt++] = strdup(buf)) == NULL) {
++ conf_err("IncludeDir out of memory");
++ }
++ continue;
++ }
++ }
++ /* We order the list, and include in reverse order, because include_file adds to the top of the list */
++ while(filecnt) {
++ use = 0;
++ for(idx = 1; idx<filecnt; idx++)
++ if (strcmp(files[use], files[idx])<0)
++ use=idx;
++
++ logmsg(LOG_DEBUG, " I==> %s", files[use]);
++
++ // Copied from Include logic
++ if(cur_fin == (MAX_FIN - 1))
++ conf_err("Include nesting too deep");
++ cur_fin++;
++ f_name[cur_fin] = files[use];
++ if((f_in[cur_fin] = fopen(files[use], "rt")) == NULL) {
++ logmsg(LOG_ERR, "%s line %d: Can't open included file %s", f_name[cur_fin], n_lin[cur_fin], files[use]);
++ exit(1);
++ }
++ n_lin[cur_fin] = 0;
++ files[use] = files[--filecnt];
++ }
++
++ closedir(dp);
++}
++
+ static char *
+ conf_fgets(char *buf, const int max)
+ {
+@@ -163,6 +220,11 @@ conf_fgets(char *buf, const int max)
+ n_lin[cur_fin] = 0;
+ continue;
+ }
++ if(!regexec(&IncludeDir, buf, 4, matches, 0)) {
++ buf[matches[1].rm_eo] = '\0';
++ include_dir(buf + matches[1].rm_so);
++ continue;
++ }
+ return buf;
+ }
+ }
+@@ -1195,6 +1257,7 @@ config_parse(const int argc, char **const argv)
+ || regcomp(&ForceHTTP10, "^[ \t]*ForceHTTP10[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
+ || regcomp(&SSLUncleanShutdown, "^[ \t]*SSLUncleanShutdown[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
+ || regcomp(&Include, "^[ \t]*Include[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
++ || regcomp(&IncludeDir, "^[ \t]*IncludeDir[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
+ || regcomp(&ConnTO, "^[ \t]*ConnTO[ \t]+([1-9][0-9]*)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
+ || regcomp(&IgnoreCase, "^[ \t]*IgnoreCase[ \t]+([01])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
+ || regcomp(&HTTPS, "^[ \t]*HTTPS[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
+@@ -1352,6 +1415,7 @@ config_parse(const int argc, char **const argv)
+ regfree(&ForceHTTP10);
+ regfree(&SSLUncleanShutdown);
+ regfree(&Include);
++ regfree(&IncludeDir);
+ regfree(&ConnTO);
+ regfree(&IgnoreCase);
+ regfree(&HTTPS);
+diff --git a/pound.8 b/pound.8
+index 930050c..c2235f4 100644
+--- a/pound.8
++++ b/pound.8
+@@ -190,6 +190,15 @@ directives (they affect only a specific group of requests).
+ Global directives may appear anywhere within the configuration file, though it is
+ customary for them to be at the start. They may appear in any order.
+ .TP
++\fBInclude\fR "file"
++Includes another configuration file inline, as if it were part of the top config file.
++This directive can be used in any block... but the result must be syntactically correct.
++.TP
++\fBIncludeDir\fR "path"
++Looks for files with conf or cfg extensions in "path", and includes all files, in sorted
++order, inline in the configuration as if it were part of the to pconfiguration file.
++This directive can be used in any block... but the result must be syntactically correct.
++.TP
+ \fBUser\fR "user_name"
+ Specify the user
+ .B Pound
+diff --git a/pound.h b/pound.h
+index 10365d6..371bdb8 100644
+--- a/pound.h
++++ b/pound.h
+@@ -29,6 +29,7 @@
+ #include <stdio.h>
+ #include <math.h>
+
++#include <dirent.h>
+ #if HAVE_STDLIB_H
+ #include <stdlib.h>
+ #else
+--
+1.6.0.2
+
|