ngircd: change MOTD file handling
authorFlorian Westphal <fw@strlen.de>
Wed, 11 Aug 2010 20:52:06 +0000 (22:52 +0200)
committerFlorian Westphal <fw@strlen.de>
Thu, 12 Aug 2010 19:46:47 +0000 (21:46 +0200)
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)

doc/sample-ngircd.conf
man/ngircd.conf.5.tmpl
src/ngircd/conf.c
src/ngircd/conf.h
src/ngircd/defines.h
src/ngircd/irc-info.c

index 645d1b8afbc525fef0d689f9c36b801bff67db5f..fdeed355bab93d257a42cfc6007388fbbdb311a4 100644 (file)
@@ -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.
        ;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
        ;MotdPhrase = "Hello world!"
 
        # User ID under which the server should run; you can use the name
index ad888713ee7d0ee310404b15c02211ff7bd6c20a..71aaa1e0e2e89601739a0c109724f6301e9d57e3 100644 (file)
@@ -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
 .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.
 .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
 .TP
 \fBServerUID\fR
 User ID under which the server should run; you can use the name of the user
index 834a1da330e989300993d5377bf6c8b726119ce5..a70973e78cf8b47d33eeac5cb54a27f8388e4fef 100644 (file)
@@ -55,6 +55,8 @@ static int New_Server_Idx;
 
 static size_t Conf_Oper_Count;
 static size_t Conf_Channel_Count;
 
 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 ));
 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("  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);
        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_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));
 
        Conf_UID = Conf_GID = 0;
        strlcpy(Conf_Chroot, CHROOT_DIR, sizeof(Conf_Chroot));
@@ -617,6 +618,36 @@ no_listenports(void)
        return cnt == 0;
 }
 
        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 )
 {
 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);
        }
                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 */
 
        return true;
 } /* Read_Config */
 
@@ -816,6 +851,7 @@ static unsigned int Handle_MaxNickLength(int Line, const char *Arg)
 } /* Handle_MaxNickLength */
 
 
 } /* Handle_MaxNickLength */
 
 
+
 static void
 Handle_GLOBAL( int Line, char *Var, char *Arg )
 {
 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 ) {
                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 );
                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) */
                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 );
                        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 ) {
                return;
        }
        if( strcasecmp( Var, "ChrootDir" ) == 0 ) {
index 74abc1d95010d889ba626f76c836abcc8fc7db14..e7b84d2e16facd41000109629c2939b56c6a9940 100644 (file)
@@ -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];
 
 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;
 
 /* Ports the server should listen on */
 GLOBAL array Conf_ListenPorts;
index b463c5f9f54006fb0fde6539c508c666569775ea..579d5521d02772afcf76e65a8ca132c521d98b0f 100644 (file)
@@ -93,7 +93,6 @@
 
 #define CONFIG_FILE "/ngircd.conf"     /* Configuration file name. */
 #define MOTD_FILE "/ngircd.motd"       /* Name of the MOTD file. */
 
 #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. */
 
 #define CHROOT_DIR ""                  /* Default chroot() directory. */
 #define PID_FILE ""                    /* Default file for the process ID. */
 
index 0a50e9fdbc45a903d1672c7a4d5c34affb46a953..ad585fe236151dc68f013ad22a81896512de767a 100644 (file)
@@ -1231,45 +1231,30 @@ static inline bool Show_MOTD_SSLInfo(UNUSED CLIENT *c) { return true; }
 GLOBAL bool
 IRC_Show_MOTD( CLIENT *Client )
 {
 GLOBAL bool
 IRC_Show_MOTD( CLIENT *Client )
 {
-       char line[127];
-       FILE *fd;
+       const char *line;
+       size_t len_tot, len_str;
 
        assert( Client != NULL );
 
 
        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);
        if (!Show_MOTD_SSLInfo(Client))
                return DISCONNECTED;
        return Show_MOTD_End(Client);