# HG changeset patch # User Tero Marttila # Date 1235860473 -7200 # Node ID d9c4c2980a0d598d746661e62d5f3d3bf6fc793e # Parent 8c80580ccde98639f45911e181f9db05040c96d2 irc_conn PING/PONG code, and line_proto fixups diff -r 8c80580ccde9 -r d9c4c2980a0d src/irc_conn.c --- a/src/irc_conn.c Sat Feb 28 23:48:34 2009 +0200 +++ b/src/irc_conn.c Sun Mar 01 00:34:33 2009 +0200 @@ -4,22 +4,58 @@ #include #include +/* + * PING [ ] + * + * Send a 'PONG ` reply right away. + */ +static void on_PING (struct irc_conn *conn, const struct irc_line *line) +{ + // just reply + irc_conn_PONG(conn, line->args[0]); +} + +/* + * Our command handlers + */ +struct irc_cmd_handler { + /* The command name */ + const char *command; + + /* The handler function */ + void (*func) (struct irc_conn *conn, const struct irc_line *line); + +} _cmd_handlers[] = { + { "PING", on_PING }, + { NULL, NULL, }, +}; + void irc_conn_on_line (char *line_buf, void *arg) { + struct irc_conn *conn = arg; struct irc_line line; + struct irc_cmd_handler *handler; int err; // log printf("<<< %s\n", line_buf); // parse - if ((err = irc_line_parse(&line, line_buf))) + if ((err = irc_line_parse(&line, line_buf))) { printf("!!! Invalid line: %s: %s\n", line_buf, error_name(err)); + + return; + } - else - printf("\tprefix=%s, command=%s, args={%s, %s, %s, ...}\n", - line.prefix, line.command, line.args[0], line.args[1], line.args[2] - ); + // look up appropriate handler + for (handler = _cmd_handlers; handler->command; handler++) { + // the command is alpha-only, so normal case-insensitive cmp is fine + if (strcasecmp(handler->command, line.command) == 0) { + // invoke the func + handler->func(conn, &line); + break; + } + } } err_t irc_conn_create (struct irc_conn **conn_ptr, struct sock_stream *sock, const struct irc_conn_config *config, struct error_info *err) @@ -64,7 +100,7 @@ // send using line_proto // XXX: ignore output-buffering - return (err = line_proto_write(conn->lp, line_buf)) < 0 ? err : SUCCESS; + return (err = line_proto_send(conn->lp, line_buf)) < 0 ? err : SUCCESS; } err_t irc_conn_NICK (struct irc_conn *conn, const char *nickname) @@ -74,7 +110,6 @@ NULL, "NICK", { nickname, NULL } }; - // send it return irc_conn_send(conn, &line); } @@ -82,10 +117,20 @@ { // USER struct irc_line line = { - NULL, "USER", { username, "0", "*", realname } + NULL, "USER", { username, "0", "*", realname, NULL } }; - // send it return irc_conn_send(conn, &line); } +err_t irc_conn_PONG (struct irc_conn *conn, const char *target) +{ + // PONG [ ] + // XXX: params are actually the wrong way around now, but nobody cares + struct irc_line line = { + NULL, "PONG", { target, NULL } + }; + + return irc_conn_send(conn, &line); +} + diff -r 8c80580ccde9 -r d9c4c2980a0d src/irc_conn.h --- a/src/irc_conn.h Sat Feb 28 23:48:34 2009 +0200 +++ b/src/irc_conn.h Sun Mar 01 00:34:33 2009 +0200 @@ -44,6 +44,15 @@ */ err_t irc_conn_send (struct irc_conn *conn, const struct irc_line *line); +/** + * @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 NICK message */ @@ -54,5 +63,9 @@ */ err_t irc_conn_USER (struct irc_conn *conn, const char *username, const char *realname); +/* + * Send a PONG message to the given target + */ +err_t irc_conn_PONG (struct irc_conn *conn, const char *target); #endif /* IRC_CONN_H */ diff -r 8c80580ccde9 -r d9c4c2980a0d src/line_proto.c --- a/src/line_proto.c Sat Feb 28 23:48:34 2009 +0200 +++ b/src/line_proto.c Sun Mar 01 00:34:33 2009 +0200 @@ -95,6 +95,7 @@ struct sock_stream_callbacks line_proto_sock_stream_callbacks = { .on_read = &line_proto_on_read, + .on_write = &line_proto_on_write, }; err_t line_proto_create (struct line_proto **lp_ptr, struct sock_stream *sock, size_t buf_size, @@ -121,7 +122,7 @@ sock_stream_event_init(sock, &line_proto_sock_stream_callbacks, lp) || line_proto_schedule_events(lp, EV_READ) ) - return ERROR_CODE(&lp->err); + JUMP_SET_ERROR_INFO(err, &lp->err); // return *lp_ptr = lp; @@ -132,9 +133,13 @@ if (lp) { free(lp->in_buf); free(lp->out_buf); + + // XXX: handle sock init errors } free(lp); + + return ERROR_CODE(err); } /*