commit 056de78e315a79edc1166649514bf8dfeb18abb1 from: Florian Westphal date: Thu Aug 12 19:46:47 2010 UTC ngircd: change MOTD file handling previously, the given MotdFile file was read whenever a client requested it. Change handling to read the MotdFile contents into memory once during config file parsing. Two side effects: - changes to the MOTD file do not have any effect until ngircds configuration is reloaded - MOTD file does no longer have to reside in the chroot directory (the MOTD contents will then not be re-read on reload in that case) commit - a02bc9cc6f821a604f6ae4a865b0da8eec4da5a4 commit + 056de78e315a79edc1166649514bf8dfeb18abb1 blob - 645d1b8afbc525fef0d689f9c36b801bff67db5f blob + fdeed355bab93d257a42cfc6007388fbbdb311a4 --- doc/sample-ngircd.conf +++ doc/sample-ngircd.conf @@ -73,7 +73,6 @@ ;MotdFile = /usr/local/etc/ngircd.motd # A simple Phrase (<256 chars) if you don't want to use a motd file. - # If it is set no MotdFile will be read at all. ;MotdPhrase = "Hello world!" # User ID under which the server should run; you can use the name blob - ad888713ee7d0ee310404b15c02211ff7bd6c20a blob + 71aaa1e0e2e89601739a0c109724f6301e9d57e3 --- man/ngircd.conf.5.tmpl +++ man/ngircd.conf.5.tmpl @@ -118,12 +118,11 @@ IP addresses and interfaces by default. .TP \fBMotdFile\fR Text file with the "message of the day" (MOTD). This message will be shown -to all users connecting to the server. +to all users connecting to the server. Changes made to this file +take effect when ngircd is instructed to re-read its configuration file. .TP \fBMotdPhrase\fR A simple Phrase (<256 chars) if you don't want to use a MOTD file. -If this variable is set, no \fBMotdFile\fR will be read at all which can be -handy if the daemon should run inside a chroot directory. .TP \fBServerUID\fR User ID under which the server should run; you can use the name of the user blob - 834a1da330e989300993d5377bf6c8b726119ce5 blob + a70973e78cf8b47d33eeac5cb54a27f8388e4fef --- src/ngircd/conf.c +++ src/ngircd/conf.c @@ -55,6 +55,8 @@ static int New_Server_Idx; static size_t Conf_Oper_Count; static size_t Conf_Channel_Count; +static char Conf_MotdFile[FNAME_LEN]; + static void Set_Defaults PARAMS(( bool InitServers )); static bool Read_Config PARAMS(( bool ngircd_starting )); static bool Validate_Config PARAMS(( bool TestOnly, bool Rehash )); @@ -299,7 +301,7 @@ Conf_Test( void ) printf(" AdminInfo2 = %s\n", Conf_ServerAdmin2); printf(" AdminEMail = %s\n", Conf_ServerAdminMail); printf(" MotdFile = %s\n", Conf_MotdFile); - printf(" MotdPhrase = %s\n", Conf_MotdPhrase); + printf(" MotdPhrase = %.32s\n", array_bytes(&Conf_Motd) ? (const char*) array_start(&Conf_Motd) : ""); printf(" ChrootDir = %s\n", Conf_Chroot); printf(" PidFile = %s\n", Conf_PidFile); printf(" Listen = %s\n", Conf_ListenAddress); @@ -567,7 +569,6 @@ Set_Defaults(bool InitServers) strlcpy(Conf_MotdFile, SYSCONFDIR, sizeof(Conf_MotdFile)); strlcat(Conf_MotdFile, MOTD_FILE, sizeof(Conf_MotdFile)); - strlcpy(Conf_MotdPhrase, MOTD_PHRASE, sizeof(Conf_MotdPhrase)); Conf_UID = Conf_GID = 0; strlcpy(Conf_Chroot, CHROOT_DIR, sizeof(Conf_Chroot)); @@ -617,6 +618,36 @@ no_listenports(void) return cnt == 0; } +static void +Read_Motd(const char *filename) +{ + char line[127]; + FILE *fp; + + if (*filename == '\0') + return; + + fp = fopen(filename, "r"); + if (!fp) { + Log(LOG_WARNING, "Can't read MOTD file \"%s\": %s", + filename, strerror(errno)); + return; + } + + array_free(&Conf_Motd); + + while (fgets(line, (int)sizeof line, fp)) { + ngt_TrimLastChr( line, '\n'); + + /* add text including \0 */ + if (!array_catb(&Conf_Motd, line, strlen(line) + 1)) { + Log(LOG_WARNING, "Cannot add MOTD text: %s", strerror(errno)); + break; + } + } + fclose(fp); +} + static bool Read_Config( bool ngircd_starting ) { @@ -780,6 +811,10 @@ Read_Config( bool ngircd_starting ) Config_Error(LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME); exit(1); } + + /* No MOTD phrase configured? (re)try motd file. */ + if (array_bytes(&Conf_Motd) == 0) + Read_Motd(Conf_MotdFile); return true; } /* Read_Config */ @@ -816,6 +851,7 @@ static unsigned int Handle_MaxNickLength(int Line, con } /* Handle_MaxNickLength */ + static void Handle_GLOBAL( int Line, char *Var, char *Arg ) { @@ -882,17 +918,24 @@ Handle_GLOBAL( int Line, char *Var, char *Arg ) return; } if( strcasecmp( Var, "MotdFile" ) == 0 ) { - /* "Message of the day" (MOTD) file */ len = strlcpy( Conf_MotdFile, Arg, sizeof( Conf_MotdFile )); if (len >= sizeof( Conf_MotdFile )) Config_Error_TooLong( Line, Var ); + Read_Motd(Arg); return; } if( strcasecmp( Var, "MotdPhrase" ) == 0 ) { /* "Message of the day" phrase (instead of file) */ - len = strlcpy( Conf_MotdPhrase, Arg, sizeof( Conf_MotdPhrase )); - if (len >= sizeof( Conf_MotdPhrase )) + len = strlen(Arg); + if (len == 0) + return; + if (len >= LINE_LEN) { Config_Error_TooLong( Line, Var ); + return; + } + if (!array_copyb(&Conf_Motd, Arg, len + 1)) + Config_Error(LOG_WARNING, "%s, line %d: Could not append MotdPhrase: %s", + NGIRCd_ConfFile, Line, strerror(errno)); return; } if( strcasecmp( Var, "ChrootDir" ) == 0 ) { blob - 74abc1d95010d889ba626f76c836abcc8fc7db14 blob + e7b84d2e16facd41000109629c2939b56c6a9940 --- src/ngircd/conf.h +++ src/ngircd/conf.h @@ -94,12 +94,9 @@ GLOBAL char Conf_ServerAdmin1[CLIENT_INFO_LEN]; GLOBAL char Conf_ServerAdmin2[CLIENT_INFO_LEN]; GLOBAL char Conf_ServerAdminMail[CLIENT_INFO_LEN]; -/* File with MOTD text */ -GLOBAL char Conf_MotdFile[FNAME_LEN]; +/* Message of the Day */ +GLOBAL array Conf_Motd; -/* Phrase with MOTD text */ -GLOBAL char Conf_MotdPhrase[LINE_LEN]; - /* Ports the server should listen on */ GLOBAL array Conf_ListenPorts; blob - b463c5f9f54006fb0fde6539c508c666569775ea blob + 579d5521d02772afcf76e65a8ca132c521d98b0f --- src/ngircd/defines.h +++ src/ngircd/defines.h @@ -93,7 +93,6 @@ #define CONFIG_FILE "/ngircd.conf" /* Configuration file name. */ #define MOTD_FILE "/ngircd.motd" /* Name of the MOTD file. */ -#define MOTD_PHRASE "" /* Default MOTD phrase string. */ #define CHROOT_DIR "" /* Default chroot() directory. */ #define PID_FILE "" /* Default file for the process ID. */ blob - 0a50e9fdbc45a903d1672c7a4d5c34affb46a953 blob + ad585fe236151dc68f013ad22a81896512de767a --- src/ngircd/irc-info.c +++ src/ngircd/irc-info.c @@ -1231,45 +1231,30 @@ static inline bool Show_MOTD_SSLInfo(UNUSED CLIENT *c) GLOBAL bool IRC_Show_MOTD( CLIENT *Client ) { - char line[127]; - FILE *fd; + const char *line; + size_t len_tot, len_str; assert( Client != NULL ); - if (Conf_MotdPhrase[0]) { - if (!Show_MOTD_Start(Client)) - return DISCONNECTED; - if (!Show_MOTD_Sendline(Client, Conf_MotdPhrase)) - return DISCONNECTED; - goto out; - } + len_tot = array_bytes(&Conf_Motd); + if (len_tot == 0 && !Conn_UsesSSL(Client_Conn(Client))) + return IRC_WriteStrClient(Client, ERR_NOMOTD_MSG, Client_ID(Client)); - fd = fopen( Conf_MotdFile, "r" ); - if( ! fd ) { - Log( LOG_WARNING, "Can't read MOTD file \"%s\": %s", Conf_MotdFile, strerror( errno )); - if (Conn_UsesSSL(Client_Conn(Client))) { - if (!Show_MOTD_Start(Client)) - return DISCONNECTED; - goto out; - } - return IRC_WriteStrClient( Client, ERR_NOMOTD_MSG, Client_ID( Client ) ); - } + if (!Show_MOTD_Start(Client)) + return DISCONNECTED; - if (!Show_MOTD_Start( Client )) { - fclose(fd); - return false; - } + line = array_start(&Conf_Motd); + while (len_tot > 0) { + len_str = strlen(line) + 1; - while (fgets( line, (int)sizeof line, fd )) { - ngt_TrimLastChr( line, '\n'); + assert(len_tot >= len_str); + len_tot -= len_str; - if( ! Show_MOTD_Sendline( Client, line)) { - fclose( fd ); - return false; - } + if (!Show_MOTD_Sendline(Client, line)) + return DISCONNECTED; + line += len_str; } - fclose(fd); -out: + if (!Show_MOTD_SSLInfo(Client)) return DISCONNECTED; return Show_MOTD_End(Client);