diff options
-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 | 55 | ||||
-rw-r--r-- | src/module.c | 40 |
8 files changed, 158 insertions, 28 deletions
diff --git a/configure.ac b/configure.ac index afe0bb5..6e8e6f4 100644 --- a/configure.ac +++ b/configure.ac @@ -174,6 +174,7 @@ AC_CONFIG_FILES([Makefile include/wydawca/Makefile src/Makefile modules/Makefile + modules/logstat/Makefile modules/mailutils/Makefile etc/Makefile]) 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 @@ -17,7 +17,7 @@ #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) 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 @@ -1004,7 +1004,7 @@ static struct grecs_keyword spool_kw[] = { 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"), @@ -1197,6 +1197,48 @@ cb_locking(enum grecs_callback_command cmd, grecs_node_t *node, } 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) { @@ -1240,19 +1282,16 @@ static struct grecs_keyword wydawca_kw[] = { { "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 }, diff --git a/src/module.c b/src/module.c index c009971..33946ee 100644 --- a/src/module.c +++ b/src/module.c @@ -87,10 +87,10 @@ cb_module(enum grecs_callback_command cmd, grecs_node_t *node, }; 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); @@ -117,12 +117,12 @@ modload(struct module *mod, lt_dladvise advise) 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)) { @@ -137,25 +137,22 @@ modload(struct module *mod, lt_dladvise advise) } 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; } } @@ -164,6 +161,12 @@ spoolmodcfg(struct spool *spool, void *unused) return 0; } +static int +spoolmodcfg(struct spool *spool, void *unused) +{ + return conf_notification_modules(spool->notification); +} + void modules_load() { @@ -207,6 +210,7 @@ modules_load() _("some modules failed to configure, exiting")); exit(EX_UNAVAILABLE); } + conf_notification_modules(default_notification); } void @@ -290,7 +294,7 @@ module_help(const char *modname) 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 |