diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-03-13 08:44:30 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-03-13 08:52:46 +0200 |
commit | 7fede76c95d658dc745e2fcce51e4d7f9091f0ba (patch) | |
tree | ba36dafbe5d506f38fb02cbb479e601ff65cd845 | |
parent | 78df8f9042140b2c0ecf9d81822d1545841df746 (diff) | |
download | wydawca-7fede76c95d658dc745e2fcce51e4d7f9091f0ba.tar.gz wydawca-7fede76c95d658dc745e2fcce51e4d7f9091f0ba.tar.bz2 |
Bugfixes. Add a stub for new module.
* include/wydawca/wydawca.h (WY_EXPORT): Add an internal
prefix. That's a stupid lossage: having not found the
composed name (modname_LTX_sym), libtool tries to look up
sym itself, which makes it impossible to use names like
"open", etc.
* src/module.c (resolve_sym): Reflect the above. Take an
extra argument specifying whether the symbol is mandatory.
(modules_load): Configure modules used in default_notification
list.
* src/config (cb_load_path): New callback to ensure that
multiple module-path* statements accumulate.
* modules/logstat/mod_logstat.c: New file.
* modules/logstat/Makefile: New file.
* configure.ac: Build modules/logstat/Makefile.
* modules/Makefile.am (SUBDIRS): Add logstat.
-rw-r--r-- | configure.ac | 1 | ||||
m--------- | grecs | 0 | ||||
-rw-r--r-- | include/wydawca/wydawca.h | 2 | ||||
-rw-r--r-- | modules/Makefile.am | 2 | ||||
-rw-r--r-- | modules/logstat/Makefile.am | 12 | ||||
-rw-r--r-- | modules/logstat/mod_logstat.c | 74 | ||||
-rw-r--r-- | src/config.c | 57 | ||||
-rw-r--r-- | src/module.c | 40 |
8 files changed, 159 insertions, 29 deletions
diff --git a/configure.ac b/configure.ac index afe0bb5..6e8e6f4 100644 --- a/configure.ac +++ b/configure.ac @@ -171,10 +171,11 @@ fi AC_CONFIG_FILES([Makefile doc/Makefile include/Makefile include/wydawca/Makefile src/Makefile modules/Makefile + modules/logstat/Makefile modules/mailutils/Makefile etc/Makefile]) AC_OUTPUT diff --git a/grecs b/grecs -Subproject 588bb9898edcc8b531980fcb180e4955d29ed40 +Subproject 487e2cfa988d6c3a5232011ab83897ef23bdb88 diff --git a/include/wydawca/wydawca.h b/include/wydawca/wydawca.h index 9b5c7df..3bda88c 100644 --- a/include/wydawca/wydawca.h +++ b/include/wydawca/wydawca.h @@ -14,13 +14,13 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ #define wy_s_cat2(a,b) a ## b #define wy_s_cat3(a,b,c) a ## b ## c -#define WY_EXPORT(module,name) wy_s_cat3(module,_LTX_,name) +#define WY_EXPORT(module,name) wy_s_cat3(module,_LTX_wy_,name) #define wy_notify WY_EXPORT(WY_MODULE,notify) #define wy_help WY_EXPORT(WY_MODULE,help) #define wy_open WY_EXPORT(WY_MODULE,open) #define wy_config WY_EXPORT(WY_MODULE,config) #define wy_flush WY_EXPORT(WY_MODULE,flush) diff --git a/modules/Makefile.am b/modules/Makefile.am index d430de8..537248e 100644 --- a/modules/Makefile.am +++ b/modules/Makefile.am @@ -1,4 +1,4 @@ if COND_MAILUTILS MAILUTILS = mailutils endif -SUBDIRS = $(MAILUTILS)
\ No newline at end of file +SUBDIRS = logstat $(MAILUTILS)
\ No newline at end of file diff --git a/modules/logstat/Makefile.am b/modules/logstat/Makefile.am new file mode 100644 index 0000000..2f7d752 --- /dev/null +++ b/modules/logstat/Makefile.am @@ -0,0 +1,12 @@ +moddir=@WYDAWCA_MODDIR@ + +mod_LTLIBRARIES=mod_logstat.la + +mod_logstat_la_SOURCES = mod_logstat.c + +AM_LDFLAGS = -module -avoid-version -no-undefined +AM_CPPFLAGS = \ + -I$(top_srcdir)\ + -I$(top_srcdir)/include\ + -I$(top_builddir)/src\ + @GRECS_INCLUDES@ diff --git a/modules/logstat/mod_logstat.c b/modules/logstat/mod_logstat.c new file mode 100644 index 0000000..874b05f --- /dev/null +++ b/modules/logstat/mod_logstat.c @@ -0,0 +1,74 @@ +#include <config.h> +#include <stdlib.h> +#include <syslog.h> +#include <grecs.h> +#include <wydawca/wydawca.h> +#include <wydawca/cfg.h> + +#define WY_MODULE mod_logstat + +static int stat_mask; +static struct grecs_list *log_msg; + +static struct grecs_keyword logstat_kw[] = { + { "statistics", N_("items"), + N_("Log these statistics items"), + grecs_type_string, GRECS_DFLT, &stat_mask, 0, + wy_cb_statistics }, + { "message", N_("text"), + N_("Log additional message"), + grecs_type_string, GRECS_LIST|GRECS_AGGR, &log_msg, 0, NULL }, + { NULL } +}; + + +void * +wy_config(grecs_node_t *node) +{ + grecs_tree_reduce(node, logstat_kw, 0); + if (grecs_tree_process(node->down, logstat_kw)) + return NULL; + return &stat_mask; +} + +void +wy_notify(void *data, int ev, wy_triplet_t trp) +{ + struct grecs_list_entry *ep; + char *text; + + if (ev != wy_ev_statistics) + return; + + if (log_msg) { + for (ep = log_msg->head; ep; ep = ep->next) { + text = wy_expand_stats(ep->data); + wy_log(LOG_INFO, "%s", text); + free(text); + } + } +} + +void +wy_help(void) +{ + static struct grecs_keyword top[] = { + { "module-config", NULL, + "module configuration", + grecs_type_section, GRECS_INAC, NULL, 0, NULL, NULL, + logstat_kw }, + { NULL } + }; + + printf("\n\n# Usage in notify-event statement:\n"); + printf("notify-event {\n event statistics;\n module logstat;"); + grecs_print_statement_array(top, 1, 1, stdout); + printf("}\n"); +} + +wd() +{ + volatile int _st=0; + while (!_st) + _st=_st; +} diff --git a/src/config.c b/src/config.c index eef4ee1..f5860d4 100644 --- a/src/config.c +++ b/src/config.c @@ -1001,13 +1001,13 @@ static struct grecs_keyword spool_kw[] = { cb_dictionary, NULL, dictionary_kw }, { "archive", N_("type: string"), N_("Set up archivation"), grecs_type_section, GRECS_DFLT, NULL, offsetof(struct spool, archive), cb_archive, NULL, archive_kw }, { "notify-event", NULL, N_("Configure notification"), - grecs_type_section, GRECS_DFLT, + grecs_type_section, GRECS_MULT, NULL, offsetof(struct spool, notification), cb_notify_event, NULL, notify_event_kw }, { "check-script", NULL, N_("A /bin/sh script to verify the tarball"), grecs_type_string, GRECS_DFLT, NULL, offsetof(struct spool, check_script) }, { NULL } @@ -1194,12 +1194,54 @@ cb_locking(enum grecs_callback_command cmd, grecs_node_t *node, value->v.string, locus); } return 0; } static int +cb_load_path(enum grecs_callback_command cmd, grecs_node_t *node, + void *varptr, void *cb_data) +{ + struct grecs_list **lpp = varptr, *lp; + grecs_locus_t *locus = &node->locus; + grecs_value_t *value = node->v.value; + + if (*lpp) + lp = *lpp; + else { + lp = _grecs_simple_list_create(1); + *lpp = lp; + } + switch (value->type) { + case GRECS_TYPE_STRING: + grecs_list_append(lp, grecs_strdup(value->v.string)); + break; + + case GRECS_TYPE_LIST: { + struct grecs_list_entry *ep; + + for (ep = value->v.list->head; ep; ep = ep->next) { + const grecs_value_t *vp = ep->data; + + if (vp->type != GRECS_TYPE_STRING) { + grecs_error(&vp->locus, 0, + _("list element must be a string")); + return 1; + } + grecs_list_append(lp, grecs_strdup(vp->v.string)); + } + break; + } + + case GRECS_TYPE_ARRAY: + grecs_error(locus, 0, _("too many arguments")); + return 1; + } + return 0; +} + +static int cb_upload_version(enum grecs_callback_command cmd, grecs_node_t *node, void *varptr, void *cb_data) { unsigned *pversion = varptr, n; grecs_locus_t *locus = &node->locus; grecs_value_t *value = node->v.value; @@ -1237,25 +1279,22 @@ static struct grecs_keyword wydawca_kw[] = { { "pidfile", N_("file"), N_("Set pid file name"), grecs_type_string, GRECS_DFLT, &pidfile }, { "module-prepend-load-path", N_("path"), N_("List of directories searched for modules prior to " "the default module directory"), - grecs_type_string, GRECS_LIST, - &module_prepend_load_path }, + grecs_type_string, GRECS_LIST|GRECS_AGGR, + &module_prepend_load_path, 0, cb_load_path }, { "module-load-path", N_("path"), N_("List of directories searched for database modules."), - grecs_type_string, GRECS_LIST, - &module_load_path }, + grecs_type_string, GRECS_LIST|GRECS_AGGR, + &module_load_path, 0, cb_load_path }, { "module", N_("name: string> <path: string"), N_("Load the specified module"), grecs_type_string, GRECS_MULT, NULL, 0, cb_module }, - { "module", N_("name: string> <path: string"), - N_("Load the specified module"), - grecs_type_string, GRECS_MULT, NULL, 0, cb_module }, { "module-init", N_("modname"), N_("Module-specific initialization data"), grecs_type_section, GRECS_INAC, NULL, 0, NULL, NULL, NULL }, { "inotify", NULL, N_("Enable or disable inotify support"), grecs_type_bool, GRECS_DFLT, &inotify_enable }, @@ -1369,13 +1408,13 @@ config_init() } void config_finish(struct grecs_node *tree) { struct grecs_node *p; - + if (grecs_tree_process(tree, wydawca_kw)) exit(EX_CONFIG); for (p = tree->down; p; p = p->next) { if (strcmp(p->ident, "module-init") == 0) { if (wy_assert_string_arg(&p->v.value->locus, grecs_callback_set_value, diff --git a/src/module.c b/src/module.c index c009971..33946ee 100644 --- a/src/module.c +++ b/src/module.c @@ -84,16 +84,16 @@ cb_module(enum grecs_callback_command cmd, grecs_node_t *node, modinstall(name->v.string, path->v.string, locus); return 0; }; static void * -resolve_sym(struct module *mod, const char *name) +resolve_sym(struct module *mod, const char *name, int mustbe) { void *sym = lt_dlsym(mod->handle, name); - if (!sym) { + if (!sym && mustbe) { grecs_error(&mod->locus, 0, _("module \"%s\" does not define symbol \"%s\""), mod->name, name); } return sym; } @@ -114,18 +114,18 @@ modload(struct module *mod, lt_dladvise advise) grecs_error(&mod->locus, 0, _("cannot load module %s: %s"), mod->path, lt_dlerror()); return 1; } mod->handle = handle; - mod->open = resolve_sym(mod, "open"); - mod->close = resolve_sym(mod, "close"); + mod->open = resolve_sym(mod, "wy_open", 0); + mod->close = resolve_sym(mod, "wy_close", 0); - mod->config = resolve_sym(mod, "config"); - mod->notify = resolve_sym(mod, "notify"); - mod->flush = resolve_sym(mod, "flush"); + mod->config = resolve_sym(mod, "wy_config", 1); + mod->notify = resolve_sym(mod, "wy_notify", 1); + mod->flush = resolve_sym(mod, "wy_flush", 0); if (mod->open) { if (mod->open(mod->modinit)) { grecs_error(mod->modinit ? &mod->modinit->locus : NULL, 0, _("failed to initialize module %s"), @@ -134,39 +134,42 @@ modload(struct module *mod, lt_dladvise advise) } } return 0; } static int -spoolmodcfg(struct spool *spool, void *unused) +conf_notification_modules(struct notification *np) { - struct notification *np; - - for (np = spool->notification; np; np = np->next) { + for (; np; np = np->next) { if (np->modname) { struct module *mod = modlookup(np->modname); if (!mod) { - wy_log(LOG_ERR, "spool %s: no such module: %s", - spool->tag, np->modname); + wy_log(LOG_ERR, "%s: no such module", + np->modname); return 1; } - if (mod->config) { + if (!np->modcfg && mod->config) { np->modcfg = mod->config(np->modnode); if (!np->modcfg) { wy_log(LOG_ERR, - "spool %s: failed to configure " - "module \"%s\"", - spool->tag, np->modname); + "%s: failed to configure", + np->modname); return 1; } } } } return 0; } +static int +spoolmodcfg(struct spool *spool, void *unused) +{ + return conf_notification_modules(spool->notification); +} + void modules_load() { lt_dladvise advise = NULL; struct grecs_list_entry *ep; struct module *mod; @@ -204,12 +207,13 @@ modules_load() if (for_each_spool(spoolmodcfg, NULL)) { wy_log(LOG_CRIT, _("some modules failed to configure, exiting")); exit(EX_UNAVAILABLE); } + conf_notification_modules(default_notification); } void modules_close() { struct module *mod; @@ -287,13 +291,13 @@ module_help(const char *modname) if (modload(&mod, advise)) exit(EX_UNAVAILABLE); lt_dladvise_destroy(&advise); - help = resolve_sym(&mod, "help"); + help = resolve_sym(&mod, "wy_help", 0); if (!help) wy_log(LOG_NOTICE, "no help for %s", modname); else help(); lt_dlclose(mod.handle); |