about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2010-08-11 22:52:06 +0200
committerFlorian Westphal <fw@strlen.de>2010-08-12 21:46:47 +0200
commit056de78e315a79edc1166649514bf8dfeb18abb1 (patch)
tree0a54069829ad3aa388de6f09386c4666cd4e1098 /src
parenta02bc9cc6f821a604f6ae4a865b0da8eec4da5a4 (diff)
downloadngircd-056de78e315a79edc1166649514bf8dfeb18abb1.tar.gz
ngircd-056de78e315a79edc1166649514bf8dfeb18abb1.zip
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)
Diffstat (limited to 'src')
-rw-r--r--src/ngircd/conf.c53
-rw-r--r--src/ngircd/conf.h7
-rw-r--r--src/ngircd/defines.h1
-rw-r--r--src/ngircd/irc-info.c47
4 files changed, 66 insertions, 42 deletions
diff --git a/src/ngircd/conf.c b/src/ngircd/conf.c
index 834a1da3..a70973e7 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 74abc1d9..e7b84d2e 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 b463c5f9..579d5521 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 0a50e9fd..ad585fe2 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);