--- a/Makefile Sun Mar 15 01:17:22 2009 +0200
+++ b/Makefile Sun Mar 15 23:01:12 2009 +0200
@@ -34,12 +34,12 @@
# modules
module_objs = $(patsubst src/%.c,obj/%.o,$(wildcard src/$(1)/*.c))
-CORE_OBJS = obj/error.o obj/log.o obj/chain.o
+CORE_OBJS = obj/error.o obj/log.o
SOCK_OBJS = obj/sock.o obj/sock_tcp.o
SOCK_TEST_OBJS = obj/sock_test.o
SOCK_GNUTLS_OBJS = obj/sock_gnutls.o
LINEPROTO_OBJS = obj/line_proto.o
-IRC_OBJS = obj/irc_line.o obj/irc_conn.o obj/irc_net.o obj/irc_chan.o obj/irc_cmd.o obj/irc_proto.o obj/irc_client.o
+IRC_OBJS = obj/irc_line.o obj/irc_conn.o obj/irc_net.o obj/irc_chan.o obj/chain.o obj/irc_cmd.o obj/irc_proto.o obj/irc_client.o
NEXUS_OBJS = obj/signals.o obj/module.o
IRC_LOG_OBJS = obj/irc_log.o
@@ -54,11 +54,11 @@
bin/test: ${CORE_OBJS} ${SOCK_OBJS} ${SOCK_GNUTLS_OBJS} ${SOCK_TEST_OBJS} ${LINEPROTO_OBJS} ${IRC_OBJS}
-modules/irc_log.so: ${CORE_OBJS} ${IRC_OBJS}
+modules/irc_log.so: ${CORE_OBJS}
# computed
-CFLAGS = ${MODE_CFLAGS} ${FIXED_CFLAGS} ${LIBEVENT_CFLAGS} ${GNUTLS_CFLAGS} ${EVSQL_CFLAGS}
-LDFLAGS = ${LIBEVENT_LDFLAGS} ${GNUTLS_LDFLAGS} ${EVSQL_LDFLAGS}
+CFLAGS = ${MODE_CFLAGS} ${FIXED_CFLAGS} ${LIBEVENT_CFLAGS} ${GNUTLS_CFLAGS} ${EVSQL_CFLAGS} -fpic
+LDFLAGS = ${LIBEVENT_LDFLAGS} ${GNUTLS_LDFLAGS} ${EVSQL_LDFLAGS} -Wl,--export-dynamic
# XXX: is this valid?
CPPFLAGS = ${CFLAGS}
@@ -92,13 +92,13 @@
# XXX: removed $(CPPFLAGS)
obj/%.o : src/%.c
- $(CC) -fpic -c $(CFLAGS) $< -o $@
+ $(CC) -c $(CFLAGS) $< -o $@
bin/% : obj/%.o
$(CC) $(LDFLAGS) $+ $(LOADLIBES) $(LDLIBS) -o $@
modules/%.so : obj/%.o
- $(CC) -shared -Wl,-soname,$(basename %@) -o $@ $+ -lc
+ $(CC) -shared -Wl,-soname,$(notdir $@) -o $@ $+ -lc
# documentation
DOXYGEN_PATH = /usr/bin/doxygen
--- a/src/error.c Sun Mar 15 01:17:22 2009 +0200
+++ b/src/error.c Sun Mar 15 23:01:12 2009 +0200
@@ -51,6 +51,7 @@
{ ERR_MODULE_OPEN, "module dlopen() failed", ERR_EXTRA_NONE },
{ ERR_MODULE_NAME, "invalid module name", ERR_EXTRA_NONE },
{ ERR_MODULE_INIT_FUNC, "invalid module init func", ERR_EXTRA_NONE },
+ { ERR_MODULE_CONF, "module_conf", ERR_EXTRA_STR },
{ _ERR_INVALID, NULL, 0 }
};
@@ -132,6 +133,11 @@
snprintf(msg, ERROR_MSG_MAXLEN, "%s: %s", desc->name, gnutls_strerror(err->extra));
break;
+ case ERR_EXTRA_STR:
+ // static error message string
+ snprintf(msg, ERROR_MSG_MAXLEN, "%s: %s", desc->name, err->extra_str);
+ break;
+
default:
// ???
snprintf(msg, ERROR_MSG_MAXLEN, "%s: %#.8x", desc->name, err->extra);
--- a/src/error.h Sun Mar 15 01:17:22 2009 +0200
+++ b/src/error.h Sun Mar 15 23:01:12 2009 +0200
@@ -29,6 +29,9 @@
/** GnuTLS, using gnutls_strerror() */
ERR_EXTRA_GNUTLS,
+
+ /** Static error message string */
+ ERR_EXTRA_STR,
};
/**
@@ -47,10 +50,10 @@
ERR_GETADDRINFO,
ERR_GETADDRINFO_EMPTY,
- /** @see enum sock_error_code*/
+ /** @see sock_error_code*/
_ERR_SOCK = 0x000300,
- /** @see enum sock_gnutls_error_code */
+ /** @see sock_gnutls_error_code */
_ERR_GNUTLS = 0x000400,
/** Libevent errors */
@@ -78,7 +81,7 @@
_ERR_IRC_NET = 0x000900,
ERR_IRC_NET_QUIT_STATE,
- /** modul errors */
+ /** @see module_error_code */
_ERR_MODULE = 0x000a00,
};
@@ -102,9 +105,14 @@
struct error_info {
/** The base error code */
err_t code;
+
+ union {
+ /** Additional detail info, usually some third-party error code, as defined by the code's ERR_EXTRA_* */
+ int extra;
- /** Additional detail info, usually some third-party error code, as defined by the code's ERR_EXTRA_* */
- int extra;
+ /** Additional info, stored as a pointer to a static string (note how dangerous this is) */
+ const char *extra_str;
+ };
};
/**
@@ -153,6 +161,13 @@
#define _SET_ERROR_ERRNO(err_info_ptr, err_code) _SET_ERROR_EXTRA(err_info_ptr, err_code, errno);
#define SET_ERROR_ERRNO(err_info_ptr, err_code) SET_ERROR_EXTRA(err_info_ptr, err_code, errno);
+/**
+ * Set error_info.code to err_code, and .extra_str to str. The given string pointer should remain valid while the error
+ * is being handled down-stack.
+ */
+#define _SET_ERROR_STR(err_info_ptr, err_code, err_str) (err_info_ptr)->code = (err_code); (err_info_ptr)->extra_str = (err_str)
+#define SET_ERROR_STR(err_info_ptr, err_code, err_str) do { _SET_ERROR_STR(err_info_ptr, err_code, err_str); } while(0)
+
/** Set error_info from another error_info. Evaluates to the new error_info */
#define SET_ERROR_INFO(err_info_ptr, from_ptr) (*err_info_ptr = *from_ptr)
@@ -161,6 +176,7 @@
#define RETURN_SET_ERROR_EXTRA(err_info_ptr, err_code, err_extra) do { _SET_ERROR_EXTRA(err_info_ptr, err_code, err_extra); return (err_code); } while (0)
#define RETURN_SET_ERROR_ERRNO(err_info_ptr, err_code) do { _SET_ERROR_ERRNO(err_info_ptr, err_code); return (err_code); } while (0)
#define RETURN_SET_ERROR_INFO(err_info_ptr, from_ptr) do { SET_ERROR_INFO(err_info_ptr, from_ptr); return (from_ptr->code); } while (0)
+#define RETURN_SET_ERROR_STR(err_info_ptr, err_code, err_str) do { _SET_ERROR_STR(err_info_ptr, err_code, err_str); return (err_code); } while (0)
/** Same as above, but also do a 'goto error' */
#define JUMP_SET_ERROR(err_info_ptr, err_code) do { SET_ERROR(err_info_ptr, err_code); goto error; } while (0)
--- a/src/irc_log.c Sun Mar 15 01:17:22 2009 +0200
+++ b/src/irc_log.c Sun Mar 15 23:01:12 2009 +0200
@@ -11,6 +11,9 @@
* The core irc_log state
*/
static struct irc_log_ctx {
+ /** The nexus this module is loaded for */
+ struct nexus *nexus;
+
/** The database connection */
struct evsql *db;
@@ -40,40 +43,43 @@
// XXX: static pointer
ctx = &_ctx;
+ // initialize
+ memset(ctx, 0, sizeof(*ctx));
+
+ // store
+ ctx->nexus = modules->nexus;
+
// ok
return ctx;
}
-err_t irc_log_conf (struct module *module, const char *name, char *value)
+err_t irc_log_conf (void *mod_ctx, const char *name, char *value, struct error_info *err)
{
- struct irc_log_ctx *ctx = module->ctx;
- struct nexus *nexus = module->modules->nexus;
- err_t err;
+ struct irc_log_ctx *ctx = mod_ctx;
if (strcmp(name, "db_info") == 0) {
log_info("connect to database: %s", value);
- if ((ctx->db = evsql_new_pq(nexus->ev_base, value, NULL, NULL)) == NULL)
+ if ((ctx->db = evsql_new_pq(ctx->nexus->ev_base, value, NULL, NULL)) == NULL)
return ERR_EVSQL_NEW_PQ;
} else if (strcmp(name, "channel") == 0) {
- const char *network = strsep(&value, ":");
+ const char *network = strsep(&value, "/");
const char *channel = value;
struct irc_chan *chan;
// kill missing tokens
if (!network || !channel)
- // XXX: need to fix the error crap
- return -1;
+ RETURN_SET_ERROR_STR(err, ERR_MODULE_CONF, "invalid '<network>/<channel>' value");
// get the channel?
- if ((chan = irc_client_get_chan(nexus->client, network, channel)) == NULL)
- return -1;
+ if ((chan = irc_client_get_chan(ctx->nexus->client, network, channel)) == NULL)
+ RETURN_SET_ERROR_STR(err, ERR_MODULE_CONF, "unknown channel name");
// add channel callbacks
- if ((err = irc_chan_add_callbacks(chan, &_chan_callbacks, ctx)))
- return err;
+ if ((ERROR_CODE(err) = irc_chan_add_callbacks(chan, &_chan_callbacks, ctx)))
+ return ERROR_CODE(err);
} else {
return -1;
--- a/src/irc_log.h Sun Mar 15 01:17:22 2009 +0200
+++ b/src/irc_log.h Sun Mar 15 23:01:12 2009 +0200
@@ -20,8 +20,8 @@
* Set one of the config options:
*
* db_info - the database connection string
- * channel - the network:channel to log
+ * channel - the '<network>/<channel>' to log
*/
-err_t irc_log_conf (struct module *module, const char *name, char *value);
+err_t irc_log_conf (void *mod_ctx, const char *name, char *value, struct error_info *err);
#endif
--- a/src/module.c Sun Mar 15 01:17:22 2009 +0200
+++ b/src/module.c Sun Mar 15 23:01:12 2009 +0200
@@ -82,8 +82,12 @@
JUMP_SET_ERROR(err, ERR_MODULE_INIT_FUNC);
// call it
- if ((module->ctx = init_func(modules, err)))
+ if ((module->ctx = init_func(modules, err)) == NULL) {
+ // ensure that this results in a valid error return code!
+ assert(ERROR_CODE(err));
+
goto error;
+ }
// add to modules list
TAILQ_INSERT_TAIL(&modules->list, module, modules_list);
@@ -100,18 +104,17 @@
return ERROR_CODE(err);
}
-err_t module_conf (struct module *module, const char *name, char *value)
+err_t module_conf (struct module *module, const char *name, char *value, struct error_info *err)
{
module_conf_func_t conf_func;
- err_t err;
// load the conf symbol
- if ((err = module_symbol(module, (void *) &conf_func, "conf")))
- return err;
+ if ((ERROR_CODE(err) = module_symbol(module, (void *) &conf_func, "conf")))
+ return ERROR_CODE(err);
// call it
- if ((err = conf_func(module, name, value)))
- return err;
+ if (conf_func(module->ctx, name, value, err))
+ return ERROR_CODE(err);
// ok
return SUCCESS;
--- a/src/module.h Sun Mar 15 01:17:22 2009 +0200
+++ b/src/module.h Sun Mar 15 23:01:12 2009 +0200
@@ -67,6 +67,7 @@
ERR_MODULE_NAME, ///< invalid module_info.name
ERR_MODULE_SYM, ///< invalid symbol
ERR_MODULE_INIT_FUNC, ///< invalid module_init_func_t
+ ERR_MODULE_CONF, ///< value error in configuration data
};
/**
@@ -86,7 +87,7 @@
* @param value the value of the configuration setting
* @return error code
*/
-typedef err_t (*module_conf_func_t) (struct module *module, const char *name, char *value);
+typedef err_t (*module_conf_func_t) (void *ctx, const char *name, char *value, struct error_info *err);
/**
* Maximum length of a module name
@@ -111,12 +112,12 @@
/**
* Load a new module
*/
-err_t module_load (struct modules *modules, struct module **module, const struct module_info *info, struct error_info *err);
+err_t module_load (struct modules *modules, struct module **module_ptr, const struct module_info *info, struct error_info *err);
/**
* Set a module configuration option
*/
-err_t module_conf (struct module *module, const char *name, char *value);
+err_t module_conf (struct module *module, const char *name, char *value, struct error_info *err);
/**
* Unload a module
--- a/src/nexus.c Sun Mar 15 01:17:22 2009 +0200
+++ b/src/nexus.c Sun Mar 15 23:01:12 2009 +0200
@@ -181,18 +181,20 @@
// get the channel
if (log_chan_info.channel) {
+ char conf_channel[] = "default/#test";
+
// create the channel
if ((irc_net_add_chan(net, &log_chan_info)) == NULL)
FATAL("irc_net_add_chan");
// configure it
// XXX: hardcoded
- if ((ERROR_CODE(&err) = module_conf(mod_irc_log, "channel", "default/#test")))
- FATAL_ERROR(&err, "module_conf(irc_log, '%s', '%s)", "channel", "default/#test");
+ if (module_conf(mod_irc_log, "channel", conf_channel, &err))
+ FATAL_ERROR(&err, "module_conf(irc_log, '%s', '%s)", "channel", conf_channel);
}
// configure the databse info
- if (log_db_info && (ERROR_CODE(&err) = module_conf(mod_irc_log, "db_info", log_db_info)))
+ if (log_db_info && module_conf(mod_irc_log, "db_info", log_db_info, &err))
FATAL_ERROR(&err, "module_conf(irc_log, 'db_info', '%s')", log_db_info);
}