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)
This commit is contained in:
Florian Westphal 2010-08-11 22:52:06 +02:00
parent a02bc9cc6f
commit 056de78e31
6 changed files with 70 additions and 48 deletions

View 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

View 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

View 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 ) {

View 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;

View 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. */

View 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))
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));
if (!Show_MOTD_Start(Client))
return DISCONNECTED;
line = array_start(&Conf_Motd);
while (len_tot > 0) {
len_str = strlen(line) + 1;
assert(len_tot >= len_str);
len_tot -= len_str;
if (!Show_MOTD_Sendline(Client, line))
return DISCONNECTED;
if (!Show_MOTD_Sendline(Client, Conf_MotdPhrase))
return DISCONNECTED;
goto out;
line += len_str;
}
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 )) {
fclose(fd);
return false;
}
while (fgets( line, (int)sizeof line, fd )) {
ngt_TrimLastChr( line, '\n');
if( ! Show_MOTD_Sendline( Client, line)) {
fclose( fd );
return false;
}
}
fclose(fd);
out:
if (!Show_MOTD_SSLInfo(Client))
return DISCONNECTED;
return Show_MOTD_End(Client);