#include "portab.h"
-static char UNUSED id[] = "$Id: conf.c,v 1.53 2002/12/31 16:12:50 alex Exp $";
+static char UNUSED id[] = "$Id: conf.c,v 1.64 2004/05/07 11:19:21 alex Exp $";
#include "imp.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <strings.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
puts( "[GLOBAL]" );
printf( " ServerName = %s\n", Conf_ServerName );
printf( " ServerInfo = %s\n", Conf_ServerInfo );
- printf( " ServerPwd = %s\n", Conf_ServerPwd );
+ 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( " Ports = " );
for( i = 0; i < Conf_ListenPorts_Count; i++ )
{
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 );
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( "" );
Conf_Server[i].lasttry = time( NULL ) - Conf_ConnectRetry + RECONNECT_DELAY;
}
}
- break;
}
} /* Conf_UnsetServer */
Conf_GetServer( CONN_ID Idx )
{
/* Get index of server in configuration structure */
-
- INT i;
-
+
+ INT i = 0;
+
assert( Idx > NONE );
for( i = 0; i < MAX_SERVERS; i++ )
INT i;
strcpy( Conf_ServerName, "" );
- sprintf( Conf_ServerInfo, "%s %s", PACKAGE, VERSION );
+ sprintf( Conf_ServerInfo, "%s %s", PACKAGE_NAME, PACKAGE_VERSION );
strcpy( Conf_ServerPwd, "" );
strcpy( Conf_ServerAdmin1, "" );
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 ));
+
Conf_ListenPorts_Count = 0;
+ strcpy( Conf_ListenAddress, "" );
Conf_UID = Conf_GID = 0;
Conf_OperCanMode = FALSE;
Conf_MaxConnections = -1;
+ Conf_MaxConnectionsIP = 5;
Conf_MaxJoins = 10;
/* Initialize server configuration structures */
/* Read configuration file. */
CHAR section[LINE_LEN], str[LINE_LEN], *var, *arg, *ptr;
- INT line, i;
+ INT line, i, n;
FILE *fd;
/* Open configuration file */
{
/* No configuration file found! */
Config_Error( LOG_ALERT, "Can't read configuration \"%s\": %s", NGIRCd_ConfFile, strerror( errno ));
- Config_Error( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE );
+ Config_Error( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME );
exit( 1 );
}
/* 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. */
+ * after the next disconnect and delete all unused servers.
+ * And delete all servers which are "duplicates" of servers
+ * that are already marked as "once" (such servers have been
+ * created by the last rehash but are now useless). */
for( i = 0; i < MAX_SERVERS; i++ )
{
if( Conf_Server[i].conn_id == NONE ) Init_Server_Struct( &Conf_Server[i] );
- else Conf_Server[i].flags |= CONF_SFLAG_ONCE;
+ else
+ {
+ /* This structure is in use ... */
+ if( Conf_Server[i].flags & CONF_SFLAG_ONCE )
+ {
+ /* Check for duplicates */
+ for( n = 0; n < MAX_SERVERS; n++ )
+ {
+ if( n == i ) continue;
+
+ if( Conf_Server[i].conn_id == Conf_Server[n].conn_id )
+ {
+ Init_Server_Struct( &Conf_Server[n] );
+ Log( LOG_DEBUG, "Deleted unused duplicate server %d (kept %d).", n, i );
+ }
+ }
+ }
+ else
+ {
+ /* Mark server as "once" */
+ Conf_Server[i].flags |= CONF_SFLAG_ONCE;
+ Log( LOG_DEBUG, "Marked server %d as \"once\"", i );
+ }
+ }
}
/* Initialize variables */
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, "MotdPhrase" ) == 0 )
+ {
+ /* "Message of the day" phrase (instead of file) */
+ if( strlcpy( Conf_MotdPhrase, Arg, sizeof( Conf_MotdPhrase )) >= sizeof( Conf_MotdPhrase )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"MotdPhrase\" too long!", NGIRCd_ConfFile, Line );
+ return;
+ }
+ if( strcasecmp( Var, "ChrootDir" ) == 0 )
+ {
+ /* directory for chroot() */
+ if( strlcpy( Conf_Chroot, Arg, sizeof( Conf_Chroot )) >= sizeof( Conf_Chroot )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"ChrootDir\" too long!", NGIRCd_ConfFile, Line );
+ return;
+ }
if( strcasecmp( Var, "ServerUID" ) == 0 )
{
/* UID the daemon should switch to */
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( LOG_WARNING, "%s, line %d: Value of \"ServerUID\" is not a number!", NGIRCd_ConfFile, Line );
else
#endif
Conf_UID = (UINT)atoi( 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( LOG_WARNING, "%s, line %d: Value of \"ServerGID\" is not a number!", NGIRCd_ConfFile, Line );
else
#endif
Conf_GID = (UINT)atoi( 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( LOG_WARNING, "%s, line %d: Value of \"MaxConnections\" is not a number!", NGIRCd_ConfFile, Line );
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( LOG_WARNING, "%s, line %d: Value of \"MaxConnectionsIP\" is not a number!", NGIRCd_ConfFile, Line );
+ 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( LOG_WARNING, "%s, line %d: Value of \"MaxJoins\" is not a number!", NGIRCd_ConfFile, Line );
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( LOG_WARNING, "%s, line %d: Value of \"Listen\" too long!", NGIRCd_ConfFile, Line );
+ }
+ return;
+ }
Config_Error( LOG_ERR, "%s, line %d (section \"Global\"): Unknown variable \"%s\"!", NGIRCd_ConfFile, Line, Var );
} /* Handle_GLOBAL */
{
/* 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( LOG_WARNING, "%s, line %d: Value of \"Group\" is not a number!", NGIRCd_ConfFile, Line );
else
#endif
New_Server.group = atoi( Arg );
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 );
+ exit( 1 );
+ }
+ }
+
+ if( Conf_ServerName[0] && ! strchr( Conf_ServerName, '.' ))
+ {
+ /* No dot in server name! */
+ 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 );
+ Config_Error( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME );
exit( 1 );
}
}
Config_Error( LOG_ALERT, "No administrator email address configured in \"%s\" ('AdminEMail')!", NGIRCd_ConfFile );
if( ! Configtest )
{
- Config_Error( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE );
+ Config_Error( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME );
exit( 1 );
}
}