terom@18: #ifndef IRC_CONN_H terom@18: #define IRC_CONN_H terom@18: terom@23: /** terom@23: * @file terom@23: * terom@23: * Support for connections to IRC servers, a rather fundamental thing. This holds the line_proto to handle the network terom@23: * communications, and then takes care of sending/receiving commands, as well as updating some core state like terom@23: * current nickname. terom@18: */ terom@18: terom@23: struct irc_conn; terom@23: terom@23: #include "error.h" terom@18: #include "sock.h" terom@18: #include "line_proto.h" terom@18: #include "irc_line.h" terom@23: #include "irc_cmd.h" terom@21: #include terom@18: terom@25: /** terom@25: * The configuration info for an IRC connection. terom@25: * terom@25: * XXX: this should probably be reworked, maybe as a separate irc_conn_register function? terom@25: */ terom@27: struct irc_conn_register_info { terom@18: /* Nickname to use on that server */ terom@18: const char *nickname; terom@18: terom@18: /* Username to supply */ terom@18: const char *username; terom@18: terom@18: /* Realname to supply */ terom@18: const char *realname; terom@18: }; terom@18: terom@23: /** terom@27: * Connection state callbacks terom@27: */ terom@27: struct irc_conn_callbacks { terom@27: /** terom@27: * irc_conn_register has completed. terom@27: */ terom@27: void (*on_registered) (struct irc_conn *conn, void *arg); terom@27: }; terom@27: terom@27: /* terom@27: * Connection state terom@27: */ terom@27: struct irc_conn { terom@27: /* We are a line-based protocol */ terom@27: struct line_proto *lp; terom@27: terom@27: /** Callbacks */ terom@27: struct irc_conn_callbacks callbacks; terom@27: terom@27: /** Opaque argument for callbacks */ terom@27: void *cb_arg; terom@27: terom@27: /** Registration request sent */ terom@27: bool registering; terom@27: terom@27: /* Registered (as in, we have a working nickname)? */ terom@27: bool registered; terom@27: terom@27: /* Command handlers */ terom@27: STAILQ_HEAD(irc_conn_handlers, irc_cmd_chain) handlers; terom@27: }; terom@27: terom@27: /** terom@27: * Create a new irc_conn using the given sock_stream, which should be connected to an IRC server. terom@27: * terom@27: * This does not yet send any requests to the server, it only sets up the core state. Use irc_conn_register to register terom@27: * with the server. terom@18: * terom@18: * On success, the resulting irc_conn is returned via *conn with SUCCESS. Otherwise, -ERR_* and error info is returned terom@18: * via *err. terom@23: * terom@23: * @param conn the new irc_conn structure is returned via this pointer terom@23: * @param sock the socket connected to the IRC server terom@23: * @param err errors are returned via this pointer terom@23: * @return error code terom@18: */ terom@27: err_t irc_conn_create (struct irc_conn **conn, struct sock_stream *sock, const struct irc_conn_callbacks *callbacks, terom@27: void *cb_arg, struct error_info *err); terom@18: terom@20: /** terom@28: * Destroy the irc_conn state, terminating any connection and releasing all resources. terom@28: * terom@28: * This does not end the session cleanly, and is intended mainly to be used after clean exit, or to clean up after errors. terom@28: */ terom@28: void irc_conn_destroy (struct irc_conn *conn); terom@28: terom@28: /** terom@23: * Add a new chain of command handler callbacks to be used to handle irc_lines from the server. The given arg will be terom@23: * passed to the callbacks as the context argument. The chain will be appended to the end of the current list of chains. terom@23: * terom@27: * XXX: rename to not conflict with irc_conn_register() terom@27: * terom@23: * @param chain the array of irc_cmd_handler structs, terminated with a NULL entry terom@23: * @param arg the context argument to use for the callbacks terom@23: */ terom@23: err_t irc_conn_register_handler_chain (struct irc_conn *conn, struct irc_cmd_handler *handlers, void *arg); terom@23: terom@23: /** terom@27: * Register with the IRC server using the given registration info (initial nickname etc.) terom@27: * terom@27: * This sends the NICK/USER command sequence. terom@27: */ terom@27: err_t irc_conn_register (struct irc_conn *conn, const struct irc_conn_register_info *info); terom@27: terom@27: /** terom@20: * @group Simple request functions terom@20: * terom@20: * The error handling of these functions is such that the error return code is can be used or ignored as convenient, terom@20: * as connection-fatal errors will be handled internally. terom@20: * terom@20: * @{ terom@20: */ terom@20: terom@23: /** terom@21: * Send a generic IRC message terom@23: * terom@23: * @param conn the IRC protocol connection terom@23: * @param line the irc_line protocol line to send terom@23: * @return error code terom@21: */ terom@21: err_t irc_conn_send (struct irc_conn *conn, const struct irc_line *line); terom@21: terom@23: /** terom@18: * Send a NICK message terom@23: * terom@23: * @param nickname the new nickname to use terom@18: */ terom@18: err_t irc_conn_NICK (struct irc_conn *conn, const char *nickname); terom@18: terom@18: /* terom@18: * Send a USER message terom@23: * terom@23: * @param username the username to register with, may be replaced with ident reply terom@23: * @param realname the full-name to register with terom@18: */ terom@18: err_t irc_conn_USER (struct irc_conn *conn, const char *username, const char *realname); terom@18: terom@20: /* terom@20: * Send a PONG message to the given target terom@23: * terom@23: * @param target the PING source, aka. the target to send the PONG reply to terom@20: */ terom@20: err_t irc_conn_PONG (struct irc_conn *conn, const char *target); terom@18: terom@23: /* terom@23: * Send a JOIN message for the given channel terom@23: * terom@23: * XXX: this doesn't implement the full command options terom@23: * terom@23: * @param channel the full channel name to join terom@23: */ terom@23: err_t irc_conn_JOIN (struct irc_conn *conn, const char *channel); terom@23: terom@21: // @} terom@21: terom@18: #endif /* IRC_CONN_H */