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.
-       # 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
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
-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
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 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 ) {
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];
 
-/* 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;
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 MOTD_PHRASE ""                 /* Default MOTD phrase string. */
 #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 )
 {
-       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);