add irc_client module, plus nexus.h header
authorTero Marttila <terom@fixme.fi>
Fri, 13 Mar 2009 16:10:48 +0200
changeset 53 12d806823775
parent 52 97604efda1ce
child 54 9f74e924b01a
child 58 65bd90f94f4e
add irc_client module, plus nexus.h header
Makefile
src/irc_client.c
src/irc_client.h
src/irc_net.c
src/irc_net.h
src/nexus.c
src/nexus.h
--- a/Makefile	Fri Mar 13 15:22:46 2009 +0200
+++ b/Makefile	Fri Mar 13 16:10:48 2009 +0200
@@ -39,7 +39,7 @@
 SOCK_TEST_OBJS = obj/sock_test.o
 SOCK_GNUTLS_OBJS = obj/sock_gnutls.o
 LINEPROTO_OBJS = obj/line_proto.o
-IRC_OBJS = obj/irc_line.o obj/irc_conn.o obj/irc_net.o obj/irc_chan.o obj/irc_cmd.o obj/irc_proto.o
+IRC_OBJS = obj/irc_line.o obj/irc_conn.o obj/irc_net.o obj/irc_chan.o obj/irc_cmd.o obj/irc_proto.o obj/irc_client.o
 IRC_LOG_OBJS = obj/irc_log.o
 
 # XXX: not yet there
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/irc_client.c	Fri Mar 13 16:10:48 2009 +0200
@@ -0,0 +1,92 @@
+#include "irc_client.h"
+#include "log.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+err_t irc_client_create (struct irc_client **client_ptr, struct error_info *err)
+{
+    struct irc_client *client;
+
+    // allocate
+    if ((client = calloc(1, sizeof(*client))) == NULL)
+        return SET_ERROR(err, ERR_CALLOC);
+
+    // init
+    TAILQ_INIT(&client->networks);
+
+    // ok
+    *client_ptr = client;
+
+    return SUCCESS;
+}
+
+void irc_client_destroy (struct irc_client *client)
+{
+    struct irc_net *next = TAILQ_FIRST(&client->networks), *net;
+
+    // our networks
+    while (next) {
+        net = next;
+        next = TAILQ_NEXT(net, client_networks);
+
+        irc_net_destroy(net);
+    }
+
+    // ourselves
+    free(client);
+}
+
+err_t irc_client_add_net (struct irc_client *client, struct irc_net **net_ptr, struct irc_net_info *net_info)
+{
+    struct irc_net *net;
+    struct error_info err;
+
+    // create the new irc_chan struct
+    if (irc_net_create(&net, net_info, &err))
+        return ERROR_CODE(&err);
+    
+    // add to network list
+    TAILQ_INSERT_TAIL(&client->networks, net, client_networks);
+    
+    // ok
+    *net_ptr = net;
+
+    return SUCCESS;
+}
+
+struct irc_net* irc_client_get_net (struct irc_client *client, const char *network)
+{
+    struct irc_net *net = NULL;
+
+    // look for it...
+    TAILQ_FOREACH(net, &client->networks, client_networks) {
+        if (strcasecmp(net->info.network, network) == 0)
+            // found it
+            return net;
+    }
+
+    // no such network
+    return NULL;
+}
+
+err_t irc_client_quit (struct irc_client *client, const char *message)
+{
+    struct irc_net *net;
+    err_t err;
+
+    // quit each network
+    TAILQ_FOREACH(net, &client->networks, client_networks) {
+        if ((err = irc_net_quit(net, message))) {
+            log_err(err, "irc_net_quit: %s [%s]", net->info.network, message);
+            
+            // XXX: destroy it?
+        }
+    }
+
+    // state
+    client->quitting = true;
+
+    // ok
+    return SUCCESS;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/irc_client.h	Fri Mar 13 16:10:48 2009 +0200
@@ -0,0 +1,53 @@
+#ifndef IRC_CLIENT_H
+#define IRC_CLIENT_H
+
+/**
+ * @file
+ * 
+ * Defines the high-level, full-featured IRC 'client' state, which essentially manipulates a set of irc_net's
+ */
+#include "irc_net.h"
+#include <sys/queue.h>
+
+/**
+ * The IRC client
+ */
+struct irc_client {
+    /** Our set of configured IRC networks */
+    TAILQ_HEAD(irc_client_networks, irc_net) networks;
+
+    /** Are we in the process of quitting all networks? */
+    bool quitting;
+
+    /** Have we quit all networks? */
+    bool quit;
+};
+
+/**
+ * Construct a new irc_client
+ */
+err_t irc_client_create (struct irc_client **client_ptr, struct error_info *err);
+
+/**
+ * Destroy the irc_client, also destroying all networks
+ */
+void irc_client_destroy (struct irc_client *client);
+
+/**
+ * Add a new IRC network
+ */
+err_t irc_client_add_net (struct irc_client *client, struct irc_net **net_ptr, struct irc_net_info *net_info);
+
+/**
+ * Get a pre-existing IRC network by name
+ */
+struct irc_net* irc_client_get_net (struct irc_client *client, const char *network);
+
+/**
+ * Quit cleanly from all our IRC networks.
+ *
+ * XXX: currently no way to indicate once we've quit all of them
+ */
+err_t irc_client_quit (struct irc_client *client, const char *message);
+
+#endif
--- a/src/irc_net.c	Fri Mar 13 15:22:46 2009 +0200
+++ b/src/irc_net.c	Fri Mar 13 16:10:48 2009 +0200
@@ -146,6 +146,7 @@
         return SET_ERROR(err, ERR_CALLOC);
 
     // initialize
+    net->info = *info;
     TAILQ_INIT(&net->channels);
 
     if (info->raw_sock) {
--- a/src/irc_net.h	Fri Mar 13 15:22:46 2009 +0200
+++ b/src/irc_net.h	Fri Mar 13 16:10:48 2009 +0200
@@ -42,8 +42,14 @@
     /* The current connection */
     struct irc_conn *conn;
 
+    /** Our connection info */
+    struct irc_net_info info;
+
     /** The list of IRC channel states */
     TAILQ_HEAD(irc_net_chan_list, irc_chan) channels;
+
+    /** The irc_client list */
+    TAILQ_ENTRY(irc_net) client_networks;
 };
 
 /**
--- a/src/nexus.c	Fri Mar 13 15:22:46 2009 +0200
+++ b/src/nexus.c	Fri Mar 13 16:10:48 2009 +0200
@@ -1,5 +1,4 @@
-
-#include "irc_net.h"
+#include "nexus.h"
 #include "irc_log.h"
 #include "signals.h"
 #include "log.h"
@@ -10,9 +9,6 @@
 #include <getopt.h>
 #include <signal.h>
 
-#include <event2/event.h>
-
-
 #define DEFAULT_HOST "irc.fixme.fi"
 #define DEFAULT_PORT "6667"
 #define DEFAULT_PORT_SSL "6697"
@@ -46,17 +42,6 @@
     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;
@@ -64,19 +49,19 @@
     (void) sig;
     (void) what;
     
-    if (ctx->net && ctx->net->conn && !ctx->net->conn->quitting) {
+    if (ctx->client && !ctx->client->quitting) {
         log_info("Quitting...");
 
         // quit it
-        irc_net_quit(ctx->net, "Goodbye, cruel world ;(");
+        irc_client_quit(ctx->client, "Goodbye, cruel world ;(");
 
     } else {
         log_error("Aborting");
         
         // die
-        if (ctx->net) {
-            irc_net_destroy(ctx->net);
-            ctx->net = NULL;
+        if (ctx->client) {
+            irc_client_destroy(ctx->client);
+            ctx->client = NULL;
         }
 
         // exit
@@ -87,8 +72,9 @@
 int main (int argc, char **argv) 
 {
     int opt, option_index;
+    struct signals *signals;
     struct nexus_ctx ctx;
-    struct signals *signals;
+    struct irc_net *net;
     struct error_info err;
 
     struct irc_net_info net_info = {
@@ -164,9 +150,13 @@
     if (sock_init(ctx.ev_base, &err))
         FATAL_ERROR(&err, "sock_init");
     
+    // the IRC client
+    if (irc_client_create(&ctx.client, &err))
+        FATAL_ERROR(&err, "irc_client_create");
+
     // the IRC network
-    if (irc_net_create(&ctx.net, &net_info, &err))
-        FATAL_ERROR(&err, "irc_net_create");
+    if (irc_client_add_net(ctx.client, &net, &net_info))
+        FATAL_ERR(ERROR_CODE(&err), "irc_client_add_net");
 
     // add our signal handlers
     if (
@@ -178,7 +168,7 @@
     // 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(ctx.net, &log_chan_info)) == NULL)
+        if (log_chan_info.channel && (log_info.channel = irc_net_add_chan(net, &log_chan_info)) == NULL)
             FATAL("irc_net_add_chan");
         
         // init the irc_log module
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/nexus.h	Fri Mar 13 16:10:48 2009 +0200
@@ -0,0 +1,26 @@
+#ifndef NEXUS_H
+#define NEXUS_H
+
+/**
+ * A nexus is the central brain of the application; the place where the main() method is implemented
+ */
+#include <event2/event.h>
+#include "irc_client.h"
+
+/**
+ * Context for async nexus operation
+ */
+struct nexus_ctx {
+    /** The libevent base */
+    struct event_base *ev_base;
+
+    /** The IRC client state */
+    struct irc_client *client;
+};
+
+/**
+ * The nexus main function, application entry point, etc.
+ */
+int main (int argc, char **argv);
+
+#endif /* NEXUS_H */