Module: ngircd.git Branch: master Commit: f206fda8ae14e9c76e3dca6aa67412d5ae9ee9f7 URL: http://ngircd.barton.de/cgi-bin/gitweb.cgi?p=ngircd.git&a=commit;h=f206f...
Author: Alexander Barton alex@barton.de Date: Fri May 24 22:29:41 2013 +0200
Implement new configuration option "IncludeDir"
The option "IncludeDir" in the [Options] section can be used to specify a directory which can contain further configuration files and configuration file snippets matching the pattern "*.conf" that should be read in after the main configuration file ("ngircd.conf" by default) has been parsed.
Closes bug #157.
---
doc/sample-ngircd.conf.tmpl | 4 ++++ man/ngircd.conf.5.tmpl | 7 ++++++- src/ngircd/conf.c | 49 +++++++++++++++++++++++++++++++++++++++---- 3 files changed, 55 insertions(+), 5 deletions(-)
diff --git a/doc/sample-ngircd.conf.tmpl b/doc/sample-ngircd.conf.tmpl index 822fd5d..31333ec 100644 --- a/doc/sample-ngircd.conf.tmpl +++ b/doc/sample-ngircd.conf.tmpl @@ -167,6 +167,10 @@ # 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. ;MorePrivacy = no diff --git a/man/ngircd.conf.5.tmpl b/man/ngircd.conf.5.tmpl index e5485db..64acd92 100644 --- a/man/ngircd.conf.5.tmpl +++ b/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 the "~" character 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 diff --git a/src/ngircd/conf.c b/src/ngircd/conf.c index eee1925..d7e1a15 100644 --- a/src/ngircd/conf.c +++ b/src/ngircd/conf.c @@ -34,7 +34,7 @@ #include <grp.h> #include <sys/types.h> #include <unistd.h> - +#include <dirent.h>
#include "array.h" #include "ngircd.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); - - /* Close configuration file */ - fclose( fd ); + 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 *fd) 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, char *Arg) 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;