]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/conf.c
New configuration option "Mask" for [Operator] sections to limit OPER command.
[ngircd-alex.git] / src / ngircd / conf.c
index 00b5bb795274a4dc3fa280c5cca4c936fbbb8e89..312ebff9a1cfcb724b3065613b1acefe904abdd0 100644 (file)
 
 #include "portab.h"
 
-static char UNUSED id[] = "$Id: conf.c,v 1.59 2003/04/29 12:36:09 alex Exp $";
+static char UNUSED id[] = "$Id: conf.c,v 1.69 2005/03/02 16:07:31 alex Exp $";
 
 #include "imp.h"
 #include <assert.h>
 #include <errno.h>
-#include <stdarg.h>
+#ifdef PROTOTYPES
+#      include <stdarg.h>
+#else
+#      include <varargs.h>
+#endif
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <strings.h>
 #include <unistd.h>
 #include <pwd.h>
 #include <grp.h>
@@ -61,6 +66,9 @@ LOCAL VOID Handle_CHANNEL PARAMS(( INT Line, CHAR *Var, CHAR *Arg ));
 
 LOCAL VOID Config_Error PARAMS(( CONST INT Level, CONST CHAR *Format, ... ));
 
+LOCAL VOID Config_Error_NaN PARAMS(( INT LINE, CONST CHAR *Value ));
+LOCAL VOID Config_Error_TooLong PARAMS(( INT LINE, CONST CHAR *Value ));
+
 LOCAL VOID Init_Server_Struct PARAMS(( CONF_SERVER *Server ));
 
 
@@ -106,13 +114,16 @@ Conf_Test( VOID )
        else puts( "Ok, dump of your server configuration follows:\n" );
 
        puts( "[GLOBAL]" );
-       printf( "  ServerName = %s\n", Conf_ServerName );
-       printf( "  ServerInfo = %s\n", Conf_ServerInfo );
+       printf( "  Name = %s\n", Conf_ServerName );
+       printf( "  Info = %s\n", Conf_ServerInfo );
        printf( "  Password = %s\n", Conf_ServerPwd );
        printf( "  AdminInfo1 = %s\n", Conf_ServerAdmin1 );
        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( "  ChrootDir = %s\n", Conf_Chroot );
+       printf( "  PidFile = %s\n", Conf_PidFile);
        printf( "  Ports = " );
        for( i = 0; i < Conf_ListenPorts_Count; i++ )
        {
@@ -120,6 +131,7 @@ Conf_Test( VOID )
                printf( "%u", Conf_ListenPorts[i] );
        }
        puts( "" );
+       printf( "  Listen = %s\n", Conf_ListenAddress );
        pwd = getpwuid( Conf_UID );
        if( pwd ) printf( "  ServerUID = %s\n", pwd->pw_name );
        else printf( "  ServerUID = %ld\n", (LONG)Conf_UID );
@@ -132,6 +144,8 @@ Conf_Test( VOID )
        printf( "  OperCanUseMode = %s\n", Conf_OperCanMode == TRUE ? "yes" : "no" );
        if( Conf_MaxConnections > 0 ) printf( "  MaxConnections = %ld\n", Conf_MaxConnections );
        else printf( "  MaxConnections = -1\n" );
+       if( Conf_MaxConnectionsIP > 0 ) printf( "  MaxConnectionsIP = %d\n", Conf_MaxConnectionsIP );
+       else printf( "  MaxConnectionsIP = -1\n" );
        if( Conf_MaxJoins > 0 ) printf( "  MaxJoins = %d\n", Conf_MaxJoins );
        else printf( "  MaxJoins = -1\n" );
        puts( "" );
@@ -144,6 +158,7 @@ Conf_Test( VOID )
                puts( "[OPERATOR]" );
                printf( "  Name = %s\n", Conf_Oper[i].name );
                printf( "  Password = %s\n", Conf_Oper[i].pwd );
+               if ( Conf_Oper[i].mask ) printf( "  Mask = %s\n", Conf_Oper[i].mask );
                puts( "" );
        }
 
@@ -339,7 +354,14 @@ Set_Defaults( BOOLEAN InitServers )
        strlcpy( Conf_MotdFile, SYSCONFDIR, sizeof( Conf_MotdFile ));
        strlcat( Conf_MotdFile, MOTD_FILE, sizeof( Conf_MotdFile ));
 
+       strlcpy( Conf_MotdPhrase, MOTD_PHRASE, sizeof( Conf_MotdPhrase ));
+
+       strlcpy( Conf_Chroot, CHROOT_DIR, sizeof( Conf_Chroot ));
+
+       strlcpy( Conf_PidFile, PID_FILE, sizeof( Conf_PidFile ));
+
        Conf_ListenPorts_Count = 0;
+       strcpy( Conf_ListenAddress, "" );
 
        Conf_UID = Conf_GID = 0;
        
@@ -354,6 +376,7 @@ Set_Defaults( BOOLEAN InitServers )
        Conf_OperCanMode = FALSE;
        
        Conf_MaxConnections = -1;
+       Conf_MaxConnectionsIP = 5;
        Conf_MaxJoins = 10;
 
        /* Initialize server configuration structures */
@@ -444,8 +467,12 @@ Read_Config( VOID )
                                else
                                {
                                        /* Initialize new operator structure */
-                                       strcpy( Conf_Oper[Conf_Oper_Count].name, "" );
-                                       strcpy( Conf_Oper[Conf_Oper_Count].pwd, "" );
+                                       Conf_Oper[Conf_Oper_Count].name[0] = '\0';
+                                       Conf_Oper[Conf_Oper_Count].pwd[0] = '\0';
+                                       if (Conf_Oper[Conf_Oper_Count].mask) {
+                                               free(Conf_Oper[Conf_Oper_Count].mask );
+                                               Conf_Oper[Conf_Oper_Count].mask = NULL;
+                                       }
                                        Conf_Oper_Count++;
                                }
                                continue;
@@ -549,37 +576,43 @@ Handle_GLOBAL( INT Line, CHAR *Var, CHAR *Arg )
        if( strcasecmp( Var, "Name" ) == 0 )
        {
                /* Server name */
-               if( strlcpy( Conf_ServerName, Arg, sizeof( Conf_ServerName )) >= sizeof( Conf_ServerName )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"Name\" too long!", NGIRCd_ConfFile, Line );
+               if( strlcpy( Conf_ServerName, Arg, sizeof( Conf_ServerName )) >= sizeof( Conf_ServerName ))
+                       Config_Error_TooLong( Line, Var );
+
                return;
        }
        if( strcasecmp( Var, "Info" ) == 0 )
        {
                /* Info text of server */
-               if( strlcpy( Conf_ServerInfo, Arg, sizeof( Conf_ServerInfo )) >= sizeof( Conf_ServerInfo )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"Info\" too long!", NGIRCd_ConfFile, Line );
+               if( strlcpy( Conf_ServerInfo, Arg, sizeof( Conf_ServerInfo )) >= sizeof( Conf_ServerInfo ))
+                       Config_Error_TooLong ( Line, Var );
+
                return;
        }
        if( strcasecmp( Var, "Password" ) == 0 )
        {
                /* Global server password */
-               if( strlcpy( Conf_ServerPwd, Arg, sizeof( Conf_ServerPwd )) >= sizeof( Conf_ServerPwd )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"Password\" too long!", NGIRCd_ConfFile, Line );
+               if( strlcpy( Conf_ServerPwd, Arg, sizeof( Conf_ServerPwd )) >= sizeof( Conf_ServerPwd ))
+                       Config_Error_TooLong( Line, Var );
+
                return;
        }
        if( strcasecmp( Var, "AdminInfo1" ) == 0 )
        {
                /* Administrative info #1 */
-               if( strlcpy( Conf_ServerAdmin1, Arg, sizeof( Conf_ServerAdmin1 )) >= sizeof( Conf_ServerAdmin1 )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"AdminInfo1\" too long!", NGIRCd_ConfFile, Line );
+               if( strlcpy( Conf_ServerAdmin1, Arg, sizeof( Conf_ServerAdmin1 )) >= sizeof( Conf_ServerAdmin1 )) Config_Error_TooLong ( Line, Var );
                return;
        }
        if( strcasecmp( Var, "AdminInfo2" ) == 0 )
        {
                /* Administrative info #2 */
-               if( strlcpy( Conf_ServerAdmin2, Arg, sizeof( Conf_ServerAdmin2 )) >= sizeof( Conf_ServerAdmin2 )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"AdminInfo2\" too long!", NGIRCd_ConfFile, Line );
+               if( strlcpy( Conf_ServerAdmin2, Arg, sizeof( Conf_ServerAdmin2 )) >= sizeof( Conf_ServerAdmin2 )) Config_Error_TooLong ( Line, Var );
                return;
        }
        if( strcasecmp( Var, "AdminEMail" ) == 0 )
        {
                /* Administrative email contact */
-               if( strlcpy( Conf_ServerAdminMail, Arg, sizeof( Conf_ServerAdminMail )) >= sizeof( Conf_ServerAdminMail )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"AdminEMail\" too long!", NGIRCd_ConfFile, Line );
+               if( strlcpy( Conf_ServerAdminMail, Arg, sizeof( Conf_ServerAdminMail )) >= sizeof( Conf_ServerAdminMail )) Config_Error_TooLong( Line, Var );
                return;
        }
        if( strcasecmp( Var, "Ports" ) == 0 )
@@ -604,9 +637,37 @@ Handle_GLOBAL( INT Line, CHAR *Var, CHAR *Arg )
        if( strcasecmp( Var, "MotdFile" ) == 0 )
        {
                /* "Message of the day" (MOTD) file */
-               if( strlcpy( Conf_MotdFile, Arg, sizeof( Conf_MotdFile )) >= sizeof( Conf_MotdFile )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"MotdFile\" too long!", NGIRCd_ConfFile, Line );
+               if( strlcpy( Conf_MotdFile, Arg, sizeof( Conf_MotdFile )) >= sizeof( Conf_MotdFile ))
+                       Config_Error_TooLong( Line, Var );
+
                return;
        }
+       if( strcasecmp( Var, "MotdPhrase" ) == 0 )
+       {
+               /* "Message of the day" phrase (instead of file) */
+               if( strlcpy( Conf_MotdPhrase, Arg, sizeof( Conf_MotdPhrase )) >= sizeof( Conf_MotdPhrase ))
+                       Config_Error_TooLong( Line, Var );
+
+               return;
+       }
+       if( strcasecmp( Var, "ChrootDir" ) == 0 )
+       {
+               /* directory for chroot() */
+               if( strlcpy( Conf_Chroot, Arg, sizeof( Conf_Chroot )) >= sizeof( Conf_Chroot ))
+                       Config_Error_TooLong( Line, Var );
+
+               return;
+       }
+
+       if ( strcasecmp( Var, "PidFile" ) == 0 )
+       {
+               /* name of pidfile */
+               if( strlcpy( Conf_PidFile, Arg, sizeof( Conf_PidFile )) >= sizeof( Conf_PidFile ))
+                       Config_Error_TooLong( Line, Var );
+
+               return;
+       }
+
        if( strcasecmp( Var, "ServerUID" ) == 0 )
        {
                /* UID the daemon should switch to */
@@ -615,7 +676,7 @@ Handle_GLOBAL( INT Line, CHAR *Var, CHAR *Arg )
                else
                {
 #ifdef HAVE_ISDIGIT
-                       if( ! isdigit( *Arg )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"ServerUID\" is not a number!", NGIRCd_ConfFile, Line );
+                       if( ! isdigit( (INT)*Arg )) Config_Error_NaN( Line, Var );
                        else
 #endif
                        Conf_UID = (UINT)atoi( Arg );
@@ -630,7 +691,7 @@ Handle_GLOBAL( INT Line, CHAR *Var, CHAR *Arg )
                else
                {
 #ifdef HAVE_ISDIGIT
-                       if( ! isdigit( *Arg )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"ServerGID\" is not a number!", NGIRCd_ConfFile, Line );
+                       if( ! isdigit( (INT)*Arg )) Config_Error_NaN( Line, Var );
                        else
 #endif
                        Conf_GID = (UINT)atoi( Arg );
@@ -683,22 +744,41 @@ Handle_GLOBAL( INT Line, CHAR *Var, CHAR *Arg )
        {
                /* Maximum number of connections. Values <= 0 are equal to "no limit". */
 #ifdef HAVE_ISDIGIT
-               if( ! isdigit( *Arg )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"MaxConnections\" is not a number!", NGIRCd_ConfFile, Line );
+               if( ! isdigit( (INT)*Arg )) Config_Error_NaN( Line, Var);
                else
 #endif
                Conf_MaxConnections = atol( Arg );
                return;
        }
+       if( strcasecmp( Var, "MaxConnectionsIP" ) == 0 )
+       {
+               /* Maximum number of simoultanous connections from one IP. Values <= 0 are equal to "no limit". */
+#ifdef HAVE_ISDIGIT
+               if( ! isdigit( (INT)*Arg )) Config_Error_NaN( Line, Var );
+               else
+#endif
+               Conf_MaxConnectionsIP = atoi( Arg );
+               return;
+       }
        if( strcasecmp( Var, "MaxJoins" ) == 0 )
        {
                /* Maximum number of channels a user can join. Values <= 0 are equal to "no limit". */
 #ifdef HAVE_ISDIGIT
-               if( ! isdigit( *Arg )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"MaxJoins\" is not a number!", NGIRCd_ConfFile, Line );
+               if( ! isdigit( (INT)*Arg )) Config_Error_NaN( Line, Var );
                else
 #endif
                Conf_MaxJoins = atoi( Arg );
                return;
        }
+       if( strcasecmp( Var, "Listen" ) == 0 )
+       {
+               /* IP-Address to bind sockets */
+               if( strlcpy( Conf_ListenAddress, Arg, sizeof( Conf_ListenAddress )) >= sizeof( Conf_ListenAddress ))
+               {
+                       Config_Error_TooLong( Line, Var );
+               }
+               return;
+       }
 
        Config_Error( LOG_ERR, "%s, line %d (section \"Global\"): Unknown variable \"%s\"!", NGIRCd_ConfFile, Line, Var );
 } /* Handle_GLOBAL */
@@ -707,6 +787,7 @@ Handle_GLOBAL( INT Line, CHAR *Var, CHAR *Arg )
 LOCAL VOID
 Handle_OPERATOR( INT Line, CHAR *Var, CHAR *Arg )
 {
+       unsigned int len;
        assert( Line > 0 );
        assert( Var != NULL );
        assert( Arg != NULL );
@@ -715,16 +796,28 @@ Handle_OPERATOR( INT Line, CHAR *Var, CHAR *Arg )
        if( strcasecmp( Var, "Name" ) == 0 )
        {
                /* Name of IRC operator */
-               if( strlcpy( Conf_Oper[Conf_Oper_Count - 1].name, Arg, sizeof( Conf_Oper[Conf_Oper_Count - 1].name )) >= sizeof( Conf_Oper[Conf_Oper_Count - 1].name )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"Name\" too long!", NGIRCd_ConfFile, Line );
+               if( strlcpy( Conf_Oper[Conf_Oper_Count - 1].name, Arg, sizeof( Conf_Oper[Conf_Oper_Count - 1].name )) >= sizeof( Conf_Oper[Conf_Oper_Count - 1].name )) Config_Error_TooLong( Line, Var );
                return;
        }
        if( strcasecmp( Var, "Password" ) == 0 )
        {
                /* Password of IRC operator */
-               if( strlcpy( Conf_Oper[Conf_Oper_Count - 1].pwd, Arg, sizeof( Conf_Oper[Conf_Oper_Count - 1].pwd )) >= sizeof( Conf_Oper[Conf_Oper_Count - 1].pwd )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"Password\" too long!", NGIRCd_ConfFile, Line );
+               if( strlcpy( Conf_Oper[Conf_Oper_Count - 1].pwd, Arg, sizeof( Conf_Oper[Conf_Oper_Count - 1].pwd )) >= sizeof( Conf_Oper[Conf_Oper_Count - 1].pwd )) Config_Error_TooLong( Line, Var );
+               return;
+       }
+       if( strcasecmp( Var, "Mask" ) == 0 )
+       {
+               if (Conf_Oper[Conf_Oper_Count - 1].mask) return; /* Hostname already configured */
+               len = strlen( Arg ) + 1;
+               Conf_Oper[Conf_Oper_Count - 1].mask = malloc( len );
+               if (! Conf_Oper[Conf_Oper_Count - 1].mask) {
+                       Config_Error( LOG_ERR, "%s, line %d: Cannot allocate memory for operator mask: %s", NGIRCd_ConfFile, Line, strerror(errno) );
+                       return;
+               }
+
+               strlcpy( Conf_Oper[Conf_Oper_Count - 1].mask, Arg, len);
                return;
        }
-       
        Config_Error( LOG_ERR, "%s, line %d (section \"Operator\"): Unknown variable \"%s\"!", NGIRCd_ConfFile, Line, Var );
 } /* Handle_OPERATOR */
 
@@ -744,25 +837,28 @@ Handle_SERVER( INT Line, CHAR *Var, CHAR *Arg )
        if( strcasecmp( Var, "Host" ) == 0 )
        {
                /* Hostname of the server */
-               if( strlcpy( New_Server.host, Arg, sizeof( New_Server.host )) >= sizeof( New_Server.host )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"Host\" too long!", NGIRCd_ConfFile, Line );
+               if( strlcpy( New_Server.host, Arg, sizeof( New_Server.host )) >= sizeof( New_Server.host ))
+                       Config_Error_TooLong ( Line, Var );
+
                return;
        }
        if( strcasecmp( Var, "Name" ) == 0 )
        {
                /* Name of the server ("Nick"/"ID") */
-               if( strlcpy( New_Server.name, Arg, sizeof( New_Server.name )) >= sizeof( New_Server.name )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"Name\" too long!", NGIRCd_ConfFile, Line );
+               if( strlcpy( New_Server.name, Arg, sizeof( New_Server.name )) >= sizeof( New_Server.name ))
+                       Config_Error_TooLong( Line, Var );
                return;
        }
        if( strcasecmp( Var, "MyPassword" ) == 0 )
        {
                /* Password of this server which is sent to the peer */
-               if( strlcpy( New_Server.pwd_in, Arg, sizeof( New_Server.pwd_in )) >= sizeof( New_Server.pwd_in )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"MyPassword\" too long!", NGIRCd_ConfFile, Line );
+               if( strlcpy( New_Server.pwd_in, Arg, sizeof( New_Server.pwd_in )) >= sizeof( New_Server.pwd_in )) Config_Error_TooLong( Line, Var );
                return;
        }
        if( strcasecmp( Var, "PeerPassword" ) == 0 )
        {
                /* Passwort of the peer which must be received */
-               if( strlcpy( New_Server.pwd_out, Arg, sizeof( New_Server.pwd_out )) >= sizeof( New_Server.pwd_out )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"PeerPassword\" too long!", NGIRCd_ConfFile, Line );
+               if( strlcpy( New_Server.pwd_out, Arg, sizeof( New_Server.pwd_out )) >= sizeof( New_Server.pwd_out )) Config_Error_TooLong( Line, Var );
                return;
        }
        if( strcasecmp( Var, "Port" ) == 0 )
@@ -777,7 +873,7 @@ Handle_SERVER( INT Line, CHAR *Var, CHAR *Arg )
        {
                /* Server group */
 #ifdef HAVE_ISDIGIT
-               if( ! isdigit( *Arg )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"Group\" is not a number!", NGIRCd_ConfFile, Line );
+               if( ! isdigit( (INT)*Arg )) Config_Error_NaN( Line, Var );
                else
 #endif
                New_Server.group = atoi( Arg );
@@ -798,19 +894,23 @@ Handle_CHANNEL( INT Line, CHAR *Var, CHAR *Arg )
        if( strcasecmp( Var, "Name" ) == 0 )
        {
                /* Name of the channel */
-               if( strlcpy( Conf_Channel[Conf_Channel_Count - 1].name, Arg, sizeof( Conf_Channel[Conf_Channel_Count - 1].name )) >= sizeof( Conf_Channel[Conf_Channel_Count - 1].name )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"Name\" too long!", NGIRCd_ConfFile, Line );
+               if( strlcpy( Conf_Channel[Conf_Channel_Count - 1].name, Arg, sizeof( Conf_Channel[Conf_Channel_Count - 1].name )) >= sizeof( Conf_Channel[Conf_Channel_Count - 1].name ))
+                       Config_Error_TooLong( Line, Var );
                return;
        }
        if( strcasecmp( Var, "Modes" ) == 0 )
        {
                /* Initial modes */
-               if( strlcpy( Conf_Channel[Conf_Channel_Count - 1].modes, Arg, sizeof( Conf_Channel[Conf_Channel_Count - 1].modes )) >= sizeof( Conf_Channel[Conf_Channel_Count - 1].modes )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"Modes\" too long!", NGIRCd_ConfFile, Line );
+               if( strlcpy( Conf_Channel[Conf_Channel_Count - 1].modes, Arg, sizeof( Conf_Channel[Conf_Channel_Count - 1].modes )) >= sizeof( Conf_Channel[Conf_Channel_Count - 1].modes ))
+                       Config_Error_TooLong( Line, Var );
                return;
        }
        if( strcasecmp( Var, "Topic" ) == 0 )
        {
                /* Initial topic */
-               if( strlcpy( Conf_Channel[Conf_Channel_Count - 1].topic, Arg, sizeof( Conf_Channel[Conf_Channel_Count - 1].topic )) >= sizeof( Conf_Channel[Conf_Channel_Count - 1].topic )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"Topic\" too long!", NGIRCd_ConfFile, Line );
+               if( strlcpy( Conf_Channel[Conf_Channel_Count - 1].topic, Arg, sizeof( Conf_Channel[Conf_Channel_Count - 1].topic )) >= sizeof( Conf_Channel[Conf_Channel_Count - 1].topic ))
+                       Config_Error_TooLong( Line, Var );
                return;
        }
 
@@ -830,7 +930,7 @@ Validate_Config( BOOLEAN Configtest )
        if( ! Conf_ServerName[0] )
        {
                /* No server name configured! */
-               Config_Error( LOG_ALERT, "No server name configured in \"%s\" ('ServerName')!", NGIRCd_ConfFile );
+               Config_Error( LOG_ALERT, "No server name configured in \"%s\" (section 'Global': 'Name')!", NGIRCd_ConfFile );
                if( ! Configtest )
                {
                        Config_Error( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME );
@@ -838,10 +938,10 @@ Validate_Config( BOOLEAN Configtest )
                }
        }
        
-       if( ! strchr( Conf_ServerName, '.' ))
+       if( Conf_ServerName[0] && ! strchr( Conf_ServerName, '.' ))
        {
                /* No dot in server name! */
-               Config_Error( LOG_ALERT, "Invalid server name configured in \"%s\" ('ServerName'): Dot missing!", NGIRCd_ConfFile );
+               Config_Error( LOG_ALERT, "Invalid server name configured in \"%s\" (section 'Global': 'Name'): Dot missing!", NGIRCd_ConfFile );
                if( ! Configtest )
                {
                        Config_Error( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME );
@@ -892,6 +992,18 @@ Validate_Config( BOOLEAN Configtest )
 } /* Validate_Config */
 
 
+LOCAL VOID
+Config_Error_TooLong ( CONST INT Line, CONST CHAR *Item )
+{
+       Config_Error( LOG_WARNING, "%s, line %d: Value of \"%s\" too long!", NGIRCd_ConfFile, Line, Item );
+}
+
+LOCAL VOID
+Config_Error_NaN( CONST INT Line, CONST CHAR *Item )
+{
+       Config_Error( LOG_WARNING, "%s, line %d: Value of \"%s\" is not a number!", NGIRCd_ConfFile, Line, Item );
+}
+
 #ifdef PROTOTYPES
 LOCAL VOID Config_Error( CONST INT Level, CONST CHAR *Format, ... )
 #else
@@ -931,17 +1043,13 @@ Init_Server_Struct( CONF_SERVER *Server )
 
        assert( Server != NULL );
 
-       strcpy( Server->host, "" );
-       strcpy( Server->ip, "" );
-       strcpy( Server->name, "" );
-       strcpy( Server->pwd_in, "" );
-       strcpy( Server->pwd_out, "" );
-       Server->port = 0;
+       memset( Server, 0, sizeof (CONF_SERVER) );
+
        Server->group = NONE;
        Server->lasttry = time( NULL ) - Conf_ConnectRetry + STARTUP_DELAY;
-       Server->res_stat = NULL;
+
        if( NGIRCd_Passive ) Server->flags = CONF_SFLAG_DISABLED;
-       else Server->flags = 0;
+
        Server->conn_id = NONE;
 } /* Init_Server_Struct */