# HG changeset patch # User Tero Marttila # Date 1236953448 -7200 # Node ID 12d806823775d757da5f490dc05f24fbbeae68a1 # Parent 97604efda1ce024fc559828b6f7bb8753b04a129 add irc_client module, plus nexus.h header diff -r 97604efda1ce -r 12d806823775 Makefile --- 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 diff -r 97604efda1ce -r 12d806823775 src/irc_client.c --- /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 +#include + +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; +} diff -r 97604efda1ce -r 12d806823775 src/irc_client.h --- /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 + +/** + * 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 diff -r 97604efda1ce -r 12d806823775 src/irc_net.c --- 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) { diff -r 97604efda1ce -r 12d806823775 src/irc_net.h --- 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; }; /** diff -r 97604efda1ce -r 12d806823775 src/nexus.c --- 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 #include -#include - - #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 diff -r 97604efda1ce -r 12d806823775 src/nexus.h --- /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 +#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 */