repo: ngircd
action: commit
revision: 
path_from: 
revision_from: 056de78e315a79edc1166649514bf8dfeb18abb1:
path_to: 
revision_to: 
git.thebackupbox.net
ngircd
git clone git://git.thebackupbox.net/ngircd
commit 056de78e315a79edc1166649514bf8dfeb18abb1
Author: Florian Westphal 
Date:   Wed Aug 11 22:52:06 2010 +0200

    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)

diff --git a/doc/sample-ngircd.conf b/doc/sample-ngircd.conf
index 645d1b8afbc525fef0d689f9c36b801bff67db5f..
index ..fdeed355bab93d257a42cfc6007388fbbdb311a4 100644
--- a/doc/sample-ngircd.conf
+++ b/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
diff --git a/man/ngircd.conf.5.tmpl b/man/ngircd.conf.5.tmpl
index ad888713ee7d0ee310404b15c02211ff7bd6c20a..
index ..71aaa1e0e2e89601739a0c109724f6301e9d57e3 100644
--- a/man/ngircd.conf.5.tmpl
+++ b/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
diff --git a/src/ngircd/conf.c b/src/ngircd/conf.c
index 834a1da330e989300993d5377bf6c8b726119ce5..
index ..a70973e78cf8b47d33eeac5cb54a27f8388e4fef 100644
--- a/src/ngircd/conf.c
+++ b/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, const char *Arg)
 } /* 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 ) {
diff --git a/src/ngircd/conf.h b/src/ngircd/conf.h
index 74abc1d95010d889ba626f76c836abcc8fc7db14..
index ..e7b84d2e16facd41000109629c2939b56c6a9940 100644
--- a/src/ngircd/conf.h
+++ b/src/ngircd/conf.h
@@ -94,11 +94,8 @@ 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];
-
-/* Phrase with MOTD text */
-GLOBAL char Conf_MotdPhrase[LINE_LEN];
+/* Message of the Day */
+GLOBAL array Conf_Motd;

 /* Ports the server should listen on */
 GLOBAL array Conf_ListenPorts;
diff --git a/src/ngircd/defines.h b/src/ngircd/defines.h
index b463c5f9f54006fb0fde6539c508c666569775ea..
index ..579d5521d02772afcf76e65a8ca132c521d98b0f 100644
--- a/src/ngircd/defines.h
+++ b/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. */

diff --git a/src/ngircd/irc-info.c b/src/ngircd/irc-info.c
index 0a50e9fdbc45a903d1672c7a4d5c34affb46a953..
index ..ad585fe236151dc68f013ad22a81896512de767a 100644
--- a/src/ngircd/irc-info.c
+++ b/src/ngircd/irc-info.c
@@ -1231,45 +1231,30 @@ static inline bool Show_MOTD_SSLInfo(UNUSED CLIENT *c) { return true; }
 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);

-----END OF PAGE-----