src/nexus.c
changeset 48 4841f4398fd2
parent 26 aec062af155d
child 53 12d806823775
--- a/src/nexus.c	Thu Mar 12 23:15:57 2009 +0200
+++ b/src/nexus.c	Thu Mar 12 23:54:03 2009 +0200
@@ -1,12 +1,14 @@
 
-#include "log.h"
 #include "irc_net.h"
 #include "irc_log.h"
+#include "signals.h"
+#include "log.h"
 
 #include <stdlib.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <getopt.h>
+#include <signal.h>
 
 #include <event2/event.h>
 
@@ -44,11 +46,49 @@
     printf(" --log-channel          channel to log\n");
 }
 
+/**
+ * Context for async nexus operation
+ */
+struct nexus_ctx {
+    /** The libevent base */
+    struct event_base *ev_base;
+
+    /** The one IRC network */
+    struct irc_net *net;
+};
+
+void on_sigint (evutil_socket_t sig, short what, void *arg)
+{
+    struct nexus_ctx *ctx = arg;
+
+    (void) sig;
+    (void) what;
+    
+    if (ctx->net && ctx->net->conn && !ctx->net->conn->quitting) {
+        log_info("Quitting...");
+
+        // quit it
+        irc_net_quit(ctx->net, "Goodbye, cruel world ;(");
+
+    } else {
+        log_error("Aborting");
+        
+        // die
+        if (ctx->net) {
+            irc_net_destroy(ctx->net);
+            ctx->net = NULL;
+        }
+
+        // exit
+        event_base_loopexit(ctx->ev_base, NULL);
+    }
+}
+
 int main (int argc, char **argv) 
 {
     int opt, option_index;
-    struct event_base *ev_base;
-    struct irc_net *net;
+    struct nexus_ctx ctx;
+    struct signals *signals;
     struct error_info err;
 
     struct irc_net_info net_info = {
@@ -113,30 +153,41 @@
     }
 
     // initialize libevent
-    if ((ev_base = event_base_new()) == NULL)
+    if ((ctx.ev_base = event_base_new()) == NULL)
         FATAL("event_base_new");
+    
+    // initialize signal handlers
+    if ((ERROR_CODE(&err) = signals_create(&signals, ctx.ev_base)))
+        FATAL("signals_create");
 
     // initialize sock module
-    if (sock_init(ev_base, &err))
+    if (sock_init(ctx.ev_base, &err))
         FATAL_ERROR(&err, "sock_init");
     
     // the IRC network
-    if (irc_net_create(&net, &net_info, &err))
+    if (irc_net_create(&ctx.net, &net_info, &err))
         FATAL_ERROR(&err, "irc_net_create");
+
+    // add our signal handlers
+    if (
+            (ERROR_CODE(&err) = signals_add(signals, SIGPIPE, &signals_ignore, signals))
+        ||  (ERROR_CODE(&err) = signals_add(signals, SIGINT, &on_sigint, &ctx))
+    )
+        FATAL_ERROR(&err, "signals_add");
     
     // logging?
     if (log_info.db_info || log_chan_info.channel) {
         // get the channel
-        if (log_chan_info.channel && (log_info.channel = irc_net_add_chan(net, &log_chan_info)) == NULL)
+        if (log_chan_info.channel && (log_info.channel = irc_net_add_chan(ctx.net, &log_chan_info)) == NULL)
             FATAL("irc_net_add_chan");
         
         // init the irc_log module
-        if ((ERROR_CODE(&err) = irc_log_init(ev_base, &log_info)))
+        if ((ERROR_CODE(&err) = irc_log_init(ctx.ev_base, &log_info)))
             FATAL_ERROR(&err, "irc_log_init");
     }
 
     // run event loop
-    if (event_base_dispatch(ev_base))
+    if (event_base_dispatch(ctx.ev_base))
         FATAL("event_base_dispatch");
     
     // ok, no cleanup