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 645d1b8..fdeed35 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 ad88871..71aaa1e 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 834a1da..a70973e 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 74abc1d..e7b84d2 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 b463c5f..579d552 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 0a50e9f..ad585fe 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);