--- a/src/irc_net.c Mon Mar 30 01:31:00 2009 +0300
+++ b/src/irc_net.c Mon Mar 30 01:31:13 2009 +0300
@@ -25,7 +25,7 @@
net->conn = NULL;
// update channel state
- TAILQ_FOREACH(chan, &net->channels, node) {
+ TAILQ_FOREACH(chan, &net->channels, net_channels) {
// XXX: notify channel somehow
}
@@ -64,7 +64,7 @@
(void) conn;
// join our channels
- TAILQ_FOREACH(chan, &net->channels, node) {
+ TAILQ_FOREACH(chan, &net->channels, net_channels) {
if ((ERROR_CODE(&err) = irc_chan_join(chan)))
// XXX: this should be some kind of irc_chan_error instead
irc_net_error(net, &err);
@@ -162,7 +162,7 @@
struct irc_chan *chan;
// scan each channel
- TAILQ_FOREACH(chan, &net->channels, node) {
+ TAILQ_FOREACH(chan, &net->channels, net_channels) {
if (irc_chan_get_user(chan, line->source->nickname)) {
// propagate
irc_cmd_invoke(&chan->handlers, line);
@@ -240,6 +240,45 @@
{ NULL, NULL }
};
+/**
+ * The given socket is now connected, so create the irc_conn and bind it in to us
+ */
+static err_t irc_net_connected (struct irc_net *net, struct sock_stream *sock, struct error_info *err)
+{
+ // create the irc connection state
+ if (irc_conn_create(&net->conn, sock, &_conn_callbacks, net, err))
+ return ERROR_CODE(err);
+
+ // add our command handlers
+ if ((ERROR_CODE(err) = irc_conn_add_cmd_handlers (net->conn, _cmd_handlers, net)))
+ return ERROR_CODE(err);
+
+ // register
+ if ((ERROR_CODE(err) = irc_conn_register(net->conn, &net->info.register_info)))
+ return ERROR_CODE(err);
+
+ // ok
+ return SUCCESS;
+}
+
+static void irc_net_on_connect (struct sock_stream *sock, struct error_info *conn_err, void *arg)
+{
+ struct irc_net *net = arg;
+ struct error_info err;
+
+ // XXX: better error handling
+
+ // trap errors
+ if (conn_err)
+ FATAL_ERROR(conn_err, "async TCP connect failed");
+
+ // ok, yay
+ if (irc_net_connected(net, sock, &err))
+ FATAL_ERROR(&err, "irc_net_connected failed");
+
+ // XXX: cleanup
+}
+
err_t irc_net_create (struct irc_net **net_ptr, const struct irc_net_info *info, struct error_info *err)
{
struct irc_net *net;
@@ -254,41 +293,35 @@
TAILQ_INIT(&net->channels);
LIST_INIT(&net->users);
- if (info->raw_sock) {
- log_debug("connected using raw socket: %p", info->raw_sock);
-
- sock = info->raw_sock;
+ // non-async socket connect?
+ if (info->raw_sock || info->use_ssl) {
+ // create the socket
+ if (info->raw_sock) {
+ log_debug("connected using raw socket: %p", info->raw_sock);
- } else if (info->use_ssl) {
- log_debug("connecting to [%s]:%s using SSL", info->hostname, info->service);
+ sock = info->raw_sock;
- // XXX: over-simplified blocking connect
- if (sock_ssl_connect(&sock, info->hostname, info->service, err))
+ } else if (info->use_ssl) {
+ log_debug("connecting to [%s]:%s using SSL", info->hostname, info->service);
+
+ // XXX: over-simplified blocking connect
+ if (sock_ssl_connect(&sock, info->hostname, info->service, err))
+ goto error;
+ }
+
+ // then create the conn right away
+ if (irc_net_connected(net, sock, err))
goto error;
} else {
log_debug("connecting to [%s]:%s", info->hostname, info->service);
-
- // XXX: over-simplified blocking connect
- if (sock_tcp_connect(&sock, info->hostname, info->service, err))
+
+ // begin async connect
+ if (sock_tcp_connect_async(&sock, info->hostname, info->service, &irc_net_on_connect, net, err))
goto error;
-
+
}
- // create the irc connection state
- if (irc_conn_create(&net->conn, sock, &_conn_callbacks, net, err))
- goto error;
-
- // add our command handlers
- if ((ERROR_CODE(err) = irc_conn_add_cmd_handlers (net->conn, _cmd_handlers, net)))
- goto error;
-
- // register
- log_debug("connected, registering");
-
- if ((ERROR_CODE(err) = irc_conn_register(net->conn, &info->register_info)))
- goto error;
-
// ok
*net_ptr = net;
@@ -316,7 +349,7 @@
// our channels
while (next) {
chan = next;
- next = TAILQ_NEXT(chan, node);
+ next = TAILQ_NEXT(chan, net_channels);
irc_chan_destroy(chan);
}
@@ -336,7 +369,7 @@
return ERROR_CODE(err);
// add to network list
- TAILQ_INSERT_TAIL(&net->channels, chan, node);
+ TAILQ_INSERT_TAIL(&net->channels, chan, net_channels);
// currently connected?
if (net->conn && net->conn->registered) {
@@ -357,7 +390,7 @@
struct irc_chan *chan = NULL;
// look for it...
- TAILQ_FOREACH(chan, &net->channels, node) {
+ TAILQ_FOREACH(chan, &net->channels, net_channels) {
if (strcasecmp(chan->info.channel, channel) == 0)
// found it
return chan;
--- a/src/irc_net.h Mon Mar 30 01:31:00 2009 +0300
+++ b/src/irc_net.h Mon Mar 30 01:31:13 2009 +0300
@@ -31,7 +31,7 @@
/** SSL? */
bool use_ssl;
- /** Protocol registration info */
+ /** Protocol registration info (nickname etc) */
struct irc_conn_register_info register_info;
/** Raw socket to use, mainly for testing purposes */
@@ -39,10 +39,18 @@
};
/**
- * IRC Network state
+ * The persistent IRC network state. This includes the "current" connection (which may change over time), the
+ * identifying info, the list of channels and their state, etc.
+ *
+ * This handles the irc_conn's messages, and propagates relevant messages to the appropriate irc_chan
+ * (using irc_chan::handlers). This includes NICK/QUIT events for users on said channel.
+ *
+ * For NICK events, the event is propagated *before* updating irc_user::nickname.
+ *
+ * XXX: needs some callbacks
*/
struct irc_net {
- /* The current connection */
+ /** The current connection */
struct irc_conn *conn;
/** Our connection info */
@@ -59,7 +67,7 @@
};
/**
- * Return the networks's name
+ * Return the network's name, as per irc_net_info::network
*/
const char* irc_net_name (struct irc_net *net);
@@ -69,7 +77,7 @@
* Errors are returned via *err, also returning the error code.
*
* @param net the new irc_net struct is returned via this pointer
- * @param info network informated, used to connect and register
+ * @param info network information, used to connect and register
* @param err return error info
*/
err_t irc_net_create (struct irc_net **net, const struct irc_net_info *info, struct error_info *err);
@@ -83,10 +91,10 @@
/**
* Create a new irc_chan and add it to our channel list.
*
- * If we are connected and registered, JOIN the channel right away, otherwise, join it once we register.
+ * If we are connected and registered, join the channel right away, otherwise, join it once we register.
*
* @param net the irc_net the channel is on
- * #param chan_ptr return the new irc_chan via this, if not NULL
+ * @param chan_ptr return the new irc_chan via this, if given
* @param info the info required to identify and join the channel
* @param err return error info
*/
@@ -119,6 +127,8 @@
/**
* Quit from the IRC network, this sends a QUIT message to the server, and waits for the connection to be closed cleanly.
+ *
+ * XXX: nothing to indicate completion
*/
err_t irc_net_quit (struct irc_net *net, const char *message);