--- 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 <stdlib.h>
#include <string.h>
+/*
+ * PING <server1> [ <server2> ]
+ *
+ * Send a 'PONG <server1>` 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 <user> <mode> <unused> <realname>
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 <server> [ <server2> ]
+ // 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);
+}
+
--- 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 */
--- 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);
}
/*