X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fngircd%2Fsighandlers.c;h=effef44d8fb8b391e1b222eb2eaabee296632e48;hb=27b9d32bf2a851c4acbfdc4d9aa5a55d12c92c10;hp=f3ce24feb4935b77d13577ab66e526a7bedb9c81;hpb=1fe17e246cba4ee2f4349196c544296790ab5d55;p=ngircd-alex.git diff --git a/src/ngircd/sighandlers.c b/src/ngircd/sighandlers.c index f3ce24fe..effef44d 100644 --- a/src/ngircd/sighandlers.c +++ b/src/ngircd/sighandlers.c @@ -1,5 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon + * Copyright (c)2001-2013 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 @@ -25,6 +26,10 @@ #include #include "imp.h" +#include "conn.h" +#include "conf-ssl.h" +#include "channel.h" +#include "conf.h" #include "io.h" #include "log.h" #include "ngircd.h" @@ -32,7 +37,28 @@ static int signalpipe[2]; -static void Signal_Block(int sig) +static const int signals_catch[] = { + SIGINT, SIGQUIT, SIGTERM, SIGHUP, SIGCHLD, SIGUSR1, SIGUSR2 +}; + +#ifdef DEBUG + +static void +Dump_State(void) +{ + Log(LOG_DEBUG, "--- Internal server state: %s ---", + Client_ID(Client_ThisServer())); + Log(LOG_DEBUG, "time()=%ld", time(NULL)); + Conf_DebugDump(); + Conn_DebugDump(); + Client_DebugDump(); + Log(LOG_DEBUG, "--- End of state dump ---"); +} /* Dump_State */ + +#endif + +static void +Signal_Block(int sig) { #ifdef HAVE_SIGPROCMASK sigset_t set; @@ -41,11 +67,13 @@ static void Signal_Block(int sig) sigaddset(&set, sig); sigprocmask(SIG_BLOCK, &set, NULL); +#else + sigblock(sig); #endif } - -static void Signal_Unblock(int sig) +static void +Signal_Unblock(int sig) { #ifdef HAVE_SIGPROCMASK sigset_t set; @@ -54,9 +82,62 @@ static void Signal_Unblock(int sig) sigaddset(&set, sig); sigprocmask(SIG_UNBLOCK, &set, NULL); +#else + int old = sigblock(0) & ~sig; + sigsetmask(old); #endif } +/** + * Reload the server configuration file. + */ +static void +Rehash(void) +{ + char old_name[CLIENT_ID_LEN]; + unsigned old_nicklen; + + Log( LOG_NOTICE|LOG_snotice, "Re-reading configuration NOW!" ); + + /* Remember old server name and nickname 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 nickname 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 of 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." ); +} /* Rehash */ /** * Signal handler of ngIRCd. @@ -66,7 +147,8 @@ static void Signal_Unblock(int sig) * It blocks the signal and queues it for later execution by Signal_Handler_BH. * @param Signal Number of the signal to handle. */ -static void Signal_Handler(int Signal) +static void +Signal_Handler(int Signal) { switch (Signal) { case SIGTERM: @@ -75,15 +157,35 @@ static void Signal_Handler(int Signal) /* shut down sever */ NGIRCd_SignalQuit = true; return; - case SIGHUP: - /* re-read configuration */ - NGIRCd_SignalRehash = true; - return; case SIGCHLD: /* child-process exited, avoid zombies */ while (waitpid( -1, NULL, WNOHANG) > 0) ; return; +#ifdef DEBUG + case SIGUSR1: + if (! NGIRCd_Debug) { + Log(LOG_INFO|LOG_snotice, + "Got SIGUSR1, debug mode activated."); +#ifdef SNIFFER + strcpy(NGIRCd_DebugLevel, "2"); + NGIRCd_Debug = true; + NGIRCd_Sniffer = true; +#else + strcpy(NGIRCd_DebugLevel, "1"); + NGIRCd_Debug = true; +#endif /* SNIFFER */ + } else { + Log(LOG_INFO|LOG_snotice, + "Got SIGUSR1, debug mode deactivated."); + strcpy(NGIRCd_DebugLevel, ""); + NGIRCd_Debug = false; +#ifdef SNIFFER + NGIRCd_Sniffer = false; +#endif /* SNIFFER */ + } + return; +#endif } /* @@ -95,7 +197,6 @@ static void Signal_Handler(int Signal) Signal_Block(Signal); } /* Signal_Handler */ - /** * Signal processing handler of ngIRCd. * This function is called from the main conn event loop in (io_dispatch) @@ -105,10 +206,22 @@ static void Signal_Handler(int Signal) * thus its not necessary to only use functions that are signal safe. * @param Signal Number of the signal that was queued. */ -static void Signal_Handler_BH(int Signal) +static void +Signal_Handler_BH(int Signal) { switch (Signal) { + case SIGHUP: + /* re-read configuration */ + Rehash(); + break; #ifdef DEBUG + case SIGUSR2: + if (NGIRCd_Debug) { + Log(LOG_INFO|LOG_snotice, + "Got SIGUSR2, dumping internal state ..."); + Dump_State(); + } + break; default: Log(LOG_DEBUG, "Got signal %d! Ignored.", Signal); #endif @@ -116,13 +229,14 @@ static void Signal_Handler_BH(int Signal) Signal_Unblock(Signal); } -static void Sig_callback(int fd, short UNUSED what) +static void +Signal_Callback(int fd, short UNUSED what) { int sig, ret; (void) what; do { - ret = read(fd, &sig, sizeof(sig)); + ret = (int)read(fd, &sig, sizeof(sig)); if (ret == sizeof(int)) Signal_Handler_BH(sig); } while (ret == sizeof(int)); @@ -131,27 +245,29 @@ static void Sig_callback(int fd, short UNUSED what) if (errno == EAGAIN || errno == EINTR) return; - Log(LOG_EMERG, "read from signal pipe: %s", strerror(errno)); + Log(LOG_EMERG, "Read from signal pipe: %s - Exiting!", + strerror(errno)); exit(1); } - Log(LOG_EMERG, "EOF on signal pipe"); + Log(LOG_EMERG, "EOF on signal pipe!? - Exiting!"); exit(1); } - -static const int signals_catch[] = { SIGINT, SIGQUIT, SIGTERM, SIGHUP, SIGCHLD, SIGUSR1, SIGUSR2 }; /** * Initialize the signal handlers, catch * those signals we are interested in and sets SIGPIPE to be ignored. - * @return true if initialization was sucessful. + * @return true if initialization was successful. */ -bool Signals_Init(void) +bool +Signals_Init(void) { size_t i; #ifdef HAVE_SIGACTION struct sigaction saction; #endif + if (signalpipe[0] > 0 || signalpipe[1] > 0) + return true; if (pipe(signalpipe)) return false; @@ -184,19 +300,18 @@ bool Signals_Init(void) signal(SIGPIPE, SIG_IGN); #endif - return io_event_create(signalpipe[0], IO_WANTREAD, - Sig_callback); -} /* Initialize_Signal_Handler */ - + return io_event_create(signalpipe[0], IO_WANTREAD, Signal_Callback); +} /* Signals_Init */ /** - * Restores signals to their default behaviour. + * Restores signals to their default behavior. * * This should be called after a fork() in the new * child prodcess, especially when we are about to call * 3rd party code (e.g. PAM). */ -void Signals_Exit(void) +void +Signals_Exit(void) { size_t i; #ifdef HAVE_SIGACTION @@ -210,11 +325,12 @@ void Signals_Exit(void) sigaction(SIGPIPE, &saction, NULL); #else for (i=0; i < C_ARRAY_SIZE(signals_catch) ; i++) - sigaction(signals_catch[i], &saction, NULL); + signal(signals_catch[i], SIG_DFL); signal(SIGPIPE, SIG_DFL); #endif close(signalpipe[1]); close(signalpipe[0]); + signalpipe[0] = signalpipe[1] = 0; } /* -eof- */