Commit Diff


commit - 6beb0fad3ff09ae92a7aea0e4b8ad7b00fe2e26d
commit + f206fda8ae14e9c76e3dca6aa67412d5ae9ee9f7
blob - 822fd5d4fb9dd5b99f2694b5be98ce88075c68c5
blob + 31333ec2c7265cb40253a2e63291c781a2d47c90
--- doc/sample-ngircd.conf.tmpl
+++ doc/sample-ngircd.conf.tmpl
@@ -166,6 +166,10 @@
 	# Users identified using IDENT are registered without the "~" character
 	# prepended to their user name.
 	;Ident = yes
+
+	# Directory containing configuration snippets (*.conf), that should
+	# be read in after parsing this configuration file.
+	;IncludeDir = :ETCDIR:/conf.d
 
 	# Enhance user privacy slightly (useful for IRC server on TOR or I2P)
 	# by censoring some information like idle time, logon time, etc.
blob - e5485dbf10edddc2c7c0532b79902bd696fedbc4
blob + 64acd9273456f7d12dc2dba4de5ba8eb5f041bc9
--- man/ngircd.conf.5.tmpl
+++ man/ngircd.conf.5.tmpl
@@ -1,7 +1,7 @@
 .\"
 .\" ngircd.conf(5) manual page template
 .\"
-.TH ngircd.conf 5 "Feb 2013" ngIRCd "ngIRCd Manual"
+.TH ngircd.conf 5 "May 2013" ngIRCd "ngIRCd Manual"
 .SH NAME
 ngircd.conf \- configuration file of ngIRCd
 .SH SYNOPSIS
@@ -265,6 +265,11 @@ Users identified using IDENT are registered without th
 prepended to their user name.
 Default: yes.
 .TP
+.TP
+\fBIncludeDir\fR (string)
+Directory containing configuration snippets (*.conf), that should be read in
+after parsing the current configuration file.
+Default: none.
 \fBMorePrivacy\fR (boolean)
 This will cause ngIRCd to censor user idle time, logon time as well as the
 part/quit messages (that are sometimes used to inform everyone about which
blob - eee1925555abbe8d05a7a3cc4ba85dfced474945
blob + d7e1a1542b327ccd2992ff91ad6d13edaa77fe67
--- src/ngircd/conf.c
+++ src/ngircd/conf.c
@@ -34,8 +34,8 @@
 #include <grp.h>
 #include <sys/types.h>
 #include <unistd.h>
+#include <dirent.h>
 
-
 #include "array.h"
 #include "ngircd.h"
 #include "conn.h"
@@ -55,6 +55,7 @@ static int New_Server_Idx;
 
 static char Conf_MotdFile[FNAME_LEN];
 static char Conf_HelpFile[FNAME_LEN];
+static char Conf_IncludeDir[FNAME_LEN];
 
 static void Set_Defaults PARAMS(( bool InitServers ));
 static bool Read_Config PARAMS(( bool TestOnly, bool IsStarting ));
@@ -404,6 +405,7 @@ Conf_Test( void )
 #ifdef IDENT
 	printf("  Ident = %s\n", yesno_to_str(Conf_Ident));
 #endif
+	printf("  IncludeDir = %s\n", Conf_IncludeDir);
 	printf("  MorePrivacy = %s\n", yesno_to_str(Conf_MorePrivacy));
 	printf("  NoticeAuth = %s\n", yesno_to_str(Conf_NoticeAuth));
 	printf("  OperCanUseMode = %s\n", yesno_to_str(Conf_OperCanMode));
@@ -778,6 +780,7 @@ Set_Defaults(bool InitServers)
 #else
 	Conf_Ident = false;
 #endif
+	strcpy(Conf_IncludeDir, "");
 	Conf_MorePrivacy = false;
 	Conf_NoticeAuth = false;
 	Conf_OperCanMode = false;
@@ -876,8 +879,11 @@ static bool
 Read_Config(bool TestOnly, bool IsStarting)
 {
 	const UINT16 defaultport = 6667;
+	char *ptr, file[FNAME_LEN];
+	struct dirent *entry;
 	int i, n;
 	FILE *fd;
+	DIR *dh;
 
 	/* Open configuration file */
 	fd = fopen( NGIRCd_ConfFile, "r" );
@@ -938,9 +944,37 @@ Read_Config(bool TestOnly, bool IsStarting)
 #endif
 
 	Read_Config_File(NGIRCd_ConfFile, fd);
+	fclose(fd);
 
-	/* Close configuration file */
-	fclose( fd );
+	if (Conf_IncludeDir[0]) {
+		/* Include further configuration files, if any */
+		dh = opendir(Conf_IncludeDir);
+		if (dh) {
+			while ((entry = readdir(dh)) != NULL) {
+				ptr = strrchr(entry->d_name, '.');
+				if (!ptr || strcasecmp(ptr, ".conf") != 0)
+					continue;
+				snprintf(file, sizeof(file), "%s/%s",
+					 Conf_IncludeDir, entry->d_name);
+				if (TestOnly)
+					Config_Error(LOG_INFO,
+						     "Reading configuration from \"%s\" ...",
+						     file);
+				fd = fopen(file, "r");
+				if (fd) {
+					Read_Config_File(file, fd);
+					fclose(fd);
+				} else
+					Config_Error(LOG_ALERT,
+						     "Can't read configuration \"%s\": %s",
+						     file, strerror(errno));
+			}
+			closedir(dh);
+		} else
+			Config_Error(LOG_ALERT,
+				     "Can't open include directory \"%s\": %s",
+				     Conf_IncludeDir, strerror(errno));
+	}
 
 	/* Check if there is still a server to add */
 	if( New_Server.name[0] ) {
@@ -999,6 +1033,7 @@ static void Read_Config_File(const char *File, FILE *f
 	size_t count;
 
 	/* Read configuration file */
+	section[0] = '\0';
 	while (true) {
 		if (!fgets(str, LINE_LEN, fd))
 			break;
@@ -1648,6 +1683,12 @@ Handle_OPTIONS(const char *File, int Line, char *Var, 
 		WarnIdent(Line);
 		return;
 	}
+	if (strcasecmp(Var, "IncludeDir") == 0) {
+		len = strlcpy(Conf_IncludeDir, Arg, sizeof(Conf_IncludeDir));
+		if (len >= sizeof(Conf_IncludeDir))
+			Config_Error_TooLong(File, Line, Var);
+		return;
+	}
 	if (strcasecmp(Var, "MorePrivacy") == 0) {
 		Conf_MorePrivacy = Check_ArgIsTrue(Arg);
 		return;