Ignore that last patch. It has a wrong indentation in an if block.

Index: httpd.conf.5
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/httpd.conf.5,v
retrieving revision 1.121
diff -u -p -u -p -r1.121 httpd.conf.5
--- httpd.conf.5	9 Mar 2022 13:50:41 -0000	1.121
+++ httpd.conf.5	2 Jun 2022 11:02:21 -0000
@@ -84,6 +84,12 @@ keyword, for example:
 .Bd -literal -offset indent
 include "/etc/httpd.conf.local"
 .Ed
+A directory with configuration files can be included with the
+.Ic include_dir
+keyword, for example:
+.Bd -literal -offset indent
+include_dir "directory"
+.Ed
 .Sh MACROS
 Macros can be defined that will later be expanded in context.
 Macro names must start with a letter, digit, or underscore,
Index: parse.y
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/parse.y,v
retrieving revision 1.128
diff -u -p -u -p -r1.128 parse.y
--- parse.y	27 Feb 2022 20:30:30 -0000	1.128
+++ parse.y	2 Jun 2022 11:02:21 -0000
@@ -52,6 +52,7 @@
 #include <string.h>
 #include <ifaddrs.h>
 #include <syslog.h>
+#include <dirent.h>
 
 #include "httpd.h"
 #include "http.h"
@@ -139,7 +140,7 @@ typedef struct {
 %token	LISTEN LOCATION LOG LOGDIR MATCH MAXIMUM NO NODELAY OCSP ON PORT PREFORK
 %token	PROTOCOLS REQUESTS ROOT SACK SERVER SOCKET STRIP STYLE SYSLOG TCP TICKET
 %token	TIMEOUT TLS TYPE TYPES HSTS MAXAGE SUBDOMAINS DEFAULT PRELOAD REQUEST
-%token	ERROR INCLUDE AUTHENTICATE WITH BLOCK DROP RETURN PASS REWRITE
+%token	ERROR INCLUDE INCLUDE_DIR AUTHENTICATE WITH BLOCK DROP RETURN PASS REWRITE
 %token	CA CLIENT CRL OPTIONAL PARAM FORWARDED FOUND NOT
 %token	ERRDOCS GZIPSTATIC
 %token	<v.string>	STRING
@@ -155,6 +156,7 @@ typedef struct {
 
 grammar		: /* empty */
 		| grammar include '\n'
+		| grammar include_dir '\n'
 		| grammar '\n'
 		| grammar varset '\n'
 		| grammar main '\n'
@@ -165,7 +167,6 @@ grammar		: /* empty */
 
 include		: INCLUDE STRING		{
 			struct file	*nfile;
-
 			if ((nfile = pushfile($2, 0)) == NULL) {
 				yyerror("failed to include file %s", $2);
 				free($2);
@@ -178,6 +179,48 @@ include		: INCLUDE STRING		{
 		}
 		;
 
+include_dir     : INCLUDE_DIR STRING {
+			char absolute_path[PATH_MAX];
+			char dir[PATH_MAX];
+			struct file *nfile;
+			DIR *opened_dir;
+			opened_dir = openddir($2);
+			struct dirent *entry;
+			size_t len = 0;
+
+			if(opened_dir == NULL) {
+				free($2);
+				yyerror("Failed to open directory %s", $2);
+				YYERROR;
+			}
+
+			len = strlcpy(dir, $2, PATH_MAX);
+
+			if(len >= sizeof(dir)) {
+			  free($2);
+				yyerror("too long");
+				YYERROR;
+			}
+
+			while((entry = readdir(opened_dir))) {
+				  if(entry->d_name[0] == '.')
+					continue;
+				len = snprintf(absolute_path, PATH_MAX, "%s%s", dir, entry->d_name);
+				if(len < 0 || len >= sizeof(absolute_path)) {
+					yyerror("too long");
+					YYERROR;
+				}
+				if((nfile = pushfile(absolute_path, 0)) == NULL) {
+					yyerror("failed to include file %s", $2);
+					YYERROR;
+				}
+			}
+
+			file = nfile;
+			lungetc('\n');
+}
+;
+
 varset		: STRING '=' STRING	{
 			char *s = $1;
 			while (*s++) {
@@ -1453,6 +1496,7 @@ lookup(char *s)
 		{ "gzip-static",	GZIPSTATIC },
 		{ "hsts",		HSTS },
 		{ "include",		INCLUDE },
+		{ "include_dir",	INCLUDE_DIR},
 		{ "index",		INDEX },
 		{ "ip",			IP },
 		{ "key",		KEY },

Reply via email to