src/irc_conn.h
author Tero Marttila <terom@fixme.fi>
Thu, 12 Mar 2009 22:50:08 +0200
changeset 45 71e65564afd2
parent 37 4fe4a3c4496e
child 48 4841f4398fd2
permissions -rw-r--r--
remove irc_chan.state, modify irc_chan_callbacks.on_msg to take a irc_nm, improve error handling a bit further (up to irc_net now)
#ifndef IRC_CONN_H
#define IRC_CONN_H

/**
 * @file
 *
 * Support for connections to IRC servers, a rather fundamental thing. This holds the line_proto to handle the network
 * communications, and then takes care of sending/receiving commands, as well as updating some core state like
 * current nickname.
 */

struct irc_conn;

#include "error.h"
#include "sock.h"
#include "line_proto.h"
#include "irc_line.h"
#include "irc_cmd.h"
#include <stdbool.h>

/**
 * The info required to register with irc_conn_register
 */
struct irc_conn_register_info {
    /* Nickname to use on that server */
    const char *nickname;

    /* Username to supply */
    const char *username;

    /* Realname to supply */
    const char *realname;
};

/**
 * Connection state callbacks
 */
struct irc_conn_callbacks {
    /**
     * irc_conn_register has completed.
     */
    void (*on_registered) (struct irc_conn *conn, void *arg);

    /**
     * The connection has failed in some way, and can not be considered useable anymore. Sending messages won't work,
     * and no more messages will be received. The connection should be destroyed, probably from this callback.
     */
    void (*on_error) (struct irc_conn *conn, struct error_info *err, void *arg);
};

/*
 * Connection state
 */
struct irc_conn {
    /* We are a line-based protocol */
    struct line_proto *lp;

    /** Callbacks */
    struct irc_conn_callbacks callbacks;

    /** Opaque argument for callbacks */
    void *cb_arg;

    /** @group flags @{ */
    /** Registration request sent */
    bool registering;

    /** Registered (as in, we have a working nickname)? */
    bool registered;
    
    // @}
    
    /** Our current real nickname */
    char *nickname;

    /** Command handlers */
    irc_cmd_handlers_t handlers;
};

/**
 * Create a new irc_conn using the given sock_stream, which should be connected to an IRC server.
 *
 * This does not yet send any requests to the server, it only sets up the core state. Use irc_conn_register to register
 * with the server.
 *
 * On success, the resulting irc_conn is returned via *conn with SUCCESS. Otherwise, -ERR_* and error info is returned
 * via *err.
 *
 * @param conn the new irc_conn structure is returned via this pointer
 * @param sock the socket connected to the IRC server
 * @param err errors are returned via this pointer
 * @return error code
 */
err_t irc_conn_create (struct irc_conn **conn, struct sock_stream *sock, const struct irc_conn_callbacks *callbacks, 
        void *cb_arg, struct error_info *err);

/**
 * Destroy the irc_conn state, terminating any connection and releasing all resources.
 *
 * This does not end the session cleanly, and is intended mainly to be used after clean exit, or to clean up after errors.
 */
void irc_conn_destroy (struct irc_conn *conn);

/**
 * Add a new chain of command handler callbacks to be used to handle irc_lines from the server. The given arg will be
 * passed to the callbacks as the context argument. The chain will be appended to the end of the current list of chains.
 *
 * XXX: rename to not conflict with irc_conn_register()
 *
 * @param chain the array of irc_cmd_handler structs, terminated with a NULL entry
 * @param arg the context argument to use for the callbacks
 */
err_t irc_conn_add_cmd_handlers (struct irc_conn *conn, struct irc_cmd_handler *handlers, void *arg);

/**
 * Register with the IRC server using the given registration info (initial nickname etc.)
 *
 * This sends the NICK/USER command sequence.
 */
err_t irc_conn_register (struct irc_conn *conn, const struct irc_conn_register_info *info);

/**
 * @group Simple request functions
 *
 * The error handling of these functions is such that the error return code is can be used or ignored as convenient,
 * as connection-fatal errors will be handled internally.
 *
 * @{
 */

/**
 * Send a generic IRC message
 *
 * @param conn the IRC protocol connection
 * @param line the irc_line protocol line to send
 * @return error code
 */
err_t irc_conn_send (struct irc_conn *conn, const struct irc_line *line);

/**
 * Send a NICK message
 *
 * @param nickname the new nickname to use
 */
err_t irc_conn_NICK (struct irc_conn *conn, const char *nickname);

/*
 * Send a USER message
 *
 * @param username the username to register with, may be replaced with ident reply
 * @param realname the full-name to register with
 */
err_t irc_conn_USER (struct irc_conn *conn, const char *username, const char *realname);

/*
 * Send a PONG message to the given target
 *
 * @param target the PING source, aka. the target to send the PONG reply to
 */
err_t irc_conn_PONG (struct irc_conn *conn, const char *target);

/*
 * Send a JOIN message for the given channel
 *
 * XXX: this doesn't implement the full command options
 *
 * @param channel the full channel name to join
 */
err_t irc_conn_JOIN (struct irc_conn *conn, const char *channel);

// @}

#endif /* IRC_CONN_H */