]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/sighandlers.c
Merge branch 'bug92-xop'
[ngircd-alex.git] / src / ngircd / sighandlers.c
index f3ce24feb4935b77d13577ab66e526a7bedb9c81..a219105f4b5aff571e045f22d58f0f5fc4d17162 100644 (file)
 #include <sys/wait.h>
 
 #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"
 
 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 +68,14 @@ 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,10 +84,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 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." );
+} /* Rehash */
+
+
 /**
  * Signal handler of ngIRCd.
  * This function is called whenever ngIRCd catches a signal sent by the
@@ -66,7 +148,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 +158,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
        }
 
        /*
@@ -105,10 +208,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 +231,15 @@ 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));
@@ -140,18 +257,20 @@ static void Sig_callback(int fd, short UNUSED what)
 }
 
 
-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.
  */
-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,9 +303,8 @@ 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 */
 
 
 /**
@@ -196,7 +314,8 @@ bool Signals_Init(void)
  * 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 +329,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- */