# HG changeset patch # User Tero Marttila # Date 1237158876 -7200 # Node ID ef8c9d7daf6287093daad6a98764ea68d3483921 # Parent d7508879ad0122f557f6488feeb0f7f6d6fc0c97 all options are now fully implemented diff -r d7508879ad01 -r ef8c9d7daf62 src/irc_log.c --- a/src/irc_log.c Mon Mar 16 01:03:41 2009 +0200 +++ b/src/irc_log.c Mon Mar 16 01:14:36 2009 +0200 @@ -74,14 +74,14 @@ 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) - RETURN_SET_ERROR_STR(err, ERR_MODULE_CONF, "invalid '/' value"); + RETURN_SET_ERROR_STR(err, ERR_MODULE_CONF, "invalid ':' value"); // get the channel? if ((chan = irc_client_get_chan(ctx->nexus->client, network, channel)) == NULL) @@ -92,8 +92,7 @@ return ERROR_CODE(err); } else { - return -1; - + RETURN_SET_ERROR_STR(err, ERR_MODULE_CONF, "unknown configuration option"); } // ok diff -r d7508879ad01 -r ef8c9d7daf62 src/module.c --- a/src/module.c Mon Mar 16 01:03:41 2009 +0200 +++ b/src/module.c Mon Mar 16 01:14:36 2009 +0200 @@ -94,6 +94,21 @@ return ERROR_CODE(err); } +struct module* module_get (struct modules *modules, const char *name) +{ + struct module *module = NULL; + + // look for it... + TAILQ_FOREACH(module, &modules->list, modules_list) { + if (strcasecmp(module->info.name, name) == 0) + // found it + return module; + } + + // no such module + return NULL; +} + err_t module_conf (struct module *module, const char *name, char *value, struct error_info *err) { // call the conf func diff -r d7508879ad01 -r ef8c9d7daf62 src/module.h --- a/src/module.h Mon Mar 16 01:03:41 2009 +0200 +++ b/src/module.h Mon Mar 16 01:14:36 2009 +0200 @@ -46,7 +46,8 @@ * 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. * - * XXX: make value a non-modifyable string + * 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). * * @param ctx the module's context pointer as returned by init * @param name the name of the configuration setting @@ -132,6 +133,15 @@ err_t module_load (struct modules *modules, struct module **module_ptr, const struct module_info *info, struct error_info *err); /** + * Lookup a module by name + * + * @param modules the modules state + * @param name the module name to get + * @return the module struct, or NULL if not found + */ +struct module* module_get (struct modules *modules, const char *name); + +/** * Set a module configuration option */ err_t module_conf (struct module *module, const char *name, char *value, struct error_info *err); diff -r d7508879ad01 -r ef8c9d7daf62 src/nexus.c --- a/src/nexus.c Mon Mar 16 01:03:41 2009 +0200 +++ b/src/nexus.c Mon Mar 16 01:14:36 2009 +0200 @@ -93,9 +93,9 @@ RETURN_SET_ERROR_STR(err, ERR_CMD_OPT, "unrecognized flag for --network"); } + // create the net log_info("add network '%s' at '%s:%s'", info.network, info.hostname, info.service); - // create the net if (irc_client_add_net(nexus->client, NULL, &info, err)) return ERROR_CODE(err); @@ -129,9 +129,9 @@ if ((net = irc_client_get_net(nexus->client, network)) == NULL) RETURN_SET_ERROR_STR(err, ERR_CMD_OPT, "unknown network for --channel"); + // add the channel log_info("add channel '%s' on network '%s'", info.channel, net->info.network); - // add the channel if (irc_net_add_chan(net, NULL, &info, err)) return ERROR_CODE(err); @@ -161,9 +161,9 @@ if (opt) RETURN_SET_ERROR_STR(err, ERR_CMD_OPT, "trailing values for --channel"); + // load it log_info("loading module '%s' from path '%s'", info.name, info.path); - // load it if (module_load(nexus->modules, &module, &info, err)) return ERROR_CODE(err); @@ -172,6 +172,39 @@ } /** + * Parse and apply a --config option, calling the module's conf func. + */ +static err_t apply_config (struct nexus *nexus, char *opt, struct error_info *err) +{ + struct module *module; + const char *module_name, *conf_name; + char *conf_value; + + // parse the required fields + if ((module_name = strsep(&opt, ":")) == NULL) + RETURN_SET_ERROR_STR(err, ERR_CMD_OPT, "missing field for --config"); + + if ((conf_name = strsep(&opt, ":")) == NULL) + RETURN_SET_ERROR_STR(err, ERR_CMD_OPT, "missing field for --config"); + + // value is the rest of the data, might be NULL + conf_value = opt; + + // lookup the module + if ((module = module_get(nexus->modules, module_name)) == NULL) + RETURN_SET_ERROR_STR(err, ERR_CMD_OPT, "unknown module for --config"); + + // 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)) + return ERROR_CODE(err); + + // ok + return SUCCESS; +} + +/** * Parse arguments and apply them to the given nexus */ static err_t parse_args (struct nexus *nexus, int argc, char **argv, struct error_info *err) @@ -206,7 +239,10 @@ break; case OPT_CONFIG: - RETURN_SET_ERROR_STR(err, ERR_CMD_OPT, "option unimplemented"); + if (apply_config(nexus, optarg, err)) + return ERROR_CODE(err); + + break; case '?': usage(argv[0]);