src/irc_net.h
author Tero Marttila <terom@fixme.fi>
Thu, 28 May 2009 01:17:36 +0300
branchnew-lib-errors
changeset 219 cefec18b8268
parent 217 7728d6ec3abf
permissions -rw-r--r--
some of the lib/transport stuff compiles
#ifndef IRC_NET_H
#define IRC_NET_H

/**
 * @file
 *
 * Support for IRC networks. This is similar to an IRC connection, but we keep track of channel state, and handle
 * reconnects.
 */

struct irc_net;

#include "irc_conn.h"
#include "irc_chan.h"
#include <lib/error.h>
#include <lib/ssl.h>
#include <sys/queue.h>

/**
 * Configuration info for an IRC network
 */
struct irc_net_info {
    /** The name of the network */
    const char *network;

    /** The hostname to connect to */
    const char *hostname;

    /** Service name (port) */
    const char *service;

    /** Use SSL if given as non-NULL, a reference will be held by the irc_net */
    struct ssl_client_cred *ssl_cred;

    /** Protocol registration info (nickname etc) */
    struct irc_conn_register_info register_info;

    /** Alternatively, raw transport to use, mainly for testing purposes */
    transport_t *transport;
};

/**
 * 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 */
    struct irc_conn *conn;

    /** Our connection info */
    struct irc_net_info info;

    /** Are we currently connecting? */
    bool connecting;

    /** Are we connected? */
    bool connected;
    
    /** Succesfull connect time */
    time_t connected_ts;

    /** The list of IRC channel states */
    TAILQ_HEAD(irc_net_chan_list, irc_chan) channels;

    /** Our set of valid irc_user items for use with irc_chan */
    LIST_HEAD(irc_net_users_list, irc_user) users;

    /** Reconnect timer */
    struct event *reconnect_timer;

    /** The irc_client list */
    TAILQ_ENTRY(irc_net) client_networks;
};

/**
 * Return the network's name, as per irc_net_info::network
 */
const char* irc_net_name (struct irc_net *net);

/**
 * Create a new IRC network state, using the given network info to connect/register.
 *
 * Errors are returned via *err, also returning the error code.
 *
 * The irc_net_info struct itself is copied, but the strings contained therein are not...
 *
 * @param net the new irc_net struct is returned via this pointer
 * @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, error_t *err);

/**
 * Destroy an irc_net state without closing anything cleanly. This destroys the irc_conn, if any, and any irc_chans as
 * well.
 */
void irc_net_destroy (struct irc_net *net);

/**
 * 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.
 *
 * @param net the irc_net the channel is on
 * @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
 */
err_t irc_net_add_chan (struct irc_net *net, struct irc_chan **chan_ptr, const struct irc_chan_info *info, error_t *err);

/**
 * Look up an existing irc_chan by name, returning NULL if not found.
 *
 * @param net the network context
 * @param channel the channel name
 */
struct irc_chan* irc_net_get_chan (struct irc_net *net, const char *channel);

/**
 * Look up an existing irc_user by nickname, or create a new one if not found.
 *
 * This will increment the reference count on the irc_user object, so do call irc_net_put_user once you're done with
 * it, or you'll get reference-counting bugs...
 *
 * @param user_ptr set to the new irc_user state
 * @param net the network context
 * @param nickname the user's current nickname
 */
err_t irc_net_get_user (struct irc_net *net, struct irc_user **user_ptr, const char *nickname);

/**
 * Release a previously get'd irc_user, decrementing its refcount and destroying it if unused.
 */
void irc_net_put_user (struct irc_net *net, struct irc_user *user);

/**
 * 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);

#endif