aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2013-03-13 08:44:30 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2013-03-13 08:52:46 +0200
commit7fede76c95d658dc745e2fcce51e4d7f9091f0ba (patch)
treeba36dafbe5d506f38fb02cbb479e601ff65cd845
parent78df8f9042140b2c0ecf9d81822d1545841df746 (diff)
downloadwydawca-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.ac1
m---------grecs0
-rw-r--r--include/wydawca/wydawca.h2
-rw-r--r--modules/Makefile.am2
-rw-r--r--modules/logstat/Makefile.am12
-rw-r--r--modules/logstat/mod_logstat.c74
-rw-r--r--src/config.c57
-rw-r--r--src/module.c40
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);

Return to:

Send suggestions and report system problems to the System administrator.