--- a/TODO Mon Mar 30 01:31:13 2009 +0300
+++ b/TODO Mon Mar 30 01:31:27 2009 +0300
@@ -1,16 +1,27 @@
sock:
- * async connect + resolve
* async SSL handshake
* sock_openssl, or improve sock_gnutls
- * tests for all of the above...
+ * tests...
irc_conn:
* support for CTCP messages, e.g. ACTION
+ * ratelimit queue for outgoing messages
+
+irc_net:
+ * reconnect, maybe cycling servers?
+
+irc_chan:
+ * handle KICK
+
+config:
+ * A more advanced structured value parser that can then handle all the various configuration values sanely
modules:
+ * Automatic module-name -> path mapping, and autoloading of modules somehow
* proper unload support, there needs to be some kind of completion notification thing that can then destroy the module
once it's completely unloaded - maybe some kind of module-resource-reference-counting thing, which will eventually
be needed anyways?
irc_log:
- * logging of NICK/QUIT
+ * recode to valid UTF8
+
--- a/src/chain.h Mon Mar 30 01:31:13 2009 +0300
+++ b/src/chain.h Mon Mar 30 01:31:27 2009 +0300
@@ -2,9 +2,11 @@
#define CHAIN_H
/**
- * Defines a generalized "chain of things" behaviour.
+ * @file
+ *
+ * Defines a semi-generalized "chain of things" behaviour.
*
- * The structure of this is a CHAIN_LIST, which contains a number of CHAIN_HEAD items, which then contain a number of
+ * The structure of this is a chain_list, which contains a number of chain_head items, which then contain a number of
* induvidual items.
*/
#include "error.h"
@@ -14,10 +16,13 @@
* The chain header.
*/
struct chain_head {
+ /** The list of items */
const void *chain;
-
+
+ /** The context arg */
void *arg;
-
+
+ /** Our position in the chain_list */
STAILQ_ENTRY(chain_head) node;
};
--- a/src/config.h Mon Mar 30 01:31:13 2009 +0300
+++ b/src/config.h Mon Mar 30 01:31:27 2009 +0300
@@ -2,6 +2,8 @@
#define CONFIG_H
/**
+ * @file
+ *
* Support for module configuration parameters
*/
#include "error.h"
@@ -16,6 +18,9 @@
CONFIG_STRING,
};
+/**
+ * A single configuration option, with a name, type, handler function, etc.
+ */
struct config_option {
/** The name of the config option */
const char *name;
--- a/src/error.h Mon Mar 30 01:31:13 2009 +0300
+++ b/src/error.h Mon Mar 30 01:31:27 2009 +0300
@@ -191,6 +191,8 @@
/** Same as above, but also do a 'goto error' */
#define JUMP_SET_ERROR(err_info_ptr, err_code) do { SET_ERROR(err_info_ptr, err_code); goto error; } while (0)
+#define JUMP_SET_ERROR_EXTRA(err_info_ptr, err_code, err_extra) do { _SET_ERROR_EXTRA(err_info_ptr, err_code, err_extra); goto error; } while (0)
+#define JUMP_SET_ERROR_ERRNO(err_info_ptr, err_code) do { _SET_ERROR_ERRNO(err_info_ptr, err_code); goto error; } while (0)
#define JUMP_SET_ERROR_INFO(err_info_ptr, from_ptr) do { SET_ERROR_INFO(err_info_ptr, from_ptr); goto error; } while (0)
#define JUMP_SET_ERROR_STR(err_info_ptr, err_code, err_str) do { _SET_ERROR_STR(err_info_ptr, err_code, err_str); goto error; } while (0)
--- a/src/irc_chan.c Mon Mar 30 01:31:13 2009 +0300
+++ b/src/irc_chan.c Mon Mar 30 01:31:27 2009 +0300
@@ -12,6 +12,21 @@
}
/**
+ * Invoke the named irc_chan_callbacks field with the given args
+ */
+#define IRC_CHAN_INVOKE_CALLBACK(chan, _cb_name_, ...) \
+ do { \
+ struct chain_head *head; \
+ \
+ CHAIN_FOREACH(&(chan)->callbacks, head) { \
+ const struct irc_chan_callbacks *callbacks = head->chain; \
+ \
+ if (callbacks->_cb_name_) \
+ callbacks->_cb_name_((chan), ## __VA_ARGS__, head->arg); \
+ } \
+ } while (0);
+
+/**
* Add or update a nickname to the irc_chan.users list.
*
* If the given nickname already exists in our users list, this does nothing. Otherwise, an irc_user is aquired using
--- a/src/irc_chan.h Mon Mar 30 01:31:13 2009 +0300
+++ b/src/irc_chan.h Mon Mar 30 01:31:27 2009 +0300
@@ -26,7 +26,12 @@
};
/**
- * Semantic IRC channel callbacks.
+ * High-level IRC channel callbacks for convenience.
+ *
+ * These are based on the normal irc_chan::handlers interface, and you can use both freely.
+ *
+ * The on_self_* handlers are for actions that affect our own status on the channel, the rest are only for actions
+ * done by other users.
*
* Where callbacks have irc_nm arguments, these are MAY be given as NULL if the prefix could not be parsed.
*/
@@ -51,22 +56,9 @@
};
/**
- * Invoke the given callback with the given args
- */
-#define IRC_CHAN_INVOKE_CALLBACK(chan, _cb_name_, ...) \
- do { \
- struct chain_head *head; \
- \
- CHAIN_FOREACH(&(chan)->callbacks, head) { \
- const struct irc_chan_callbacks *callbacks = head->chain; \
- \
- if (callbacks->_cb_name_) \
- callbacks->_cb_name_((chan), ## __VA_ARGS__, head->arg); \
- } \
- } while (0);
-
-/**
- * Per-channel-user state
+ * Per-channel-user state. This is used to store the list of irc_user's on an irc_chan.
+ *
+ * The nickname is accessible via user->nickname.
*/
struct irc_chan_user {
/** The per-network user info */
@@ -77,23 +69,26 @@
};
/**
- * IRC channel state
+ * Persistent IRC channel state, part of irc_net.
+ *
+ * This stores the channel's info, status flags, users list, and handlers/callbacks.
+ *
+ * Create/get channels using the irc_net_add_chan()/irc_net_get_chan() interface, and then attach your own
+ * callbacks/handlers using irc_chan_add_callbacks()/irc_chan::handlers and irc_cmd_add().
+ *
+ * Note that irc_net will propagate all relevant events for each channel.
*/
struct irc_chan {
- /** The irc_net.channels list */
- TAILQ_ENTRY(irc_chan) node;
-
- /* The network we're on */
+ /** The network we're part of */
struct irc_net *net;
/** Our identifying info */
struct irc_chan_info info;
/**
- * @group State flags
+ * @defgroup irc_chan_state State flags
* @{
*/
-
/** JOIN request sent, waiting for reply */
bool joining;
@@ -113,6 +108,9 @@
/** High-level user callbacks */
struct chain_list callbacks;
+
+ /** The irc_net::channels list */
+ TAILQ_ENTRY(irc_chan) net_channels;
};
/**
@@ -138,7 +136,7 @@
void irc_chan_destroy (struct irc_chan *chan);
/**
- * Add high-level irc_chan callbacks
+ * Add a set of high-level irc_chan callbacks. Not all callbacks need to be implemented.
*/
err_t irc_chan_add_callbacks (struct irc_chan *chan, const struct irc_chan_callbacks *callbacks, void *arg);
@@ -150,20 +148,19 @@
/**
* Look up an irc_chan_user struct by nickname for this channel, returning NULL if no such chan_user exists.
*
+ * Be careful not to hold on to this, as the irc_chan_user struct may be released if the user leaves the channel.
+ *
* @param chan the channel context
* @param nickname the user's current nickname
- * @param return the irc_chan_user state, or NULL if nickname not found
+ * @return the irc_chan_user state, or NULL if nickname not found
*/
struct irc_chan_user* irc_chan_get_user (struct irc_chan *chan, const char *nickname);
/**
* Send the initial JOIN message.
*
- * The channel must be in the IRC_CHAN_INIT state, and will transition to the IRC_CHAN_JOINING state.
- *
* @param chan the channel to JOIN
*/
err_t irc_chan_join (struct irc_chan *chan);
-
#endif
--- a/src/irc_client.h Mon Mar 30 01:31:13 2009 +0300
+++ b/src/irc_client.h Mon Mar 30 01:31:27 2009 +0300
@@ -10,7 +10,7 @@
#include <sys/queue.h>
/**
- * The IRC client
+ * High-level IRC client state, this just means a set of named irc_net's and some common behaviour.
*/
struct irc_client {
/** Our set of configured IRC networks */
@@ -39,6 +39,7 @@
* @param client the irc_client state
* @param net_ptr used to return the new irc_net if not NULL
* @param net_info info required to identify and connect to the network
+ * @param err returned error info
*/
err_t irc_client_add_net (struct irc_client *client, struct irc_net **net_ptr, struct irc_net_info *net_info, struct error_info *err);
--- a/src/irc_cmd.h Mon Mar 30 01:31:13 2009 +0300
+++ b/src/irc_cmd.h Mon Mar 30 01:31:27 2009 +0300
@@ -4,27 +4,32 @@
/**
* @file
*
- * Flexible command handlers callback lists for use with irc_lines
+ * Command handlers callback lists for use with irc_line's
*/
#include "irc_line.h"
#include "chain.h"
/**
- * Single command -> handler mapping for lookup
+ * A single command name + handler function lookup entry. This defines the irc_line::command to handle, and the function used to handle it.
+ *
+ * Note that when an irc_line is matched against an array of these, only the *first* matching handler is invoked.
*/
struct irc_cmd_handler {
/** The command name to match */
const char *command;
- /** The handler function */
+ /**
+ * The handler function.
+ *
+ * @param line the irc_line that matched the command
+ * @param arg the context arg, as given to irc_cmd_add.
+ */
void (*func) (const struct irc_line *line, void *arg);
};
/**
- * @struct irc_cmd_handlers
- *
- * A dynamic list of irc_cmd_chain handlers
+ * A dynamic list of irc_cmd_handler's
*/
typedef struct chain_list irc_cmd_handlers_t;
@@ -34,22 +39,35 @@
void irc_cmd_init (irc_cmd_handlers_t *handlers);
/**
- * Add an irc_cmd_chain to the irc_cmd_handlers list for the given handlers/arg
+ * Append the given NULL-termianted array of irc_cmd_handler's to the irc_cmd_handlers list, without copying it.
+ *
+ * @param handlers the irc_cmd_handlers_t
+ * @param list the { NULL, NULL } termianted array of irc_cmd_handlers
+ * @param arg the opaque context argument, will be passed to the func's of the given list when invoked
*/
err_t irc_cmd_add (irc_cmd_handlers_t *handlers, const struct irc_cmd_handler *list, void *arg);
/**
- * Trigger irc_cmd_chain callbacks for the given irc_line
+ * Trigger all relevant handlers for the given irc_line.
+ *
+ * @param handlers the irc_cmd_handlers_t
+ * @param line the line to match against the handlers and invoke the func with
*/
void irc_cmd_invoke (irc_cmd_handlers_t *handlers, const struct irc_line *line);
/**
- * Remove a previously added chain_head from the irc_cmd_handlers list with the given list/arg
+ * Remove a previously added handler list.
+ *
+ * @param handlers the irc_cmd_handlers_t
+ * @param list the list given to irc_cmd_add, compared as pointer value
+ * @param arg the context arg given to irc_cmd_add, compared as pointer value
*/
void irc_cmd_remove (irc_cmd_handlers_t *handlers, const struct irc_cmd_handler *list, void *arg);
/**
- * Cleanup an irc_cmd_handlers list
+ * Cleanup an irc_cmd_handlers list, releasing all memory.
+ *
+ * @param handlers the irc_cmd_handlers_t to cleanup
*/
void irc_cmd_free (irc_cmd_handlers_t *handlers);
--- a/src/irc_line.h Mon Mar 30 01:31:13 2009 +0300
+++ b/src/irc_line.h Mon Mar 30 01:31:27 2009 +0300
@@ -23,10 +23,15 @@
* Chars that are invalid inside of tokens
*/
#define IRC_TOKEN_INVALID "\r\n\n "
+
+/**
+ * Chars that are invalid inside of the trailing-argument token
+ */
#define IRC_TOKEN_TRAILING_INVALID "\r\n\n"
/**
- * Low-level IRC protocol unit
+ * Low-level IRC protocol unit. Note that all fields are specifically constant strings, MUST NOT be modified, and
+ * usually point at stack-allocated memory. Hence, if you need to mutate or store these values, you must copy them.
*/
struct irc_line {
/** The message source as a nickmask, for those messages that have a valid prefix. May be NULL otherwise */
@@ -40,8 +45,8 @@
};
/**
- * Parse an IRC message to fill in an irc_line. This mutates the value of data (to insert NULs between tokens), and
- * stores pointers into this data into the irc_line.
+ * Parse an IRC message to fill in an irc_line. This mutates the contents of data (to insert NULs between tokens), and
+ * stores pointers into this memory in the irc_line.
*
* If the prefix is a valid nickmask, it will be stored in the given given irc_nm, and irc_line.nm set to this.
*
--- a/src/irc_proto.h Mon Mar 30 01:31:13 2009 +0300
+++ b/src/irc_proto.h Mon Mar 30 01:31:27 2009 +0300
@@ -28,6 +28,8 @@
/**
* The set of characters that are considered nickname channel flag prefixes (i.e. op, voice, etc).
+ *
+ * XXX: many IRCd's have more than these, should use the 005 reply instead.
*/
#define IRC_CHANFLAGS "@+"
@@ -42,7 +44,7 @@
/** Username, including any ident-related prefix from the network */
const char *username;
- /** Hostname, either reverse DNS hostname, literal IPv4 or literal IPv6 */
+ /** Hostname, either reverse DNS hostname, literal IPv4, literal IPv6, or something else... */
const char *hostname;
};
@@ -59,12 +61,12 @@
err_t irc_nm_parse (struct irc_nm *nm, char *buf, const char *prefix);
/**
- * Compare two nicknames for equality, with standard strcmp() semantics.
+ * Compare two nicknames for equality, with standard cmp() semantics.
*/
int irc_cmp_nick (const char *nick1, const char *nick2);
/**
- * Compare up to the first n chars of the two nickname strings for equality, with standard strcmp() semantics.
+ * Compare up to the first n chars of the two nickname strings for equality, with standard cmp() semantics.
*/
int irc_ncmp_nick (const char *nick1, const char *nick2, size_t n);
@@ -84,14 +86,14 @@
* Copy the prefixed flags from the given nickname into the given flags buffer (of at least IRC_CHANFLAGS_MAX bytes) and
* NUL-terminate it. Returns a pointer to the actual nickname itself.
*
- * @param nick the nickname, including prefixed chanflags
- * @param chanflags the buffer to store the parsed chanflags into
- * @returns a pointer to the first char of the actual nickname
+ * @param nickname the nickname including prefixed chanflags
+ * @param chanflags buffer to store the parsed chanflags into
+ * @return a pointer to the first char of the actual nickname
*/
-const char* irc_nick_chanflags (const char *nick, char chanflags[IRC_CHANFLAGS_MAX]);
+const char* irc_nick_chanflags (const char *nickname, char chanflags[IRC_CHANFLAGS_MAX]);
/**
- * @group IRC command numerics
+ * @defgroup IRC_RPL_ IRC command numerics
* @{
*/
--- a/src/irc_user.h Mon Mar 30 01:31:13 2009 +0300
+++ b/src/irc_user.h Mon Mar 30 01:31:27 2009 +0300
@@ -2,8 +2,10 @@
#define IRC_USER_H
/**
+ * @file
+ *
* Minimal state for tracking per-user state for an irc_net. Mainly, the purpose of this module is to support the
- * irc_chan.users implementation, such that when a user's nickname is changed, one does not need to modify all
+ * irc_chan::users implementation, such that when a user's nickname is changed, one does not need to modify all
* irc_chan lists, but rather, just replace the nickname field here.
*
* XXX: should this tie in to irc_net to register its own NICK/QUIT handlers?
@@ -12,9 +14,9 @@
#include "error.h"
/**
- * The basic per-network user info. The lifetime of an irc_user struct is strictly for the duration between the user
+ * Basic per-network user info. The lifetime of an irc_user struct is strictly for the duration between the user
* JOIN'ing onto the first irc_chan we are on (or us JOIN'ing onto it while they are on it), and them PART'ing the
- * channel or QUIT'ing.
+ * last channel we see them on, or QUIT'ing.
*/
struct irc_user {
/** The user's nickname */
--- a/src/line_proto.h Mon Mar 30 01:31:13 2009 +0300
+++ b/src/line_proto.h Mon Mar 30 01:31:27 2009 +0300
@@ -15,7 +15,7 @@
struct line_proto;
/**
- * User callback list
+ * User callbacks for event-based line_proto behaviour
*/
struct line_proto_callbacks {
/** Handle received line */
--- a/src/module.h Mon Mar 30 01:31:13 2009 +0300
+++ b/src/module.h Mon Mar 30 01:31:27 2009 +0300
@@ -7,7 +7,7 @@
* Dynamically loadable modules for use with nexus.
*
* The modules are loaded using dlopen(), and hence should be standard dynamic libraries. Modules are then "loaded" by
- * resolving a `struct module_funcs` symbol called '<modname>_funcs', and then using the init func to construct a
+ * resolving a `struct module_funcs` symbol called "<modname>_funcs", and then using the init func to construct a
* "context", which is then further manipulated by various other module functions.
*/
#include "nexus.h"
@@ -28,8 +28,8 @@
};
/**
- * A module's behaviour is defined as a set of function pointers, which is dynamically resolved from the module DSO,
- * using the <mod_name>_funcs symbol.
+ * A table of (function) pointers defining a module's behaviour. This is dynamically resolved from the module DSO
+ * using the "<mod_name>_funcs" symbol.
*
* XXX: this also includes non-functions now...
*/
--- a/src/nexus.h Mon Mar 30 01:31:13 2009 +0300
+++ b/src/nexus.h Mon Mar 30 01:31:27 2009 +0300
@@ -2,9 +2,10 @@
#define NEXUS_H
/**
+ * @file
+ *
* A nexus is the central brain of the application; the place where the main() method is implemented
*/
-
struct nexus;
#include <event2/event.h>
@@ -13,7 +14,7 @@
#include "irc_client.h"
/**
- * Context for async nexus operation
+ * The central brain, as created in the main() function.
*/
struct nexus {
/** The libevent base */