# HG changeset patch # User Tero Marttila # Date 1238531765 -10800 # Node ID cfb7776bd6f09379186380f660b3c3b55f83223b # Parent 155a6c7d388669452210dcbed3a88e6a4dad1376 improve the config module futher, now the module_desc interface uses structured config_value's diff -r 155a6c7d3886 -r cfb7776bd6f0 src/config.c --- a/src/config.c Tue Mar 31 23:35:24 2009 +0300 +++ b/src/config.c Tue Mar 31 23:36:05 2009 +0300 @@ -1,21 +1,140 @@ #include "config.h" #include +#include -err_t config_apply (struct config_option *options, void *ctx, const char *name, char *value, struct error_info *err) +const struct config_option* config_lookup (const struct config_option *options, const char *name, struct error_info *err) { - struct config_option *option; + const struct config_option *option; // find the matching config opt for (option = options; option->name && option->type; option++) { if (strcmp(option->name, name) == 0) + return option; + } + + // not found + SET_ERROR_STR(err, ERR_MODULE_CONF, "unknown configuration option"); + + return NULL; +} + +/** + * Parse a raw value for a CONFIG_IRC_CHAN into an irc_chan + */ +static struct irc_chan* config_parse_irc_chan (struct nexus *nexus, char *raw_value, struct error_info *err) +{ + const char *network, *channel; + struct irc_chan *chan; + + // parse required args + if ((network = strsep(&raw_value, "/")) == NULL) + JUMP_SET_ERROR_STR(err, ERR_MODULE_CONF, "invalid for CONFIG_IRC_CHAN value"); + + if ((channel = strsep(&raw_value, "/")) == NULL) + JUMP_SET_ERROR_STR(err, ERR_MODULE_CONF, "invalid for CONFIG_IRC_CHAN value"); + + // extraneous stuff? + if (raw_value) + JUMP_SET_ERROR_STR(err, ERR_MODULE_CONF, "trailing data for CONFIG_IRC_CHAN value"); + + // get the channel? + if ((chan = irc_client_get_chan(nexus->client, network, channel)) == NULL) + JUMP_SET_ERROR_STR(err, ERR_MODULE_CONF, "unknown network/channel name for CONFIG_IRC_CHAN value"); + + // ok + return chan; + +error: + return NULL; +} + +err_t config_parse (const struct config_option *option, struct nexus *nexus, struct config_value *value, char *raw_value, struct error_info *err) +{ + // parse the value + switch (option->type) { + case CONFIG_STRING: + // simple! + value->string = raw_value; break; + + case CONFIG_IRC_CHAN: + // parse the value + if (!(value->irc_chan = config_parse_irc_chan(nexus, raw_value, err))) + return ERROR_CODE(err); + + break; + + default: + NOT_REACHED(); } + // copy the type + value->type = option->type; + + // ok + return SUCCESS; +} + +err_t config_apply_opt (const struct config_option *option, void *ctx, const struct config_value *value, struct error_info *err) +{ + // wrong type? + if (option->type != value->type) + // XXX: info about type names + return SET_ERROR(err, ERR_CONFIG_TYPE); + + // null? + if (!value) + RETURN_SET_ERROR_STR(err, ERR_CONFIG_REQUIRED, option->name); + + // call the handler + switch (option->type) { + case CONFIG_STRING: return option->func.string(ctx, value->string, err); + case CONFIG_IRC_CHAN: return option->func.irc_chan(ctx, value->irc_chan, err); + default: NOT_REACHED(); + } +} + +err_t config_apply (const struct config_option *options, void *ctx, const char *name, const struct config_value *value, struct error_info *err) +{ + const struct config_option *option; + // no matching option found? - if (!option) - RETURN_SET_ERROR_STR(err, ERR_CONFIG_NAME, name); + if (!(option = config_lookup(options, name, err))) + return ERROR_CODE(err); + + // apply it + return config_apply_opt(option, ctx, value, err); +} - // call the handler - return option->func(ctx, value, err); +err_t config_apply_string (const struct config_option *options, void *ctx, const char *name, char *value, struct error_info *err) +{ + struct config_value conf_value = { CONFIG_STRING, { .string = value } }; + + return config_apply(options, ctx, name, &conf_value, err); } + +err_t config_apply_irc_chan (const struct config_option *options, void *ctx, const char *name, struct irc_chan *value, struct error_info *err) +{ + struct config_value conf_value = { CONFIG_STRING, { .irc_chan = value } }; + + return config_apply(options, ctx, name, &conf_value, err); +} + +err_t config_apply_raw (const struct config_option *options, struct nexus *nexus, void *ctx, const char *name, char *raw_value, struct error_info *err) +{ + const struct config_option *option; + struct config_value value; + + // no matching option found? + if (!(option = config_lookup(options, name, err))) + return ERROR_CODE(err); + + // parse it + if (config_parse(option, nexus, &value, raw_value, err)) + return ERROR_CODE(err); + + // apply it + return config_apply_opt(option, ctx, &value, err); +} + diff -r 155a6c7d3886 -r cfb7776bd6f0 src/config.h --- a/src/config.h Tue Mar 31 23:35:24 2009 +0300 +++ b/src/config.h Tue Mar 31 23:36:05 2009 +0300 @@ -16,6 +16,26 @@ /** A plain NUL-terminated string */ CONFIG_STRING, + + /** An IRC channel */ + CONFIG_IRC_CHAN, +}; + +/** + * Structure to hold a value as defined by config_type + */ +struct config_value { + /** The type of the value */ + enum config_type type; + + /** The typed value */ + union { + /** Value for CONFIG_STRING */ + char *string; + + /** Value for CONFIG_IRC_CHAN */ + struct irc_chan *irc_chan; + }; }; /** @@ -25,11 +45,14 @@ /** The name of the config option */ const char *name; - /** The type of the value, XXX: unused */ + /** The type of the value expected */ enum config_type type; - /** The value handler func */ - err_t (*func) (void *ctx, char *value, struct error_info *err); + /** The value handler func, by type */ + union { + err_t (*string) (void *ctx, char *value, struct error_info *err); + err_t (*irc_chan) (void *ctx, struct irc_chan *chan, struct error_info *err); + } func; /** The value description */ const char *description; @@ -38,11 +61,102 @@ const char *help; }; +#define CONFIG_OPT_STRING(name, func, desc, help) \ + { name, CONFIG_STRING, { .string = func }, desc, help } + +#define CONFIG_OPT_IRC_CHAN(name, func, desc, help) \ + { name, CONFIG_IRC_CHAN, { .irc_chan = func }, desc, help } + +#define CONFIG_OPT_END \ + { NULL, CONFIG_INVALID, { NULL }, NULL, NULL } + /** - * Apply a configuration name/value to an array of config_option's. + * Lookup a config option by name. * - * This finds the appropriate config_option and calls its func. + * @param options a CONFIG_OPT_END-terminated array of config_option's + * @param name the config_option::name to look up + * @param err returned error info if not found + * @return a direct pointer to the config_option if found */ -err_t config_apply (struct config_option *options, void *ctx, const char *name, char *value, struct error_info *err); +const struct config_option* config_lookup (const struct config_option *options, const char *name, struct error_info *err); + +// XXX: move this into nexus +#include "nexus.h" +/** + * Parse a raw value into a suitable configuration value, based on the config option type. + * + * Since this needs to access the application state, you need to pass in the nexus as an argument. + * + * Formats supported: + * CONFIG_IRC_CHAN - uses a '/' format and irc_client_get_chan + * + * @param option the option to parse the value for, use config_lookup to find it + * @param nexus the application state + * @param value the returned value, if succesfull + * @param raw_value the raw value to parse based on the type + * @param err returned error info + */ +err_t config_parse (const struct config_option *option, struct nexus *nexus, struct config_value *value, char *raw_value, struct error_info *err); + +/** + * Apply a parsed configuration value to the given option. + * + * The config option handlers take a context argument; the value of this depends on the implementor of the config_option. + * + * @param option the option to apply + * @param ctx the context pointer for the option handler + * @param value the parsed value + * @param err returned error info + */ +err_t config_apply_opt (const struct config_option *option, void *ctx, const struct config_value *value, struct error_info *err); + +/** + * Apply a parsed configuration value for the named config opt. + * + * @param options a CONFIG_OPT_END-terminated array of config_option's + * @param ctx the context pointer for the option handler + * @param name the config_option::name to look up + * @param value the parsed value + * @param err returned error info + */ +err_t config_apply (const struct config_option *options, void *ctx, const char *name, const struct config_value *value, struct error_info *err); + +/** + * Apply a string value for the named config opt. + * + * @param options a CONFIG_OPT_END-terminated array of config_option's + * @param ctx the context pointer for the option handler + * @param name the config_option::name to look up + * @param value the string value + * @param err returned error info + */ +err_t config_apply_string (const struct config_option *options, void *ctx, const char *name, char *value, struct error_info *err); + +/** + * Apply an irc_chan value for the named config opt. + * + * @param options a CONFIG_OPT_END-terminated array of config_option's + * @param ctx the context pointer for the option handler + * @param name the config_option::name to look up + * @param value the irc_chan value + * @param err returned error info + */ +err_t config_apply_irc_chan (const struct config_option *options, void *ctx, const char *name, struct irc_chan *value, struct error_info *err); + +/** + * Parse and apply a configuration value for the named config opt. + * + * See config_parse() for more info. + * + * @param options a CONFIG_OPT_END-terminated array of config_option's + * @param nexus the application state + * @param ctx the context pointer for the option handler + * @param name the config_option::name to look up + * @param raw_value the raw value to parse + * @param err returned error info + * + * @see config_parse + */ +err_t config_apply_raw (const struct config_option *options, struct nexus *nexus, void *ctx, const char *name, char *raw_value, struct error_info *err); #endif diff -r 155a6c7d3886 -r cfb7776bd6f0 src/error.c --- a/src/error.c Tue Mar 31 23:35:24 2009 +0300 +++ b/src/error.c Tue Mar 31 23:36:05 2009 +0300 @@ -19,7 +19,6 @@ { ERR_EVENT_ADD, "event_add", ERR_EXTRA_NONE }, { ERR_EVSQL_NEW_PQ, "evsql_new_pq", ERR_EXTRA_NONE }, { ERR_EVSQL_QUERY_EXEC, "evsql_query_exec", ERR_EXTRA_NONE }, - { ERR_CONFIG_NAME, "no matching config name", ERR_EXTRA_STR }, { ERR_CMD_OPT, "argv", ERR_EXTRA_STR }, { _ERR_INVALID, NULL, 0 } @@ -45,18 +44,44 @@ { ERR_GNUTLS_RECORD_GET_DIRECTION, "gnutls_record_get_direction", ERR_EXTRA_GNUTLS }, { _ERR_INVALID, NULL, 0 } -}, _irc_proto_error_desc[] = { +}, _irc_error_desc[] = { { ERR_LINE_TOO_LONG, "IRC line is too long", ERR_EXTRA_NONE }, { ERR_LINE_INVALID_TOKEN, "Illegal token value for IRC line", ERR_EXTRA_NONE }, { ERR_INVALID_NM, "Invalid nickmask", ERR_EXTRA_NONE }, { ERR_INVALID_NICK_LENGTH, "Nickname is too long", ERR_EXTRA_NONE }, + + // extra: the name of the invalid field + { ERR_IRC_NET_INFO, "invalid irc_net_info", ERR_EXTRA_STR }, + { ERR_IRC_NET_STATE, "invalid irc_net state for operation", ERR_EXTRA_NONE }, + { ERR_IRC_CHAN_STATE, "invalid irc_chan state for operation", ERR_EXTRA_NONE }, + { _ERR_INVALID, NULL, 0 } + +}, _config_error_desc[] = { + // extra: the (unknown) config field name + { ERR_CONFIG_NAME, "no matching config name", ERR_EXTRA_STR }, + + // XXX: extra: the mismatching types + { ERR_CONFIG_TYPE, "wrong config type", ERR_EXTRA_NONE }, + + // extra: the name of the field with missing value + { ERR_CONFIG_REQUIRED, "missing required value", ERR_EXTRA_STR }, + + { _ERR_INVALID, NULL, 0 } + }, _module_error_desc[] = { { ERR_MODULE_OPEN, "module dlopen() failed", ERR_EXTRA_STR }, { ERR_MODULE_NAME, "invalid module name", ERR_EXTRA_NONE }, { ERR_MODULE_INIT_FUNC, "invalid module init func", ERR_EXTRA_STR }, { ERR_MODULE_CONF, "module_conf", ERR_EXTRA_STR }, { _ERR_INVALID, NULL, 0 } + +}, _lua_error_desc[] = { + { ERR_LUA_MEM, "lua: out of memory", ERR_EXTRA_NONE }, + { ERR_LUA_SYNTAX, "lua: syntax error", ERR_EXTRA_NONE }, + { ERR_LUA_RUN, "lua: runtime error", ERR_EXTRA_NONE }, + { ERR_LUA_ERR, "lua: error handling error", ERR_EXTRA_NONE }, + { _ERR_INVALID, NULL, 0 } }; /** @@ -66,8 +91,9 @@ _core_error_desc, _sock_error_desc, _sock_gnutls_error_desc, - _irc_proto_error_desc, + _irc_error_desc, _module_error_desc, + _lua_error_desc, NULL }; diff -r 155a6c7d3886 -r cfb7776bd6f0 src/error.h --- a/src/error.h Tue Mar 31 23:35:24 2009 +0300 +++ b/src/error.h Tue Mar 31 23:36:05 2009 +0300 @@ -90,6 +90,8 @@ /** config errors */ _ERR_CONFIG = 0x000b00, ERR_CONFIG_NAME, + ERR_CONFIG_TYPE, + ERR_CONFIG_REQUIRED, /** lua errors */ _ERR_LUA = 0x000c00, @@ -209,4 +211,9 @@ #define JUMP_SET_ERROR_INFO(err_info_ptr, from_ptr) do { SET_ERROR_INFO(err_info_ptr, from_ptr); goto error; } while (0) #define JUMP_SET_ERROR_STR(err_info_ptr, err_code, err_str) do { _SET_ERROR_STR(err_info_ptr, err_code, err_str); goto error; } while (0) +/** + * Macro used to mark code segments that should never be executed (e.g. switch-default), kind of like assert + */ +#define NOT_REACHED() assert(false) + #endif diff -r 155a6c7d3886 -r cfb7776bd6f0 src/irc_client.c --- a/src/irc_client.c Tue Mar 31 23:35:24 2009 +0300 +++ b/src/irc_client.c Tue Mar 31 23:36:05 2009 +0300 @@ -58,18 +58,28 @@ }; // combine _net_info and defaults to get net_info - if ( - _net_info->raw_sock - || (net_info.network = _net_info->network) == NULL - || (net_info.hostname = _net_info->hostname) == NULL - || (net_info.service = (_net_info->service ? _net_info->service : ( + if (_net_info->raw_sock) + RETURN_SET_ERROR_STR(err, ERR_IRC_NET_INFO, "raw_sock"); + + if ((net_info.network = _net_info->network) == NULL) + RETURN_SET_ERROR_STR(err, ERR_IRC_NET_INFO, "network"); + + if ((net_info.hostname = _net_info->hostname) == NULL) + RETURN_SET_ERROR_STR(err, ERR_IRC_NET_INFO, "hostname"); + + if ((net_info.service = (_net_info->service ? _net_info->service : ( _net_info->use_ssl ? client->defaults.service_ssl : client->defaults.service - ))) == NULL - || APPLY_REGISTER_INFO_DEFAULT(&net_info, _net_info, &client->defaults, nickname) - || APPLY_REGISTER_INFO_DEFAULT(&net_info, _net_info, &client->defaults, username) - || APPLY_REGISTER_INFO_DEFAULT(&net_info, _net_info, &client->defaults, realname) - ) - return SET_ERROR(err, ERR_IRC_NET_INFO); + ))) == NULL) + RETURN_SET_ERROR_STR(err, ERR_IRC_NET_INFO, "service"); + + if (APPLY_REGISTER_INFO_DEFAULT(&net_info, _net_info, &client->defaults, nickname)) + RETURN_SET_ERROR_STR(err, ERR_IRC_NET_INFO, "nickname"); + + if (APPLY_REGISTER_INFO_DEFAULT(&net_info, _net_info, &client->defaults, username)) + RETURN_SET_ERROR_STR(err, ERR_IRC_NET_INFO, "username"); + + if (APPLY_REGISTER_INFO_DEFAULT(&net_info, _net_info, &client->defaults, realname)) + RETURN_SET_ERROR_STR(err, ERR_IRC_NET_INFO, "realname"); // create the new irc_chan struct if (irc_net_create(&net, &net_info, err)) diff -r 155a6c7d3886 -r cfb7776bd6f0 src/irc_log.c --- a/src/irc_log.c Tue Mar 31 23:35:24 2009 +0300 +++ b/src/irc_log.c Tue Mar 31 23:36:05 2009 +0300 @@ -440,31 +440,14 @@ * Fails if the value is invalid, we don't have a database connected, the channel doesn't exist, adding our command * handlers/callbacks fails, or sending the initial INSERT-OPEN query fails. */ -static err_t irc_log_conf_channel (void *_ctx, char *value, struct error_info *err) +static err_t irc_log_conf_channel (void *_ctx, struct irc_chan *chan, struct error_info *err) { struct irc_log_ctx *ctx = _ctx; - const char *network, *channel; - struct irc_chan *chan; - // parse required args - if ((network = strsep(&value, ":")) == NULL) - RETURN_SET_ERROR_STR(err, ERR_MODULE_CONF, "invalid for irc_log.channel"); - - if ((channel = strsep(&value, ":")) == NULL) - RETURN_SET_ERROR_STR(err, ERR_MODULE_CONF, "invalid for irc_log.channel"); - - // extraneous stuff? - if (value) - RETURN_SET_ERROR_STR(err, ERR_MODULE_CONF, "trailing data for irc_log.channel"); - // have a db configured? if (!ctx->db) RETURN_SET_ERROR_STR(err, ERR_MODULE_CONF, "irc_log.channel used without any irc_log.db_info"); - // get the channel? - if ((chan = irc_client_get_chan(ctx->nexus->client, network, channel)) == NULL) - RETURN_SET_ERROR_STR(err, ERR_MODULE_CONF, "unknown channel name"); - // begin logging it if (irc_log_chan(ctx, chan, err)) return ERROR_CODE(err); @@ -477,25 +460,11 @@ * Our configuration options */ struct config_option irc_log_config_options[] = { - { "db_info", CONFIG_STRING, &irc_log_conf_db_info, "[= [...]]", "set database connection info, see libpq docs" }, - { "channel", CONFIG_STRING, &irc_log_conf_channel, ":", "log the given channel" }, - { NULL, 0, NULL, NULL, NULL } -}; + CONFIG_OPT_STRING( "db_info", &irc_log_conf_db_info, "[= [...]]", "set database connection info, see libpq docs" ), + CONFIG_OPT_IRC_CHAN( "channel", &irc_log_conf_channel, "", "log the given channel" ), -/** - * Set a config option - */ -static err_t irc_log_conf (void *_ctx, const char *name, char *value, struct error_info *err) -{ - struct irc_log_ctx *ctx = _ctx; - - // wrong state - if (ctx->unloading) - RETURN_SET_ERROR_STR(err, ERR_MODULE_CONF, "module is being unloaded"); - - // apply it - return config_apply(irc_log_config_options, ctx, name, value, err); -} + CONFIG_OPT_END +}; /** * Deinitialize, logging CLOSE events for all channels, and removing any hooks we've added @@ -520,9 +489,8 @@ /** * The module function table */ -struct module_funcs irc_log_funcs = { +struct module_desc irc_log_module = { .init = &irc_log_init, - .conf = &irc_log_conf, .config_options = irc_log_config_options, .unload = &irc_log_unload, }; diff -r 155a6c7d3886 -r cfb7776bd6f0 src/irc_proto.h --- a/src/irc_proto.h Tue Mar 31 23:35:24 2009 +0300 +++ b/src/irc_proto.h Tue Mar 31 23:36:05 2009 +0300 @@ -10,6 +10,16 @@ #include /** + * Default TCP port for normal connections + */ +#define IRC_PORT "6667" + +/** + * Default TCP port for SSL connections + */ +#define IRC_SSL_PORT "6697" + +/** * Maximum length of an IRC nickname including terminating NUL. */ #define IRC_NICK_MAX (30 + 1) diff -r 155a6c7d3886 -r cfb7776bd6f0 src/module.c --- a/src/module.c Tue Mar 31 23:35:24 2009 +0300 +++ b/src/module.c Tue Mar 31 23:36:05 2009 +0300 @@ -72,11 +72,11 @@ JUMP_SET_ERROR_STR(err, ERR_MODULE_OPEN, dlerror()); // load the funcs symbol - if ((ERROR_CODE(err) = module_symbol(module, (void **) &module->funcs, "funcs"))) + if ((ERROR_CODE(err) = module_symbol(module, (void **) &module->desc, "module"))) JUMP_SET_ERROR_STR(err, ERROR_CODE(err), dlerror()); // call the init func - if ((module->funcs->init(modules->nexus, &module->ctx, err))) + if ((module->desc->init(modules->nexus, &module->ctx, err))) goto error; // add to modules list @@ -110,19 +110,52 @@ return NULL; } -err_t module_conf (struct module *module, const char *name, char *value, struct error_info *err) +err_t module_conf_raw (struct module *module, const char *name, char *value, struct error_info *err) { - // call the conf func - return module->funcs->conf(module->ctx, name, value, err); + if (!module->desc->config_options) + RETURN_SET_ERROR_STR(err, ERR_MODULE_CONF, "module does not have any config options"); + + // wrong state + if (module->unloading) + RETURN_SET_ERROR_STR(err, ERR_MODULE_CONF, "module is being unloaded"); + + // parse/apply using the module's stuff + return config_apply_raw(module->desc->config_options, module->modules->nexus, module->ctx, name, value, err); +} + +const struct config_option* module_conf_lookup (struct module *module, const char *name, struct error_info *err) +{ + if (!module->desc->config_options) + JUMP_SET_ERROR_STR(err, ERR_MODULE_CONF, "module does not have any config options"); + + // direct lookup + return config_lookup(module->desc->config_options, name, err); + +error: + return NULL; +} + +err_t module_conf (struct module *module, const struct config_option *opt, const struct config_value *value, struct error_info *err) +{ + // wrong state + if (module->unloading) + RETURN_SET_ERROR_STR(err, ERR_MODULE_CONF, "module is being unloaded"); + + // apply with the module's ctx + return config_apply_opt(opt, module->ctx, value, err); } err_t module_unload (struct module *module) { err_t err; - + // invoke the unload func - if ((err = module->funcs->unload(module->ctx))) + if ((err = module->desc->unload(module->ctx))) return err; + + // update status + // XXX: before or after? + module->unloading = true; // ok return SUCCESS; diff -r 155a6c7d3886 -r cfb7776bd6f0 src/module.h --- a/src/module.h Tue Mar 31 23:35:24 2009 +0300 +++ b/src/module.h Tue Mar 31 23:36:05 2009 +0300 @@ -28,12 +28,10 @@ }; /** - * A table of (function) pointers defining a module's behaviour. This is dynamically resolved from the module DSO - * using the "_funcs" symbol. - * - * XXX: this also includes non-functions now... + * A table of (function/other) pointers defining a module's behaviour. This is dynamically resolved from the module DSO + * using the "_module" symbol. */ -struct module_funcs { +struct module_desc { /** * Initialize the module, returning an opaque context pointer that is stored in the module state, and supplied for * subsequent calls. The supplied nexus arg can be used to access the global state. @@ -45,23 +43,10 @@ err_t (*init) (struct nexus *nexus, void **ctx_ptr, struct error_info *err); /** - * Set a configuration option with the given name and value, given by the user. Configuration settings are not - * regarded as unique-per-name, but rather, several invocations of 'conf' with the same name and different values - * could set up a multitude of things. - * - * The given value is either a NUL-terminated string value (which may be mutated, using e.g. strsep), or NULL if - * no value was given (flag option). + * A module may define a set of available configuration parameters for use by module_conf, by setting this to an + * array of config_option's. * - * @param ctx the module's context pointer as returned by init - * @param name the name of the configuration setting - * @param value the value of the configuration setting - * @param err returned error info - */ - err_t (*conf) (void *ctx, const char *name, char *value, struct error_info *err); - - /** - * Optionally, a module may also provide some kind of list of available configuration parameters, by setting this - * to a pointer to an array of those. + * The handler functions will recieve the module's context pointer as their ctx argument. */ const struct config_option *config_options; @@ -86,8 +71,8 @@ /** The dlopen handle */ void *handle; - /** The resolved function table */ - struct module_funcs *funcs; + /** The module entry point */ + struct module_desc *desc; /** The module context object */ void *ctx; @@ -95,6 +80,11 @@ /** Reference back to modules struct used to load this module */ struct modules *modules; + /** + * Is the module currently being unloaded? + */ + bool unloading; + /** Our entry in the list of modules */ TAILQ_ENTRY(module) modules_list; }; @@ -164,9 +154,19 @@ struct module* module_get (struct modules *modules, const char *name); /** - * Set a module configuration option + * Look up a module configuration option by name */ -err_t module_conf (struct module *module, const char *name, char *value, struct error_info *err); +const struct config_option* module_conf_lookup (struct module *module, const char *name, struct error_info *err); + +/** + * Apply a module configuration option using a structured value + */ +err_t module_conf (struct module *module, const struct config_option *opt, const struct config_value *value, struct error_info *err); + +/** + * Set a module configuration option using a raw value + */ +err_t module_conf_raw (struct module *module, const char *name, char *value, struct error_info *err); /** * Unload a module. This means calling its 'unload' func, which will then go about shutting down the module. This might diff -r 155a6c7d3886 -r cfb7776bd6f0 src/nexus.c --- a/src/nexus.c Tue Mar 31 23:35:24 2009 +0300 +++ b/src/nexus.c Tue Mar 31 23:36:05 2009 +0300 @@ -9,10 +9,6 @@ #include #include -#define DEFAULT_HOST "irc.fixme.fi" -#define DEFAULT_PORT "6667" -#define DEFAULT_PORT_SSL "6697" - /** * Command-line option codes */ @@ -75,10 +71,11 @@ printf("\n"); printf("%s:\n", module->info.name); - if (module->funcs->config_options) { + // XXX: shouldn't be accessing directly + if (module->desc->config_options) { const struct config_option *opt; - for (opt = module->funcs->config_options; opt->name && opt->type; opt++) { + for (opt = module->desc->config_options; opt->name && opt->type; opt++) { printf(" --config %s:%s:%s\t\t%s\n", module->info.name, opt->name, opt->description, opt->help); } @@ -96,8 +93,8 @@ { struct irc_client_defaults defaults = { .register_info = { NULL, NULL, NULL }, - .service = DEFAULT_PORT, - .service_ssl = DEFAULT_PORT_SSL, + .service = IRC_PORT, + .service_ssl = IRC_SSL_PORT, }; // parse the required fields @@ -260,7 +257,7 @@ // do the config log_info("applying module '%s' config name '%s' with value: %s", module->info.name, conf_name, conf_value); - if (module_conf(module, conf_name, conf_value, err)) + if (module_conf_raw(module, conf_name, conf_value, err)) return ERROR_CODE(err); // ok