X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=blobdiff_plain;f=src%2Fngircd%2Fconf.c;h=c12658d9e17329a8c3cfe9408cced78b9b938cac;hp=2ff503612cd31575116941c9267ffc7f742408f1;hb=a2544e496c3d2887069e646c9451ec49968125f5;hpb=8b7b23cf8f36e51bbe89a1a586bd238357183e83 diff --git a/src/ngircd/conf.c b/src/ngircd/conf.c index 2ff50361..c12658d9 100644 --- a/src/ngircd/conf.c +++ b/src/ngircd/conf.c @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: conf.c,v 1.43 2002/12/13 17:32:33 alex Exp $"; +static char UNUSED id[] = "$Id: conf.c,v 1.52 2002/12/30 00:01:45 alex Exp $"; #include "imp.h" #include @@ -27,6 +27,7 @@ static char UNUSED id[] = "$Id: conf.c,v 1.43 2002/12/13 17:32:33 alex Exp $"; #include #include #include +#include #ifdef HAVE_CTYPE_H # include @@ -45,11 +46,13 @@ static char UNUSED id[] = "$Id: conf.c,v 1.43 2002/12/13 17:32:33 alex Exp $"; LOCAL BOOLEAN Use_Log = TRUE; +LOCAL CONF_SERVER New_Server; +LOCAL INT New_Server_Idx; -LOCAL VOID Set_Defaults PARAMS(( VOID )); +LOCAL VOID Set_Defaults PARAMS(( BOOLEAN InitServers )); LOCAL VOID Read_Config PARAMS(( VOID )); -LOCAL VOID Validate_Config PARAMS(( VOID )); +LOCAL VOID Validate_Config PARAMS(( BOOLEAN TestOnly )); LOCAL VOID Handle_GLOBAL PARAMS(( INT Line, CHAR *Var, CHAR *Arg )); LOCAL VOID Handle_OPERATOR PARAMS(( INT Line, CHAR *Var, CHAR *Arg )); @@ -58,16 +61,27 @@ LOCAL VOID Handle_CHANNEL PARAMS(( INT Line, CHAR *Var, CHAR *Arg )); LOCAL VOID Config_Error PARAMS(( CONST INT Level, CONST CHAR *Format, ... )); +LOCAL VOID Init_Server_Struct PARAMS(( CONF_SERVER *Server )); + GLOBAL VOID Conf_Init( VOID ) { - Set_Defaults( ); + Set_Defaults( TRUE ); Read_Config( ); - Validate_Config( ); + Validate_Config( FALSE ); } /* Config_Init */ +GLOBAL VOID +Conf_Rehash( VOID ) +{ + Set_Defaults( FALSE ); + Read_Config( ); + Validate_Config( FALSE ); +} /* Config_Rehash */ + + GLOBAL INT Conf_Test( VOID ) { @@ -78,9 +92,10 @@ Conf_Test( VOID ) INT i; Use_Log = FALSE; - Set_Defaults( ); + Set_Defaults( TRUE ); Read_Config( ); + Validate_Config( TRUE ); /* If stdin is a valid tty wait for a key: */ if( isatty( fileno( stdout ))) @@ -119,8 +134,6 @@ Conf_Test( VOID ) else printf( " MaxConnections = -1\n" ); if( Conf_MaxJoins > 0 ) printf( " MaxJoins = %d\n", Conf_MaxJoins ); else printf( " MaxJoins = -1\n" ); - if( Conf_MaxPChannels > 0 ) printf( " MaxPChannels = %d\n", Conf_MaxPChannels ); - else printf( " MaxPChannels = -1\n" ); puts( "" ); for( i = 0; i < Conf_Oper_Count; i++ ) @@ -134,7 +147,7 @@ Conf_Test( VOID ) puts( "" ); } - for( i = 0; i < Conf_Server_Count; i++ ) + for( i = 0; i < MAX_SERVERS; i++ ) { if( ! Conf_Server[i].name[0] ) continue; @@ -165,11 +178,79 @@ Conf_Test( VOID ) } /* Conf_Test */ +GLOBAL VOID +Conf_UnsetServer( CONN_ID Idx ) +{ + /* Set next time for next connection attempt, if this is a server + * link that is (still) configured here. If the server is set as + * "once", delete it from our configuration. + * Non-Server-Connections will be silently ignored. */ + + INT i; + + /* Check all our configured servers */ + for( i = 0; i < MAX_SERVERS; i++ ) + { + if( Conf_Server[i].conn_id != Idx ) continue; + + /* Gotcha! Mark server configuration as "unused": */ + Conf_Server[i].conn_id = NONE; + + if( Conf_Server[i].once ) + { + /* Delete configuration here */ + Init_Server_Struct( &Conf_Server[i] ); + } + else + { + /* Set time for next connect attempt */ + if( Conf_Server[i].lasttry < time( NULL ) - Conf_ConnectRetry ) + { + /* Okay, the connection was established "long enough": */ + Conf_Server[i].lasttry = time( NULL ) - Conf_ConnectRetry + RECONNECT_DELAY; + } + } + break; + } +} /* Conf_UnsetServer */ + + +GLOBAL VOID +Conf_SetServer( INT ConfServer, CONN_ID Idx ) +{ + /* Set connection for specified configured server */ + + assert( ConfServer > NONE ); + assert( Idx > NONE ); + + Conf_Server[ConfServer].conn_id = Idx; +} /* Conf_SetServer */ + + +GLOBAL INT +Conf_GetServer( CONN_ID Idx ) +{ + /* Get index of server in configuration structure */ + + INT i; + + assert( Idx > NONE ); + + for( i = 0; i < MAX_SERVERS; i++ ) + { + if( Conf_Server[i].conn_id == Idx ) return i; + } + return NONE; +} /* Conf_GetServer */ + + LOCAL VOID -Set_Defaults( VOID ) +Set_Defaults( BOOLEAN InitServers ) { /* Initialize configuration variables with default values. */ + INT i; + strcpy( Conf_ServerName, "" ); sprintf( Conf_ServerInfo, "%s %s", PACKAGE, VERSION ); strcpy( Conf_ServerPwd, "" ); @@ -178,7 +259,8 @@ Set_Defaults( VOID ) strcpy( Conf_ServerAdmin2, "" ); strcpy( Conf_ServerAdminMail, "" ); - strcpy( Conf_MotdFile, MOTD_FILE ); + strlcpy( Conf_MotdFile, SYSCONFDIR, sizeof( Conf_MotdFile )); + strlcat( Conf_MotdFile, MOTD_FILE, sizeof( Conf_MotdFile )); Conf_ListenPorts_Count = 0; @@ -190,14 +272,15 @@ Set_Defaults( VOID ) Conf_ConnectRetry = 60; Conf_Oper_Count = 0; - Conf_Server_Count = 0; Conf_Channel_Count = 0; Conf_OperCanMode = FALSE; Conf_MaxConnections = -1; Conf_MaxJoins = 10; - Conf_MaxPChannels = -1; + + /* Initialize server configuration structures */ + if( InitServers ) for( i = 0; i < MAX_SERVERS; Init_Server_Struct( &Conf_Server[i++] )); } /* Set_Defaults */ @@ -207,9 +290,10 @@ Read_Config( VOID ) /* Read configuration file. */ CHAR section[LINE_LEN], str[LINE_LEN], *var, *arg, *ptr; - INT line; + INT line, i; FILE *fd; + /* Open configuration file */ fd = fopen( NGIRCd_ConfFile, "r" ); if( ! fd ) { @@ -221,8 +305,22 @@ Read_Config( VOID ) Config_Error( LOG_INFO, "Reading configuration from \"%s\" ...", NGIRCd_ConfFile ); + /* Clean up server configuration structure: mark all already + * configured servers as "once" so that they are deleted + * after the next disconnect and delete all unused servers. */ + for( i = 0; i < MAX_SERVERS; i++ ) + { + if( Conf_Server[i].conn_id == NONE ) Init_Server_Struct( &Conf_Server[i] ); + else Conf_Server[i].once = TRUE; + } + + /* Initialize variables */ line = 0; strcpy( section, "" ); + Init_Server_Struct( &New_Server ); + New_Server_Idx = NONE; + + /* Read configuration file */ while( TRUE ) { if( ! fgets( str, LINE_LEN, fd )) break; @@ -235,7 +333,7 @@ Read_Config( VOID ) /* Is this the beginning of a new section? */ if(( str[0] == '[' ) && ( str[strlen( str ) - 1] == ']' )) { - strcpy( section, str ); + strlcpy( section, str, sizeof( section )); if( strcasecmp( section, "[GLOBAL]" ) == 0 ) continue; if( strcasecmp( section, "[OPERATOR]" ) == 0 ) { @@ -251,21 +349,30 @@ Read_Config( VOID ) } if( strcasecmp( section, "[SERVER]" ) == 0 ) { - if( Conf_Server_Count + 1 > MAX_SERVERS ) Config_Error( LOG_ERR, "Too many servers configured." ); - else + /* Check if there is already a server to add */ + if( New_Server.name[0] ) + { + /* Copy data to "real" server structure */ + assert( New_Server_Idx > NONE ); + Conf_Server[New_Server_Idx] = New_Server; + } + + /* Re-init structure for new server */ + Init_Server_Struct( &New_Server ); + + /* Search unused item in server configuration structure */ + for( i = 0; i < MAX_SERVERS; i++ ) { - /* Initialize new server structure */ - strcpy( Conf_Server[Conf_Server_Count].host, "" ); - strcpy( Conf_Server[Conf_Server_Count].ip, "" ); - strcpy( Conf_Server[Conf_Server_Count].name, "" ); - strcpy( Conf_Server[Conf_Server_Count].pwd_in, "" ); - strcpy( Conf_Server[Conf_Server_Count].pwd_out, "" ); - Conf_Server[Conf_Server_Count].port = 0; - Conf_Server[Conf_Server_Count].group = -1; - Conf_Server[Conf_Server_Count].lasttry = time( NULL ) - Conf_ConnectRetry + STARTUP_DELAY; - Conf_Server[Conf_Server_Count].res_stat = NULL; - Conf_Server_Count++; + /* Is this item used? */ + if( ! Conf_Server[i].name[0] ) break; } + if( i >= MAX_SERVERS ) + { + /* Oops, no free item found! */ + Config_Error( LOG_ERR, "Too many servers configured." ); + New_Server_Idx = NONE; + } + else New_Server_Idx = i; continue; } if( strcasecmp( section, "[CHANNEL]" ) == 0 ) @@ -303,8 +410,17 @@ Read_Config( VOID ) else if( strcasecmp( section, "[CHANNEL]" ) == 0 ) Handle_CHANNEL( line, var, arg ); else Config_Error( LOG_ERR, "%s, line %d: Variable \"%s\" outside section!", NGIRCd_ConfFile, line, var ); } - + + /* Close configuration file */ fclose( fd ); + + /* Check if there is still a server to add */ + if( New_Server.name[0] ) + { + /* Copy data to "real" server structure */ + assert( New_Server_Idx > NONE ); + Conf_Server[New_Server_Idx] = New_Server; + } /* If there are no ports configured use the default: 6667 */ if( Conf_ListenPorts_Count < 1 ) @@ -330,49 +446,37 @@ Handle_GLOBAL( INT Line, CHAR *Var, CHAR *Arg ) if( strcasecmp( Var, "Name" ) == 0 ) { /* Server name */ - strncpy( Conf_ServerName, Arg, CLIENT_ID_LEN - 1 ); - Conf_ServerName[CLIENT_ID_LEN - 1] = '\0'; - if( strlen( Arg ) > CLIENT_ID_LEN - 1 ) 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( LOG_WARNING, "%s, line %d: Value of \"Name\" too long!", NGIRCd_ConfFile, Line ); return; } if( strcasecmp( Var, "Info" ) == 0 ) { /* Info text of server */ - strncpy( Conf_ServerInfo, Arg, CLIENT_INFO_LEN - 1 ); - Conf_ServerInfo[CLIENT_INFO_LEN - 1] = '\0'; - if( strlen( Arg ) > CLIENT_INFO_LEN - 1 ) 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( LOG_WARNING, "%s, line %d: Value of \"Info\" too long!", NGIRCd_ConfFile, Line ); return; } if( strcasecmp( Var, "Password" ) == 0 ) { /* Global server password */ - strncpy( Conf_ServerPwd, Arg, CLIENT_PASS_LEN - 1 ); - Conf_ServerPwd[CLIENT_PASS_LEN - 1] = '\0'; - if( strlen( Arg ) > CLIENT_PASS_LEN - 1 ) 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( LOG_WARNING, "%s, line %d: Value of \"Password\" too long!", NGIRCd_ConfFile, Line ); return; } if( strcasecmp( Var, "AdminInfo1" ) == 0 ) { /* Administrative info #1 */ - strncpy( Conf_ServerAdmin1, Arg, CLIENT_INFO_LEN - 1 ); - Conf_ServerAdmin1[CLIENT_INFO_LEN - 1] = '\0'; - if( strlen( Arg ) > CLIENT_INFO_LEN - 1 ) 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( LOG_WARNING, "%s, line %d: Value of \"AdminInfo1\" too long!", NGIRCd_ConfFile, Line ); return; } if( strcasecmp( Var, "AdminInfo2" ) == 0 ) { /* Administrative info #2 */ - strncpy( Conf_ServerAdmin2, Arg, CLIENT_INFO_LEN - 1 ); - Conf_ServerAdmin2[CLIENT_INFO_LEN - 1] = '\0'; - if( strlen( Arg ) > CLIENT_INFO_LEN - 1 ) 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( LOG_WARNING, "%s, line %d: Value of \"AdminInfo2\" too long!", NGIRCd_ConfFile, Line ); return; } if( strcasecmp( Var, "AdminEMail" ) == 0 ) { /* Administrative email contact */ - strncpy( Conf_ServerAdminMail, Arg, CLIENT_INFO_LEN - 1 ); - Conf_ServerAdminMail[CLIENT_INFO_LEN - 1] = '\0'; - if( strlen( Arg ) > CLIENT_INFO_LEN - 1 ) 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( LOG_WARNING, "%s, line %d: Value of \"AdminEMail\" too long!", NGIRCd_ConfFile, Line ); return; } if( strcasecmp( Var, "Ports" ) == 0 ) @@ -397,9 +501,7 @@ Handle_GLOBAL( INT Line, CHAR *Var, CHAR *Arg ) if( strcasecmp( Var, "MotdFile" ) == 0 ) { /* "Message of the day" (MOTD) file */ - strncpy( Conf_MotdFile, Arg, FNAME_LEN - 1 ); - Conf_MotdFile[FNAME_LEN - 1] = '\0'; - if( strlen( Arg ) > FNAME_LEN - 1 ) 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( LOG_WARNING, "%s, line %d: Value of \"MotdFile\" too long!", NGIRCd_ConfFile, Line ); return; } if( strcasecmp( Var, "ServerUID" ) == 0 ) @@ -494,16 +596,6 @@ Handle_GLOBAL( INT Line, CHAR *Var, CHAR *Arg ) Conf_MaxJoins = atoi( Arg ); return; } - if( strcasecmp( Var, "MaxPChannels" ) == 0 ) - { - /* Maximum number of persistent channels in the network. Values <= 0 are equal to "no limit". */ -#ifdef HAVE_ISDIGIT - if( ! isdigit( *Arg )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"MaxPChannels\" is not a number!", NGIRCd_ConfFile, Line ); - else -#endif - Conf_MaxPChannels = atoi( Arg ); - return; - } Config_Error( LOG_ERR, "%s, line %d (section \"Global\"): Unknown variable \"%s\"!", NGIRCd_ConfFile, Line, Var ); } /* Handle_GLOBAL */ @@ -520,17 +612,13 @@ Handle_OPERATOR( INT Line, CHAR *Var, CHAR *Arg ) if( strcasecmp( Var, "Name" ) == 0 ) { /* Name of IRC operator */ - strncpy( Conf_Oper[Conf_Oper_Count - 1].name, Arg, CLIENT_PASS_LEN - 1 ); - Conf_Oper[Conf_Oper_Count - 1].name[CLIENT_PASS_LEN - 1] = '\0'; - if( strlen( Arg ) > CLIENT_PASS_LEN - 1 ) 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( LOG_WARNING, "%s, line %d: Value of \"Name\" too long!", NGIRCd_ConfFile, Line ); return; } if( strcasecmp( Var, "Password" ) == 0 ) { /* Password of IRC operator */ - strncpy( Conf_Oper[Conf_Oper_Count - 1].pwd, Arg, CLIENT_PASS_LEN - 1 ); - Conf_Oper[Conf_Oper_Count - 1].pwd[CLIENT_PASS_LEN - 1] = '\0'; - if( strlen( Arg ) > CLIENT_PASS_LEN - 1 ) 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( LOG_WARNING, "%s, line %d: Value of \"Password\" too long!", NGIRCd_ConfFile, Line ); return; } @@ -547,43 +635,38 @@ Handle_SERVER( INT Line, CHAR *Var, CHAR *Arg ) assert( Var != NULL ); assert( Arg != NULL ); + /* Ignore server block if no space is left in server configuration structure */ + if( New_Server_Idx <= NONE ) return; + if( strcasecmp( Var, "Host" ) == 0 ) { /* Hostname of the server */ - strncpy( Conf_Server[Conf_Server_Count - 1].host, Arg, HOST_LEN - 1 ); - Conf_Server[Conf_Server_Count - 1].host[HOST_LEN - 1] = '\0'; - if( strlen( Arg ) > HOST_LEN - 1 ) 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( LOG_WARNING, "%s, line %d: Value of \"Host\" too long!", NGIRCd_ConfFile, Line ); return; } if( strcasecmp( Var, "Name" ) == 0 ) { /* Name of the server ("Nick"/"ID") */ - strncpy( Conf_Server[Conf_Server_Count - 1].name, Arg, CLIENT_ID_LEN - 1 ); - Conf_Server[Conf_Server_Count - 1].name[CLIENT_ID_LEN - 1] = '\0'; - if( strlen( Arg ) > CLIENT_ID_LEN - 1 ) 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( LOG_WARNING, "%s, line %d: Value of \"Name\" too long!", NGIRCd_ConfFile, Line ); return; } if( strcasecmp( Var, "MyPassword" ) == 0 ) { /* Password of this server which is sent to the peer */ - strncpy( Conf_Server[Conf_Server_Count - 1].pwd_in, Arg, CLIENT_PASS_LEN - 1 ); - Conf_Server[Conf_Server_Count - 1].pwd_in[CLIENT_PASS_LEN - 1] = '\0'; - if( strlen( Arg ) > CLIENT_PASS_LEN - 1 ) 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( LOG_WARNING, "%s, line %d: Value of \"MyPassword\" too long!", NGIRCd_ConfFile, Line ); return; } if( strcasecmp( Var, "PeerPassword" ) == 0 ) { /* Passwort of the peer which must be received */ - strncpy( Conf_Server[Conf_Server_Count - 1].pwd_out, Arg, CLIENT_PASS_LEN - 1 ); - Conf_Server[Conf_Server_Count - 1].pwd_out[CLIENT_PASS_LEN - 1] = '\0'; - if( strlen( Arg ) > CLIENT_PASS_LEN - 1 ) 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( LOG_WARNING, "%s, line %d: Value of \"PeerPassword\" too long!", NGIRCd_ConfFile, Line ); return; } if( strcasecmp( Var, "Port" ) == 0 ) { /* Port to which this server should connect */ port = atol( Arg ); - if( port > 0 && port < 0xFFFF ) Conf_Server[Conf_Server_Count - 1].port = (INT)port; + if( port > 0 && port < 0xFFFF ) New_Server.port = (INT)port; else Config_Error( LOG_ERR, "%s, line %d (section \"Server\"): Illegal port number %ld!", NGIRCd_ConfFile, Line, port ); return; } @@ -594,7 +677,7 @@ Handle_SERVER( INT Line, CHAR *Var, CHAR *Arg ) if( ! isdigit( *Arg )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"Group\" is not a number!", NGIRCd_ConfFile, Line ); else #endif - Conf_Server[Conf_Server_Count - 1].group = atoi( Arg ); + New_Server.group = atoi( Arg ); return; } @@ -612,25 +695,19 @@ Handle_CHANNEL( INT Line, CHAR *Var, CHAR *Arg ) if( strcasecmp( Var, "Name" ) == 0 ) { /* Name of the channel */ - strncpy( Conf_Channel[Conf_Channel_Count - 1].name, Arg, CHANNEL_NAME_LEN - 1 ); - Conf_Channel[Conf_Channel_Count - 1].name[CHANNEL_NAME_LEN - 1] = '\0'; - if( strlen( Arg ) > CHANNEL_NAME_LEN - 1 ) 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( LOG_WARNING, "%s, line %d: Value of \"Name\" too long!", NGIRCd_ConfFile, Line ); return; } if( strcasecmp( Var, "Modes" ) == 0 ) { /* Initial modes */ - strncpy( Conf_Channel[Conf_Channel_Count - 1].modes, Arg, CHANNEL_MODE_LEN - 1 ); - Conf_Channel[Conf_Channel_Count - 1].modes[CHANNEL_MODE_LEN - 1] = '\0'; - if( strlen( Arg ) > CHANNEL_MODE_LEN - 1 ) 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( LOG_WARNING, "%s, line %d: Value of \"Modes\" too long!", NGIRCd_ConfFile, Line ); return; } if( strcasecmp( Var, "Topic" ) == 0 ) { /* Initial topic */ - strncpy( Conf_Channel[Conf_Channel_Count - 1].topic, Arg, CHANNEL_TOPIC_LEN - 1 ); - Conf_Channel[Conf_Channel_Count - 1].topic[CHANNEL_TOPIC_LEN - 1] = '\0'; - if( strlen( Arg ) > CHANNEL_TOPIC_LEN - 1 ) 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( LOG_WARNING, "%s, line %d: Value of \"Topic\" too long!", NGIRCd_ConfFile, Line ); return; } @@ -639,16 +716,23 @@ Handle_CHANNEL( INT Line, CHAR *Var, CHAR *Arg ) LOCAL VOID -Validate_Config( VOID ) +Validate_Config( BOOLEAN Configtest ) { /* Validate configuration settings. */ - + +#ifdef DEBUG + INT i, servers, servers_once; +#endif + 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, "%s exiting due to fatal errors!", PACKAGE ); - exit( 1 ); + if( ! Configtest ) + { + Config_Error( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE ); + exit( 1 ); + } } #ifdef STRICT_RFC @@ -656,16 +740,41 @@ Validate_Config( VOID ) { /* No administrative contact configured! */ Config_Error( LOG_ALERT, "No administrator email address configured in \"%s\" ('AdminEMail')!", NGIRCd_ConfFile ); - Config_Error( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE ); - exit( 1 ); + if( ! Configtest ) + { + Config_Error( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE ); + exit( 1 ); + } } #endif if( ! Conf_ServerAdmin1[0] && ! Conf_ServerAdmin2[0] && ! Conf_ServerAdminMail[0] ) { /* No administrative information configured! */ - Log( LOG_WARNING, "No administrative information configured but required by RFC!" ); + Config_Error( LOG_WARNING, "No administrative information configured but required by RFC!" ); } +#ifdef FD_SETSIZE + if(( Conf_MaxConnections > (LONG)FD_SETSIZE ) || ( Conf_MaxConnections < 1 )) + { + Conf_MaxConnections = (LONG)FD_SETSIZE; + Config_Error( LOG_ERR, "Setting MaxConnections to %ld, select() can't handle more file descriptors!", Conf_MaxConnections ); + } +#else + Config_Error( LOG_WARN, "Don't know how many file descriptors select() can handle on this system, don't set MaxConnections too high!" ); +#endif + +#ifdef DEBUG + servers = servers_once = 0; + for( i = 0; i < MAX_SERVERS; i++ ) + { + if( Conf_Server[i].name[0] ) + { + servers++; + if( Conf_Server[i].once ) servers_once++; + } + } + Log( LOG_DEBUG, "Configuration: Operators=%d, Servers=%d[%d], Channels=%d", Conf_Oper_Count, servers, servers_once, Conf_Channel_Count ); +#endif } /* Validate_Config */ @@ -701,4 +810,25 @@ va_dcl } /* Config_Error */ +LOCAL VOID +Init_Server_Struct( CONF_SERVER *Server ) +{ + /* Initialize server configuration structur to default values */ + + assert( Server != NULL ); + + strcpy( Server->host, "" ); + strcpy( Server->ip, "" ); + strcpy( Server->name, "" ); + strcpy( Server->pwd_in, "" ); + strcpy( Server->pwd_out, "" ); + Server->port = 0; + Server->group = NONE; + Server->lasttry = time( NULL ) - Conf_ConnectRetry + STARTUP_DELAY; + Server->res_stat = NULL; + Server->once = FALSE; + Server->conn_id = NONE; +} /* Init_Server_Struct */ + + /* -eof- */