From: Alexander Barton Date: Fri, 24 May 2013 20:29:41 +0000 (+0200) Subject: Implement new configuration option "IncludeDir" X-Git-Tag: rel-21-rc1~99 X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=commitdiff_plain;h=f206fda8ae14e9c76e3dca6aa67412d5ae9ee9f7 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. --- diff --git a/doc/sample-ngircd.conf.tmpl b/doc/sample-ngircd.conf.tmpl index 822fd5d4..31333ec2 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 e5485dbf..64acd927 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 eee19255..d7e1a154 100644 --- a/src/ngircd/conf.c +++ b/src/ngircd/conf.c @@ -34,7 +34,7 @@ #include #include #include - +#include #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;