+ char *ptr = strdup(str);
+ if (!ptr)
+ Config_Error(LOG_ERR, "Could not allocate mem for string: %s", str);
+ return ptr;
+}
+
+
+static void
+ports_puts(array *a)
+{
+ size_t len;
+ UINT16 *ports;
+ len = array_length(a, sizeof(UINT16));
+ if (len--) {
+ ports = (UINT16*) array_start(a);
+ printf("%u", (unsigned int) *ports);
+ while (len--) {
+ ports++;
+ printf(", %u", (unsigned int) *ports);
+ }
+ }
+ putc('\n', stdout);
+}
+
+
+static void
+ports_parse(array *a, int Line, char *Arg)
+{
+ char *ptr;
+ int port;
+ UINT16 port16;
+
+ array_trunc(a);
+
+ /* Ports on that the server should listen. More port numbers
+ * must be separated by "," */
+ ptr = strtok( Arg, "," );
+ while (ptr) {
+ ngt_TrimStr( ptr );
+ port = atol( ptr );
+ if (port > 0 && port < 0xFFFF) {
+ port16 = (UINT16) port;
+ if (!array_catb(a, (char*)&port16, sizeof port16))
+ Config_Error(LOG_ERR, "%s, line %d Could not add port number %ld: %s",
+ NGIRCd_ConfFile, Line, port, strerror(errno));
+ } else {
+ Config_Error( LOG_ERR, "%s, line %d (section \"Global\"): Illegal port number %ld!",
+ NGIRCd_ConfFile, Line, port );
+ }
+
+ ptr = strtok( NULL, "," );
+ }
+}
+
+
+GLOBAL void
+Conf_Init( void )
+{
+ Read_Config( true );
+ Validate_Config(false, false);
+} /* Config_Init */
+
+
+GLOBAL bool
+Conf_Rehash( void )
+{
+ if (!Read_Config(false))
+ return false;
+ Validate_Config(false, true);
+
+ /* Update CLIENT structure of local server */
+ Client_SetInfo(Client_ThisServer(), Conf_ServerInfo);
+ return true;
+} /* Config_Rehash */
+
+
+static const char*
+yesno_to_str(int boolean_value)
+{
+ if (boolean_value)
+ return "yes";
+ return "no";
+}
+
+
+GLOBAL int
+Conf_Test( void )
+{
+ /* Read configuration, validate and output it. */
+
+ struct passwd *pwd;
+ struct group *grp;
+ unsigned int i;
+ char *topic;
+
+ Use_Log = false;
+
+ Read_Config( true );
+ Validate_Config(true, false);
+
+ /* If stdin and stdout ("you can read our nice message and we can
+ * read in your keypress") are valid tty's, wait for a key: */
+ if( isatty( fileno( stdin )) && isatty( fileno( stdout ))) {
+ puts( "OK, press enter to see a dump of your service configuration ..." );
+ getchar( );
+ } else {
+ puts( "Ok, dump of your server configuration follows:\n" );
+ }
+
+ puts( "[GLOBAL]" );
+ 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);
+ fputs(" Ports = ", stdout);
+
+ ports_puts(&Conf_ListenPorts);
+
+ 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 );
+ grp = getgrgid( Conf_GID );
+ if( grp ) printf( " ServerGID = %s\n", grp->gr_name );
+ else printf( " ServerGID = %ld\n", (long)Conf_GID );
+ printf( " PingTimeout = %d\n", Conf_PingTimeout );
+ printf( " PongTimeout = %d\n", Conf_PongTimeout );
+ printf( " ConnectRetry = %d\n", Conf_ConnectRetry );
+ printf( " OperCanUseMode = %s\n", yesno_to_str(Conf_OperCanMode));
+ printf( " OperServerMode = %s\n", yesno_to_str(Conf_OperServerMode));
+ printf( " PredefChannelsOnly = %s\n", yesno_to_str(Conf_PredefChannelsOnly));
+ printf( " NoDNS = %s\n", yesno_to_str(Conf_NoDNS));
+
+#ifdef WANT_IPV6
+ printf(" ListenIPv6 = %s\n", yesno_to_str(Conf_ListenIPv6));
+ printf(" ListenIPv4 = %s\n", yesno_to_str(Conf_ListenIPv4));
+ printf(" ConnectIPv4 = %s\n", yesno_to_str(Conf_ConnectIPv6));
+ printf(" ConnectIPv6 = %s\n", yesno_to_str(Conf_ConnectIPv4));
+#endif
+ printf( " MaxConnections = %ld\n", Conf_MaxConnections);
+ printf( " MaxConnectionsIP = %d\n", Conf_MaxConnectionsIP);
+ printf( " MaxJoins = %d\n", Conf_MaxJoins>0 ? Conf_MaxJoins : -1);
+ printf( " MaxNickLength = %u\n\n", Conf_MaxNickLength - 1);
+
+ for( i = 0; i < Conf_Oper_Count; i++ ) {
+ if( ! Conf_Oper[i].name[0] ) continue;
+
+ /* Valid "Operator" section */
+ 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( "" );
+ }
+
+ for( i = 0; i < MAX_SERVERS; i++ ) {
+ if( ! Conf_Server[i].name[0] ) continue;
+
+ /* Valid "Server" section */
+ puts( "[SERVER]" );
+ printf( " Name = %s\n", Conf_Server[i].name );
+ printf( " Host = %s\n", Conf_Server[i].host );
+ printf( " Port = %u\n", (unsigned int)Conf_Server[i].port );
+ printf( " MyPassword = %s\n", Conf_Server[i].pwd_in );
+ printf( " PeerPassword = %s\n", Conf_Server[i].pwd_out );
+ printf( " Group = %d\n", Conf_Server[i].group );
+ printf( " Passive = %s\n\n", Conf_Server[i].flags & CONF_SFLAG_DISABLED ? "yes" : "no");
+ }
+
+ for( i = 0; i < Conf_Channel_Count; i++ ) {
+ if( ! Conf_Channel[i].name[0] ) continue;
+
+ /* Valid "Channel" section */
+ puts( "[CHANNEL]" );
+ printf( " Name = %s\n", Conf_Channel[i].name );
+ printf( " Modes = %s\n", Conf_Channel[i].modes );
+ printf( " Key = %s\n", Conf_Channel[i].key );
+ printf( " MaxUsers = %lu\n", Conf_Channel[i].maxusers );
+
+ topic = (char*)array_start(&Conf_Channel[i].topic);
+ printf( " Topic = %s\n\n", topic ? topic : "");
+ }
+
+ return 0;
+} /* 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;
+ time_t t;
+
+ /* 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].flags & CONF_SFLAG_ONCE ) {
+ /* Delete configuration here */
+ Init_Server_Struct( &Conf_Server[i] );
+ } else {
+ /* Set time for next connect attempt */
+ t = time(NULL);
+ if (Conf_Server[i].lasttry < t - Conf_ConnectRetry) {
+ /* The connection has been "long", so we don't
+ * require the next attempt to be delayed. */
+ Conf_Server[i].lasttry =
+ t - Conf_ConnectRetry + RECONNECT_DELAY;
+ } else
+ Conf_Server[i].lasttry = t;
+ }
+ }
+} /* 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 */