add basic log.c module
authorTero Marttila <terom@fixme.fi>
Sun, 01 Mar 2009 01:48:14 +0200
changeset 21 0911d0b828d4
parent 20 d9c4c2980a0d
child 22 c339c020fd33
add basic log.c module
Makefile
src/irc_conn.c
src/irc_conn.h
src/line_proto.c
src/log.c
src/log.h
src/nexus.c
src/sock_tcp.c
--- 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;
 }