--- a/Makefile Sun Mar 01 00:34:33 2009 +0200
+++ b/Makefile Sun Mar 01 01:48:14 2009 +0200
@@ -30,7 +30,7 @@
# modules
module_objs = $(patsubst src/%.c,obj/%.o,$(wildcard src/$(1)/*.c))
-CORE_OBJS = obj/error.o
+CORE_OBJS = obj/error.o obj/log.o
SOCK_OBJS = obj/sock.o obj/sock_tcp.o
SOCK_GNUTLS_OBJS = obj/sock_gnutls.o
LINEPROTO_OBJS = obj/line_proto.o
--- a/src/irc_conn.c Sun Mar 01 00:34:33 2009 +0200
+++ b/src/irc_conn.c Sun Mar 01 01:48:14 2009 +0200
@@ -1,10 +1,20 @@
#include "irc_conn.h"
+#include "irc_cmd.h"
#include <stdlib.h>
#include <string.h>
/*
+ * "Welcome to the Internet Relay Network <nick>!<user>@<host>"
+ */
+static void on_RPL_WELCOME (struct irc_conn *conn, const struct irc_line *line)
+{
+ // update state
+ conn->registered = true;
+}
+
+/*
* PING <server1> [ <server2> ]
*
* Send a 'PONG <server1>` reply right away.
@@ -26,6 +36,7 @@
void (*func) (struct irc_conn *conn, const struct irc_line *line);
} _cmd_handlers[] = {
+ { IRC_RPL_WELCOME, on_RPL_WELCOME },
{ "PING", on_PING },
{ NULL, NULL, },
};
--- a/src/irc_conn.h Sun Mar 01 00:34:33 2009 +0200
+++ b/src/irc_conn.h Sun Mar 01 01:48:14 2009 +0200
@@ -9,6 +9,7 @@
#include "line_proto.h"
#include "irc_line.h"
#include "error.h"
+#include <stdbool.h>
/*
* A connection to an IRC server.
@@ -16,6 +17,9 @@
struct irc_conn {
/* We are a line-based protocol */
struct line_proto *lp;
+
+ /* Registered (as in, we have a working nickname)? */
+ bool registered;
};
// XXX: this should probably be slightly reworked
@@ -39,11 +43,6 @@
*/
err_t irc_conn_create (struct irc_conn **conn, struct sock_stream *sock, const struct irc_conn_config *config, struct error_info *err);
-/*
- * Send an IRC message directly
- */
-err_t irc_conn_send (struct irc_conn *conn, const struct irc_line *line);
-
/**
* @group Simple request functions
*
@@ -54,6 +53,11 @@
*/
/*
+ * Send a generic IRC message
+ */
+err_t irc_conn_send (struct irc_conn *conn, const struct irc_line *line);
+
+/*
* Send a NICK message
*/
err_t irc_conn_NICK (struct irc_conn *conn, const char *nickname);
@@ -68,4 +72,6 @@
*/
err_t irc_conn_PONG (struct irc_conn *conn, const char *target);
+// @}
+
#endif /* IRC_CONN_H */
--- a/src/line_proto.c Sun Mar 01 00:34:33 2009 +0200
+++ b/src/line_proto.c Sun Mar 01 01:48:14 2009 +0200
@@ -251,7 +251,7 @@
// drop line if we already have output buffered
if (lp->out_offset)
- return -ERR_WRITE_EOF;
+ return -ERR_LINE_TOO_LONG;
// try and write the line
if ((ret = sock_stream_write(lp->sock, line, len)) < 0) {
@@ -275,7 +275,8 @@
lp->out_offset = trailing;
// register for EV_WRITE
- line_proto_schedule_events(lp, EV_READ | EV_WRITE);
+ if (line_proto_schedule_events(lp, EV_READ | EV_WRITE))
+ return -ERROR_CODE(&lp->err);
// buffered...
return 1;
@@ -317,7 +318,8 @@
}
// register for EV_WRITE
- line_proto_schedule_events(lp, EV_READ | EV_WRITE);
+ if (line_proto_schedule_events(lp, EV_READ | EV_WRITE))
+ return -ERROR_CODE(&lp->err);
// ok
return 1;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/log.c Sun Mar 01 01:48:14 2009 +0200
@@ -0,0 +1,73 @@
+
+#include "log.h"
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#define _LOG_LEVEL_NAME(ll) case LOG_ ## ll: return #ll;
+const char *log_level_name (enum log_level level)
+{
+ switch (level) {
+ _LOG_LEVEL_NAME(DEBUG)
+ _LOG_LEVEL_NAME(INFO)
+ _LOG_LEVEL_NAME(WARN)
+ _LOG_LEVEL_NAME(ERROR)
+ _LOG_LEVEL_NAME(FATAL)
+ default: return "???";
+ }
+}
+
+/*
+ * Output the "[TYPE] FUNC: " header
+ */
+void _log_header (enum log_level level, const char *func)
+{
+ printf("[%5s] %s: ", log_level_name(level), func);
+}
+
+void log_msg (enum log_level level, const char *func, const char *format, ...)
+{
+ va_list vargs;
+
+ _log_header(level, func);
+
+ // formatted output
+ va_start(vargs, format);
+ vprintf(format, vargs);
+ va_end(vargs);
+
+ // newline
+ printf("\n");
+}
+
+void _log_err (err_t err, const char *func, const char *format, ...)
+{
+ va_list vargs;
+
+ // header
+ _log_header(LOG_ERROR, func);
+
+ // formatted output
+ va_start(vargs, format);
+ vprintf(format, vargs);
+ va_end(vargs);
+
+ // err_code and newline
+ printf(": %s\n", error_name(err));
+}
+
+void _log_err_info (struct error_info *err, const char *func, const char *format, ...)
+{
+ va_list vargs;
+
+ // header
+ _log_header(LOG_ERROR, func);
+
+ // formatted output
+ va_start(vargs, format);
+ vprintf(format, vargs);
+ va_end(vargs);
+
+ // err_code and newline
+ printf(": %s\n", error_msg(err));
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/log.h Sun Mar 01 01:48:14 2009 +0200
@@ -0,0 +1,60 @@
+#ifndef LOG_H
+#define LOG_H
+
+/** @file log.h
+ *
+ * Local logging functions
+ */
+#include "error.h"
+
+/**
+ * Log level definitions
+ *
+ * XXX: these names conflict with <syslog.h>
+ */
+enum log_level {
+ LOG_DEBUG,
+ LOG_INFO,
+ LOG_WARN,
+ LOG_ERROR,
+ LOG_FATAL,
+};
+
+/**
+ * Log a message with the given level
+ */
+void log_msg (enum log_level level, const char *func, const char *format, ...)
+ __attribute__ ((format (printf, 3, 4)));
+
+/**
+ * Shorthand for log_msg
+ */
+#define log_debug(...) log_msg(LOG_DEBUG, __func__, __VA_ARGS__)
+#define log_info(...) log_msg(LOG_INFO, __func__, __VA_ARGS__)
+#define log_warn(...) log_msg(LOG_WARN, __func__, __VA_ARGS__)
+#define log_error(...) log_msg(LOG_ERROR, __func__, __VA_ARGS__)
+#define log_fatal(...) log_msg(LOG_FATAL, __func__, __VA_ARGS__)
+
+/**
+ * Log a message with LOG_ERROR, appending the formatted error code
+ */
+void _log_err (err_t err, const char *func, const char *format, ...)
+ __attribute__ ((format (printf, 3, 4)));
+
+void _log_err_info (struct error_info *err, const char *func, const char *format, ...)
+ __attribute__ ((format (printf, 3, 4)));
+
+#define log_err(err, ...) _log_err(err, __func__, __VA_ARGS__)
+#define log_err_info(err_info, ...) _log_err_info(err_info, __func__, __VA_ARGS__)
+
+/*
+ * log_fatal + exit failure
+ */
+#define FATAL(...) do { log_fatal(__VA_ARGS__); exit(EXIT_FAILURE); } while (0)
+
+/*
+ * log_err_info + exit failure
+ */
+#define FATAL_ERROR(err, ...) do { log_err_info(err, __VA_ARGS__); exit(EXIT_FAILURE); } while (0)
+
+#endif /* LOG_H */
--- a/src/nexus.c Sun Mar 01 00:34:33 2009 +0200
+++ b/src/nexus.c Sun Mar 01 01:48:14 2009 +0200
@@ -1,14 +1,15 @@
+
+#include "log.h"
+#include "sock.h"
+#include "irc_conn.h"
#include <stdlib.h>
#include <stdbool.h>
-#include <err.h>
#include <stdio.h>
#include <getopt.h>
#include <event2/event.h>
-#include "sock.h"
-#include "irc_conn.h"
#define DEFAULT_HOST "irc.fixme.fi"
#define DEFAULT_PORT "6667"
@@ -38,7 +39,7 @@
struct event_base *ev_base;
struct sock_stream *sock;
struct irc_conn *conn;
- struct error_info _err;
+ struct error_info err;
const char *hostname = DEFAULT_HOST, *portname = DEFAULT_PORT;
bool ssl = 0;
@@ -82,30 +83,30 @@
// initialize libevent
if ((ev_base = event_base_new()) == NULL)
- err(1, "event_base_new");
+ FATAL("event_base_new");
// initialize sock module
- if (sock_init(ev_base, &_err))
- errx(1, "sock_init: %s", error_msg(&_err));
+ if (sock_init(ev_base, &err))
+ FATAL_ERROR(&err, "sock_init");
// over-simplified connect
if (ssl) {
- if (sock_ssl_connect(&sock, hostname, portname, &_err))
- errx(1, "sock_ssl_connect: %s", error_msg(&_err));
+ if (sock_ssl_connect(&sock, hostname, portname, &err))
+ FATAL_ERROR(&err, "sock_ssl_connect(%s, %s)", hostname, portname);
} else {
- if (sock_tcp_connect(&sock, hostname, portname, &_err))
- errx(1, "sock_tcp_connect: %s", error_msg(&_err));
+ if (sock_tcp_connect(&sock, hostname, portname, &err))
+ FATAL_ERROR(&err, "sock_tcp_connect(%s, %s)", hostname, portname);
}
// create the irc connection state
- if (irc_conn_create(&conn, sock, &conn_config, &_err))
- errx(1, "irc_conn_create: %s", error_msg(&_err));
+ if (irc_conn_create(&conn, sock, &conn_config, &err))
+ FATAL_ERROR(&err, "irc_conn_create");
// run event loop
if (event_base_dispatch(ev_base))
- errx(1, "event_base_dispatch");
+ FATAL("event_base_dispatch");
// ok, no cleanup
return 0;
--- a/src/sock_tcp.c Sun Mar 01 00:34:33 2009 +0200
+++ b/src/sock_tcp.c Sun Mar 01 01:48:14 2009 +0200
@@ -126,6 +126,9 @@
// initialize base with sock_tcp_type
sock_stream_init(SOCK_TCP_BASE(*sock_ptr), &sock_tcp_type);
+ // invalid fds are <0
+ (*sock_ptr)->fd = -1;
+
// done
return SUCCESS;
}