aboutsummaryrefslogtreecommitdiff
path: root/src/module.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2013-03-10 22:39:23 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2013-03-10 22:39:23 +0200
commit87602f5492b842f734dffe22f4e2f85dbc6ce713 (patch)
tree3e7e04bca15e8af5c981a78619e2d95f03b45c67 /src/module.c
parent826bb71c57d903f760c89406f93d19fe0c131de0 (diff)
downloadwydawca-87602f5492b842f734dffe22f4e2f85dbc6ce713.tar.gz
wydawca-87602f5492b842f734dffe22f4e2f85dbc6ce713.tar.bz2
Replace mail notification with module event notification framework.
The new framework is to be general-purpose; the mail notification is implemented as a module. Althoug the program is operational, the change is not completed yet. In particular, the docs are out of date and the tests will mostly fail. * .gitignore: Update. * Makefile.am (SUBDIRS): Add modules. * configure.ac: Mailutils is now optional (though highly recommended). (AC_CONFIG_FILES): Build modules/Makefile and modules/mailutils/Makefile. * modules/Makefile.am: New file. * modules/mailutils/Makefile.am: New file. * modules/mailutils/mod_mailutils.c: New file. * src/mail.c: Remove. * src/mail.h: Remove. * src/event.c: New file. * src/Makefile.am (wydawca_SOURCES): Update. (LDADD): Remove MAILUTILS_LIBS. * src/config.c: Remove mail-related configuration statements. Add module-related ones instead. * src/wydawca.h (notification_event) <ev_statistics>: New event. (notification_target): Remove. (notification) <tgt,sign_keys,msg>: Remove. <statmask>: New member. (register_message_template): Remove. (notify_stats,notify_flush): New protos. (notification_target_str): Remove. (format_fn): Remove. (module) <next,modinit,open> <flush,close>: New members. <notify>: Change signature. (modules_close, module_set_init) (module_flush): New protos. (debug_level): Rename to wy_debug_level. All uses changed. (wy_version): New extern. (admin_stat_message,admin_stat_sign_key): Remove. (default_notification): New global. (triplet_expand_param,triplet_expand_dictionary_query): The file_triplet argument is const pointer. (assert_string_arg): Rename to wy_assert_string_arg. * src/wydawca.c (debug_level): Rename to wy_debug_level. (wy_version): New global. (logstats): Call notify_stats. (main): Call modules_close. * src/module.c: Keep modules in a singly-linked list instead of a symtab. Provide new functions. * src/net.c: Update. * src/dictionary.c: Update. * src/directive.c: Update. * src/diskio.c: Update. * src/exec.c: Update. * src/gpg.c: Update. * src/job.c (wydawca_scanner): Call notify_flush. * src/null.c: Update. * src/process.c: Update. * src/sql.c: Update. * src/tcpwrap.c: Update. * src/triplet.c: Update. * src/verify.c: Update. * src/watcher.c: Update.
Diffstat (limited to 'src/module.c')
-rw-r--r--src/module.c141
1 files changed, 82 insertions, 59 deletions
diff --git a/src/module.c b/src/module.c
index 41bbb39..f9aba39 100644
--- a/src/module.c
+++ b/src/module.c
@@ -17,67 +17,49 @@
#include "wydawca.h"
#include <ltdl.h>
-static struct grecs_symtab *modtab;
+static struct module *mod_head, *mod_tail;
struct grecs_list *module_load_path, *module_prepend_load_path;
-static void
-modfree(void *p)
+static struct module *
+modlookup(const char *name)
{
- struct module *mod = p;
- free(mod->locus.beg.file);
- free(mod->locus.end.file);
- free(mod->path);
- free(mod->name);
- free(mod);
+ struct module *p;
+
+ for (p = mod_head; p; p = p->next)
+ if (strcmp(p->name, name) == 0)
+ return p;;
+ return NULL;
}
static struct module *
modinstall(const char *name, const char *path, grecs_locus_t *loc)
{
- struct module key;
- struct module *ent;
- int install = 1;
-
- if (!modtab) {
- modtab = grecs_symtab_create(sizeof(struct module),
- NULL,
- NULL,
- NULL,
- NULL,
- modfree);
- if (!modtab)
- grecs_alloc_die();
- }
-
- key.name = (char*) name;
- ent = grecs_symtab_lookup_or_install(modtab, &key, &install);
- if (!ent)
- grecs_alloc_die();
- if (install == 0) {
+ struct module *p;
+
+ p = modlookup(name);
+ if (p) {
grecs_error(loc, 0, _("module %s already declared"), name);
- grecs_error(&ent->locus, 0, _("previously declared here"));
+ grecs_error(&p->locus, 0, _("previously declared here"));
return NULL;
}
- ent->path = grecs_strdup(path);
- ent->locus.beg.file = grecs_strdup(loc->beg.file);
- ent->locus.beg.line = loc->beg.line;
- ent->locus.beg.col = loc->beg.col;
- ent->locus.end.file = grecs_strdup(loc->end.file);
- ent->locus.end.line = loc->end.line;
- ent->locus.end.col = loc->end.col;
- return ent;
-}
-static struct module *
-modlookup(const char *name)
-{
- struct module key;
+ p = grecs_zalloc(sizeof(*p));
+ p->name = grecs_strdup(name);
+ p->path = grecs_strdup(path);
+ p->locus.beg.file = grecs_strdup(loc->beg.file);
+ p->locus.beg.line = loc->beg.line;
+ p->locus.beg.col = loc->beg.col;
+ p->locus.end.file = grecs_strdup(loc->end.file);
+ p->locus.end.line = loc->end.line;
+ p->locus.end.col = loc->end.col;
- if (!modtab)
- return NULL;
-
- key.name = (char*) name;
- return grecs_symtab_lookup_or_install(modtab, &key, NULL);
+ if (mod_tail)
+ mod_tail->next = p;
+ else
+ mod_head = p;
+ mod_tail = p;
+
+ return p;
}
int
@@ -117,11 +99,9 @@ resolve_sym(struct module *mod, const char *name)
}
static int
-modload(void *sym, void *data)
+modload(struct module *mod, lt_dladvise advise)
{
- struct module *mod = sym;
lt_dlhandle handle = NULL;
- lt_dladvise advise = data;
if (mod->handle) {
grecs_error(&mod->locus, 0, _("already loaded"));
@@ -137,9 +117,22 @@ modload(void *sym, void *data)
return 1;
}
mod->handle = handle;
+ mod->open = resolve_sym(mod, "open");
+ mod->close = resolve_sym(mod, "close");
+
mod->config = resolve_sym(mod, "config");
mod->notify = resolve_sym(mod, "notify");
-
+ mod->flush = resolve_sym(mod, "flush");
+
+ if (mod->open) {
+ if (mod->open(mod->modinit)) {
+ grecs_error(mod->modinit ? &mod->modinit->locus : NULL,
+ 0,
+ _("failed to initialize module %s"),
+ mod->name);
+ return 1;
+ }
+ }
return 0;
}
@@ -176,6 +169,7 @@ modules_load()
{
lt_dladvise advise = NULL;
struct grecs_list_entry *ep;
+ struct module *mod;
if (lt_dlinit()) {
logmsg(LOG_ERR, _("failed to initialize libtool"));
@@ -201,9 +195,10 @@ modules_load()
logmsg(LOG_ERR, "lt_dladvise_global: %s",
lt_dlerror());
}
- if (grecs_symtab_enumerate(modtab, modload, NULL)) {
- logmsg(LOG_CRIT, _("some modules failed to load, exiting"));
- exit(EX_UNAVAILABLE);
+
+ for (mod = mod_head; mod; mod = mod->next) {
+ if (modload(mod, advise))
+ exit(EX_UNAVAILABLE);
}
lt_dladvise_destroy(&advise);
@@ -214,12 +209,28 @@ modules_load()
}
}
-static char *
-getfn(void *trp, const char *fmt)
+void
+modules_close()
{
- return triplet_expand_param(fmt, trp);
+ struct module *mod;
+
+ for (mod = mod_head; mod; mod = mod->next) {
+ if (mod->close)
+ mod->close();
+ lt_dlclose(mod->handle);
+ }
}
+int
+module_set_init(const char *name, grecs_node_t *node)
+{
+ struct module *mod = modlookup(name);
+ if (!mod)
+ return 1;
+ mod->modinit = node;
+ return 0;
+}
+
void
module_notify(const char *name, void *modcfg,
enum notification_event ev, struct file_triplet *trp)
@@ -231,6 +242,18 @@ module_notify(const char *name, void *modcfg,
return;
}
if (mod->notify)
- mod->notify(modcfg, ev, getfn, trp);
+ mod->notify(modcfg, ev, trp);
}
+void
+module_flush(const char *name, void *modcfg)
+{
+ struct module *mod = modlookup(name);
+
+ if (!mod) {
+ logmsg(LOG_ERR, "no such module: %s", name);
+ return;
+ }
+ if (mod->flush)
+ mod->flush(modcfg);
+}

Return to:

Send suggestions and report system problems to the System administrator.