]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/ngircd.c
New configuration option "RequireAuthPing": PING-PONG on login
[ngircd-alex.git] / src / ngircd / ngircd.c
index 4d329d2ade1c89724bf975c98cb758f12fa310b0..74a998800f364376a87efb290cd2d0dc030a2ab4 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2010 Alexander Barton (alex@barton.de).
+ * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -9,7 +9,6 @@
  * Please read the file COPYING, README and AUTHORS for more information.
  */
 
-
 #include "portab.h"
 
 /**
@@ -29,7 +28,6 @@
 #include <time.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <sys/wait.h>
 #include <fcntl.h>
 #include <pwd.h>
 #include <grp.h>
 #include "lists.h"
 #include "log.h"
 #include "parse.h"
+#include "sighandlers.h"
+#include "io.h"
 #include "irc.h"
 
-#ifdef ZEROCONF
-#include "rendezvous.h"
-#endif
-
 #include "exp.h"
 #include "ngircd.h"
 
 
-static void Initialize_Signal_Handler PARAMS(( void ));
-static void Signal_Handler PARAMS(( int Signal ));
-
 static void Show_Version PARAMS(( void ));
 static void Show_Help PARAMS(( void ));
 
@@ -71,13 +64,16 @@ static void Setup_FDStreams PARAMS(( int fd ));
 
 static bool NGIRCd_Init PARAMS(( bool ));
 
+
 /**
  * The main() function of ngIRCd.
+ *
  * Here all starts: this function is called by the operating system loader,
  * it is the first portion of code executed of ngIRCd.
- * @param argc The number of arguments passed to ngIRCd on the command line.
- * @param argv An array containing all the arguments passed to ngIRCd.
- * @return Global exit code of ngIRCd, zero on success.
+ *
+ * @param argc The number of arguments passed to ngIRCd on the command line.
+ * @param argv An array containing all the arguments passed to ngIRCd.
+ * @return     Global exit code of ngIRCd, zero on success.
  */
 GLOBAL int
 main( int argc, const char *argv[] )
@@ -95,7 +91,7 @@ main( int argc, const char *argv[] )
 
        umask( 0077 );
 
-       NGIRCd_SignalQuit = NGIRCd_SignalRestart = NGIRCd_SignalRehash = false;
+       NGIRCd_SignalQuit = NGIRCd_SignalRestart = false;
        NGIRCd_Passive = false;
 #ifdef DEBUG
        NGIRCd_Debug = false;
@@ -238,7 +234,7 @@ main( int argc, const char *argv[] )
                }
        }
 
-       /* Debug-Level (for IRCs "VERSION" command) */
+       /* Debug level for "VERSION" command */
        NGIRCd_DebugLevel[0] = '\0';
 #ifdef DEBUG
        if( NGIRCd_Debug ) strcpy( NGIRCd_DebugLevel, "1" );
@@ -263,7 +259,6 @@ main( int argc, const char *argv[] )
                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;
 
@@ -282,24 +277,23 @@ main( int argc, const char *argv[] )
                 * called with already dropped privileges ... */
                Channel_Init( );
                Client_Init( );
-#ifdef ZEROCONF
-               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
+               if (!io_library_init(CONNECTION_POOL)) {
+                       Log(LOG_ALERT, "Fatal: Cannot initialize IO routines: %s", strerror(errno));
+                       exit(1);
+               }
+
+               if (!Signals_Init()) {
+                       Log(LOG_ALERT, "Fatal: Could not set up signal handlers: %s", strerror(errno));
+                       exit(1);
+               }
 
-               Initialize_Signal_Handler( );
+               srandom(getpid());
 
-               /*
-                * create protocol and server identification.
-                * The syntax used by ngIRCd in PASS commands and the extended flags
-                * are described in doc/Protocol.txt
-                */
+               /* Create protocol and server identification. The syntax
+                * used by ngIRCd in PASS commands and the known "extended
+                * flags" are described in doc/Protocol.txt. */
 #ifdef IRCPLUS
                snprintf( NGIRCd_ProtoID, sizeof NGIRCd_ProtoID, "%s%s %s|%s:%s", PROTOVER, PROTOIRCPLUS, PACKAGE_NAME, PACKAGE_VERSION, IRCPLUSFLAGS );
 #ifdef ZLIB
@@ -324,15 +318,11 @@ main( int argc, const char *argv[] )
                        Pidfile_Delete( );
                        exit( 1 );
                }
-               
-               /* Hauptschleife */
+
+               /* Main Run Loop */
                Conn_Handler( );
 
-               /* Alles abmelden */
                Conn_Exit( );
-#ifdef ZEROCONF
-               Rendezvous_Exit( );
-#endif
                Client_Exit( );
                Channel_Exit( );
                Log_Exit( );
@@ -344,10 +334,12 @@ main( int argc, const char *argv[] )
 
 
 /**
- * Generate ngIRCd "version string".
- * This string is generated once and then stored in NGIRCd_Version for
- * further usage, for example by the IRC command VERSION and the --version
- * command line switch.
+ * Generate ngIRCd "version strings".
+ *
+ * The ngIRCd version information is generated once and then stored in the
+ * NGIRCd_Version and NGIRCd_VersionAddition string variables for further
+ * usage, for example by the IRC command "VERSION" and the --version command
+ * line switch.
  */
 static void
 Fill_Version( void )
@@ -371,11 +363,6 @@ Fill_Version( void )
                        strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
        strlcat( NGIRCd_VersionAddition, "TCPWRAP", sizeof NGIRCd_VersionAddition );
 #endif
-#ifdef ZEROCONF
-       if( NGIRCd_VersionAddition[0] )
-               strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
-       strlcat( NGIRCd_VersionAddition, "ZEROCONF", sizeof NGIRCd_VersionAddition );
-#endif
 #ifdef IDENTAUTH
        if( NGIRCd_VersionAddition[0] )
                strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
@@ -422,131 +409,7 @@ Fill_Version( void )
 
        snprintf(NGIRCd_Version, sizeof NGIRCd_Version, "%s %s-%s",
                 PACKAGE_NAME, PACKAGE_VERSION, NGIRCd_VersionAddition);
-       } /* Fill_Version */
-
-
-/**
- * Reload the server configuration file.
- */
-GLOBAL void
-NGIRCd_Rehash( void )
-{
-       char old_name[CLIENT_ID_LEN];
-       unsigned old_nicklen;
-
-       Log( LOG_NOTICE|LOG_snotice, "Re-reading configuration NOW!" );
-       NGIRCd_SignalRehash = false;
-
-       /* Remember old server name and nick name length */
-       strlcpy( old_name, Conf_ServerName, sizeof old_name );
-       old_nicklen = Conf_MaxNickLength;
-
-       /* Re-read configuration ... */
-       if (!Conf_Rehash( ))
-               return;
-
-       /* Close down all listening sockets */
-       Conn_ExitListeners( );
-
-       /* Recover old server name and nick name length: these values can't
-        * be changed during run-time */
-       if (strcmp(old_name, Conf_ServerName) != 0 ) {
-               strlcpy(Conf_ServerName, old_name, sizeof Conf_ServerName);
-               Log(LOG_ERR, "Can't change \"ServerName\" on runtime! Ignored new name.");
-       }
-       if (old_nicklen != Conf_MaxNickLength) {
-               Conf_MaxNickLength = old_nicklen;
-               Log(LOG_ERR, "Can't change \"MaxNickLength\" on runtime! Ignored new value.");
-       }
-
-       /* Create new pre-defined channels */
-       Channel_InitPredefined( );
-
-       if (!ConnSSL_InitLibrary())
-               Log(LOG_WARNING, "Re-Initializing SSL failed, using old keys");
-
-       /* Start listening on sockets */
-       Conn_InitListeners( );
-
-       /* Sync configuration with established connections */
-       Conn_SyncServerStruct( );
-
-       Log( LOG_NOTICE|LOG_snotice, "Re-reading of configuration done." );
-} /* NGIRCd_Rehash */
-
-
-/**
- * Initialize the signal handler.
- */
-static void
-Initialize_Signal_Handler( void )
-{
-#ifdef HAVE_SIGACTION
-       struct sigaction saction;
-
-       memset( &saction, 0, sizeof( saction ));
-       saction.sa_handler = Signal_Handler;
-#ifdef SA_RESTART
-       saction.sa_flags |= SA_RESTART;
-#endif
-#ifdef SA_NOCLDWAIT
-       saction.sa_flags |= SA_NOCLDWAIT;
-#endif
-
-       sigaction(SIGINT, &saction, NULL);
-       sigaction(SIGQUIT, &saction, NULL);
-       sigaction(SIGTERM, &saction, NULL);
-       sigaction(SIGHUP, &saction, NULL);
-       sigaction(SIGCHLD, &saction, NULL);
-
-       /* we handle write errors properly; ignore SIGPIPE */
-       saction.sa_handler = SIG_IGN;
-       sigaction(SIGPIPE, &saction, NULL);
-#else
-       signal(SIGINT, Signal_Handler);
-       signal(SIGQUIT, Signal_Handler);
-       signal(SIGTERM, Signal_Handler);
-       signal(SIGHUP, Signal_Handler);
-       signal(SIGCHLD, Signal_Handler);
-
-       signal(SIGPIPE, SIG_IGN);
-#endif
-} /* Initialize_Signal_Handler */
-
-
-/**
- * Signal handler of ngIRCd.
- * This function is called whenever ngIRCd catches a signal sent by the
- * user and/or the system to it. For example SIGTERM and SIGHUP.
- * @param Signal Number of the signal to handle.
- */
-static void
-Signal_Handler( int Signal )
-{
-       switch( Signal )
-       {
-               case SIGTERM:
-               case SIGINT:
-               case SIGQUIT:
-                       /* shut down sever */
-                       NGIRCd_SignalQuit = true;
-                       break;
-               case SIGHUP:
-                       /* re-read configuration */
-                       NGIRCd_SignalRehash = true;
-                       break;
-               case SIGCHLD:
-                       /* child-process exited, avoid zombies */
-                       while (waitpid( -1, NULL, WNOHANG) > 0)
-                               ;
-                       break;
-#ifdef DEBUG
-               default:
-                       /* unbekanntes bzw. unbehandeltes Signal */
-                       Log( LOG_DEBUG, "Got signal %d! Ignored.", Signal );
-#endif
-       }
-} /* Signal_Handler */
+} /* Fill_Version */
 
 
 /**
@@ -556,7 +419,7 @@ static void
 Show_Version( void )
 {
        puts( NGIRCd_Version );
-       puts( "Copyright (c)2001-2010 Alexander Barton (<alex@barton.de>) and Contributors." );
+       puts( "Copyright (c)2001-2011 Alexander Barton (<alex@barton.de>) and Contributors." );
        puts( "Homepage: <http://ngircd.barton.de/>\n" );
        puts( "This is free software; see the source for copying conditions. There is NO" );
        puts( "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." );
@@ -606,7 +469,8 @@ Pidfile_Delete( void )
 
 /**
  * Create the file containing the process ID of ngIRCd ("PID file").
- * @param pid The process ID to be stored in this file.
+ *
+ * @param pid  The process ID to be stored in this file.
  */
 static void
 Pidfile_Create(pid_t pid)
@@ -644,6 +508,8 @@ Pidfile_Create(pid_t pid)
 
 /**
  * Redirect stdin, stdout and stderr to apropriate file handles.
+ *
+ * @param fd   The file handle stdin, stdout and stderr should be redirected to.
  */
 static void
 Setup_FDStreams(int fd)
@@ -659,6 +525,13 @@ Setup_FDStreams(int fd)
 } /* Setup_FDStreams */
 
 
+/**
+ * Get user and group ID of unprivileged "nobody" user.
+ *
+ * @param uid  User ID
+ * @param gid  Group ID
+ * @return     true on success.
+ */
 static bool
 NGIRCd_getNobodyID(uid_t *uid, gid_t *gid )
 {
@@ -683,14 +556,21 @@ NGIRCd_getNobodyID(uid_t *uid, gid_t *gid )
        if ( !pwd->pw_uid || !pwd->pw_gid)
                return false;
 
-       *uid = pwd->pw_uid;     
+       *uid = pwd->pw_uid;
        *gid = pwd->pw_gid;
        endpwent();
 
-       return true;    
-}
+       return true;
+} /* NGIRCd_getNobodyID */
 
 
+/**
+ * Initialize ngIRCd daemon.
+ *
+ * @param NGIRCd_NoDaemon      Set to true if ngIRCd should run in the
+ *                             foreground and not as a daemon.
+ * @return                     true on success.
+ */
 static bool
 NGIRCd_Init( bool NGIRCd_NoDaemon ) 
 {
@@ -841,6 +721,7 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
        if (fd > 2)
                close(fd);
        return false;
-}
+} /* NGIRCd_Init */
+
 
 /* -eof- */