#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;
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;
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
* 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:
/* 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
}
/*
* 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)
+ Dump_State();
+ break;
default:
Log(LOG_DEBUG, "Got signal %d! Ignored.", Signal);
#endif
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));
}
-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;
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 */
/**
* 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
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]);