X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=blobdiff_plain;f=src%2Fngircd%2Fngircd.c;h=63fc64bf2ef2ac6a34ff847bb9f59ad7d1b036d8;hp=8b2e4a82a774d6a9deb27ec71c262606051e2426;hb=6d11fb149707194e986b0d64af3d44f21e158fcc;hpb=cc336b75580d012c1caee58a252d1ad14b2cee23 diff --git a/src/ngircd/ngircd.c b/src/ngircd/ngircd.c index 8b2e4a82..63fc64bf 100644 --- a/src/ngircd/ngircd.c +++ b/src/ngircd/ngircd.c @@ -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 @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -41,12 +40,13 @@ #include "defines.h" #include "conn.h" #include "conf-ssl.h" -#include "client.h" #include "channel.h" #include "conf.h" #include "lists.h" #include "log.h" #include "parse.h" +#include "sighandlers.h" +#include "io.h" #include "irc.h" #ifdef ZEROCONF @@ -57,9 +57,6 @@ #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 )); @@ -68,10 +65,11 @@ static void Pidfile_Delete PARAMS(( void )); static void Fill_Version PARAMS(( void )); -static void Setup_FDStreams PARAMS(( void )); +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, @@ -96,7 +94,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; @@ -264,7 +262,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; @@ -288,13 +285,15 @@ main( int argc, const char *argv[] ) #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); + } - Initialize_Signal_Handler( ); + if (!Signals_Init()) { + Log(LOG_ALERT, "Fatal: Could not set up signal handlers: %s", strerror(errno)); + exit(1); + } /* * create protocol and server identification. @@ -361,7 +360,6 @@ Fill_Version( void ) #ifdef ZLIB if( NGIRCd_VersionAddition[0] ) strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition ); - strlcat( NGIRCd_VersionAddition, "ZLIB", sizeof NGIRCd_VersionAddition ); #endif #ifdef SSL_SUPPORT @@ -371,49 +369,46 @@ Fill_Version( void ) #ifdef TCPWRAP if( NGIRCd_VersionAddition[0] ) 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 ); - strlcat( NGIRCd_VersionAddition, "IDENT", sizeof NGIRCd_VersionAddition ); #endif +#ifdef PAM + if (NGIRCd_VersionAddition[0]) + strlcat(NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition); + strlcat(NGIRCd_VersionAddition, "PAM", sizeof NGIRCd_VersionAddition); +#endif #ifdef DEBUG if( NGIRCd_VersionAddition[0] ) strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition ); - strlcat( NGIRCd_VersionAddition, "DEBUG", sizeof NGIRCd_VersionAddition ); #endif #ifdef SNIFFER if( NGIRCd_VersionAddition[0] ) strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition ); - strlcat( NGIRCd_VersionAddition, "SNIFFER", sizeof NGIRCd_VersionAddition ); #endif #ifdef STRICT_RFC if( NGIRCd_VersionAddition[0] ) strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition ); - strlcat( NGIRCd_VersionAddition, "RFC", sizeof NGIRCd_VersionAddition ); #endif #ifdef IRCPLUS if( NGIRCd_VersionAddition[0] ) strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition ); - strlcat( NGIRCd_VersionAddition, "IRCPLUS", sizeof NGIRCd_VersionAddition ); #endif #ifdef WANT_IPV6 if (NGIRCd_VersionAddition[0]) strlcat(NGIRCd_VersionAddition, "+", sizeof(NGIRCd_VersionAddition)); - strlcat(NGIRCd_VersionAddition, "IPv6", sizeof(NGIRCd_VersionAddition)); #endif if( NGIRCd_VersionAddition[0] ) @@ -430,130 +425,6 @@ Fill_Version( void ) } /* 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 */ - - /** * Display copyright and version information of ngIRCd on the console. */ @@ -561,7 +432,7 @@ static void Show_Version( void ) { puts( NGIRCd_Version ); - puts( "Copyright (c)2001-2010 Alexander Barton () and Contributors." ); + puts( "Copyright (c)2001-2011 Alexander Barton () and Contributors." ); puts( "Homepage: \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." ); @@ -651,27 +522,16 @@ Pidfile_Create(pid_t pid) * Redirect stdin, stdout and stderr to apropriate file handles. */ static void -Setup_FDStreams( void ) +Setup_FDStreams(int fd) { - int fd; - - /* Test if we can open /dev/null for reading and writing. If not - * we are most probably chrooted already and the server has been - * restarted. So we simply don't try to redirect stdXXX ... */ - fd = open( "/dev/null", O_RDWR ); - if ( fd < 0 ) { - Log(LOG_WARNING, "Could not open /dev/null: %s", strerror(errno)); + if (fd < 0) return; - } fflush(stdout); fflush(stderr); /* Create new stdin(0), stdout(1) and stderr(2) descriptors */ dup2( fd, 0 ); dup2( fd, 1 ); dup2( fd, 2 ); - - /* Close newly opened file descriptor if not stdin/out/err */ - if( fd > 2 ) close( fd ); } /* Setup_FDStreams */ @@ -714,12 +574,19 @@ NGIRCd_Init( bool NGIRCd_NoDaemon ) bool chrooted = false; struct passwd *pwd; struct group *grp; - int real_errno; + int real_errno, fd = -1; pid_t pid; if (initialized) return true; + if (!NGIRCd_NoDaemon) { + /* open /dev/null before chroot() */ + fd = open( "/dev/null", O_RDWR); + if (fd < 0) + Log(LOG_WARNING, "Could not open /dev/null: %s", strerror(errno)); + } + if (!ConnSSL_InitLibrary()) Log(LOG_WARNING, "Warning: Error during SSL initialization, continuing ..."); @@ -727,15 +594,14 @@ NGIRCd_Init( bool NGIRCd_NoDaemon ) if( Conf_Chroot[0] ) { if( chdir( Conf_Chroot ) != 0 ) { Log( LOG_ERR, "Can't chdir() in ChrootDir (%s): %s", Conf_Chroot, strerror( errno )); - return false; + goto out; } if( chroot( Conf_Chroot ) != 0 ) { if (errno != EPERM) { Log( LOG_ERR, "Can't change root directory to \"%s\": %s", Conf_Chroot, strerror( errno )); - - return false; + goto out; } } else { chrooted = true; @@ -749,7 +615,7 @@ NGIRCd_Init( bool NGIRCd_NoDaemon ) if (! NGIRCd_getNobodyID(&Conf_UID, &Conf_GID)) { Log(LOG_WARNING, "Could not get user/group ID of user \"nobody\": %s", errno ? strerror(errno) : "not found" ); - return false; + goto out; } } @@ -759,7 +625,7 @@ NGIRCd_Init( bool NGIRCd_NoDaemon ) real_errno = errno; Log( LOG_ERR, "Can't change group ID to %u: %s", Conf_GID, strerror( errno )); if (real_errno != EPERM) - return false; + goto out; } } @@ -769,7 +635,7 @@ NGIRCd_Init( bool NGIRCd_NoDaemon ) real_errno = errno; Log(LOG_ERR, "Can't change user ID to %u: %s", Conf_UID, strerror(errno)); if (real_errno != EPERM) - return false; + goto out; } } @@ -802,7 +668,11 @@ NGIRCd_Init( bool NGIRCd_NoDaemon ) strerror(errno)); /* Detach stdin, stdout and stderr */ - Setup_FDStreams( ); + Setup_FDStreams(fd); + if (fd > 2) { + close(fd); + fd = -1; + } } pid = getpid(); @@ -829,8 +699,8 @@ NGIRCd_Init( bool NGIRCd_NoDaemon ) /* Change working directory to home directory of the user * we are running as (only when running in daemon mode and not in chroot) */ - - if ( pwd ) { + + if (pwd) { if (!NGIRCd_NoDaemon ) { if( chdir( pwd->pw_dir ) == 0 ) Log( LOG_DEBUG, "Changed working directory to \"%s\" ...", pwd->pw_dir ); @@ -842,7 +712,12 @@ NGIRCd_Init( bool NGIRCd_NoDaemon ) Log( LOG_ERR, "Can't get user informaton for UID %d!?", Conf_UID ); } -return true; + return true; + out: + if (fd > 2) + close(fd); + return false; } + /* -eof- */