+ /* Initialize global variables */
+ NGIRCd_Start = time( NULL );
+ (void)strftime( NGIRCd_StartStr, 64, "%a %b %d %Y at %H:%M:%S (%Z)", localtime( &NGIRCd_Start ));
+
+ NGIRCd_SignalRehash = false;
+ NGIRCd_SignalRestart = false;
+ NGIRCd_SignalQuit = false;
+
+ /* Initialize modules, part I */
+ Log_Init( );
+ Conf_Init( );
+
+ if( Conf_Chroot[0] )
+ {
+ /* Chroot */
+ if( chdir( Conf_Chroot ) != 0 ) Log( LOG_ERR, "Can't chdir() in ChrootDir (%s): %s", Conf_Chroot, strerror( errno ));
+
+ if( chroot( Conf_Chroot ) != 0 ) Log( LOG_ERR, "Can't change root directory to \"%s\": %s", Conf_Chroot, strerror( errno ));
+ else Log( LOG_INFO, "Changed root and working directory to \"%s\".", Conf_Chroot );
+ }
+
+ if( Conf_GID != 0 )
+ {
+ /* Set new group ID */
+ if( setgid( Conf_GID ) != 0 ) Log( LOG_ERR, "Can't change group ID to %u: %s", Conf_GID, strerror( errno ));
+ }
+ if( Conf_UID != 0 )
+ {
+ /* Set new user ID */
+ if( setuid( Conf_UID ) != 0 ) Log( LOG_ERR, "Can't change user ID to %u: %s", Conf_UID, strerror( errno ));
+ }
+
+ /* Normally a child process is forked which isn't any longer
+ * connected to ther controlling terminal. Use "--nodaemon"
+ * to disable this "daemon mode" (useful for debugging). */
+ if( ! NGIRCd_NoDaemon )
+ {
+ /* fork child process */
+ pid = (long)fork( );
+ if( pid > 0 )
+ {
+ /* "Old" process: exit. */
+ exit( 0 );
+ }
+ if( pid < 0 )
+ {
+ /* Error!? */
+ fprintf( stderr, "%s: Can't fork: %s!\nFatal error, exiting now ...\n", PACKAGE_NAME, strerror( errno ));
+ exit( 1 );
+ }
+
+ /* New child process */
+ (void)setsid( );
+ chdir( "/" );
+
+ /* Detach stdin, stdout and stderr */
+ Setup_FDStreams( );
+ }
+
+ /* Create PID file */
+ pid = (long) getpid( );
+ Pidfile_Create( pid );
+
+ /* Show user, group, and PID of the running daemon */
+ pwd = getpwuid( getuid( )); grp = getgrgid( getgid( ));
+ Log( LOG_INFO, "Running as user %s(%ld), group %s(%ld), with PID %ld.", pwd ? pwd->pw_name : "unknown", (long)getuid( ), grp ? grp->gr_name : "unknown", (long)getgid( ), pid);
+
+ /* Change working directory to home directory of the user
+ * we are running as (when not running chroot()'ed!) */
+ if( Conf_UID != 0 && ! Conf_Chroot[0] )
+ {
+ struct passwd *pwd;
+
+ pwd = getpwuid( Conf_UID );
+ if( pwd != NULL )
+ {
+ if( chdir( pwd->pw_dir ) == 0 ) Log( LOG_DEBUG, "Changed working directory to \"%s\" ...", pwd->pw_dir );
+ else Log( LOG_ERR, "Can't change working directory to \"%s\": %s", pwd->pw_dir, strerror( errno ));
+ }
+ else Log( LOG_ERR, "Can't get user informaton for UID %d!?", Conf_UID );
+ }
+
+ /* Initialize modules, part II: these functions are eventually
+ * called with already dropped privileges ... */
+ Resolve_Init( );
+ Lists_Init( );
+ Channel_Init( );
+ Client_Init( );
+#ifdef RENDEZVOUS
+ Rendezvous_Init( );
+#endif
+ Conn_Init( );
+
+#ifdef DEBUG
+ /* Redirect stderr handle to "error file" for debugging
+ * when not running in "no daemon" mode: */
+ if( ! NGIRCd_NoDaemon ) Log_InitErrorfile( );
+#endif
+
+ /* Signal-Handler initialisieren */
+ Initialize_Signal_Handler( );
+
+ /* Protokoll- und Server-Identifikation erzeugen. Die vom ngIRCd
+ * beim PASS-Befehl verwendete Syntax sowie die erweiterten Flags
+ * sind in doc/Protocol.txt beschrieben. */
+#ifdef IRCPLUS
+ sprintf( NGIRCd_ProtoID, "%s%s %s|%s:%s", PROTOVER, PROTOIRCPLUS, PACKAGE_NAME, PACKAGE_VERSION, IRCPLUSFLAGS );
+#ifdef ZLIB
+ strcat( NGIRCd_ProtoID, "Z" );
+#endif
+ if( Conf_OperCanMode ) strcat( NGIRCd_ProtoID, "o" );
+#else
+ sprintf( NGIRCd_ProtoID, "%s%s %s|%s", PROTOVER, PROTOIRC, PACKAGE_NAME, PACKAGE_VERSION );
+#endif
+ strcat( NGIRCd_ProtoID, " P" );
+#ifdef ZLIB
+ strcat( NGIRCd_ProtoID, "Z" );
+#endif
+ Log( LOG_DEBUG, "Protocol and server ID is \"%s\".", NGIRCd_ProtoID );
+
+ /* Vordefinierte Channels anlegen */
+ Channel_InitPredefined( );
+
+ /* Listen-Ports initialisieren */
+ if( Conn_InitListeners( ) < 1 )
+ {
+ Log( LOG_ALERT, "Server isn't listening on a single port!" );
+ Log( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME );
+ Pidfile_Delete( );
+ exit( 1 );
+ }
+
+ /* Hauptschleife */