diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-03-10 22:39:23 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-03-10 22:39:23 +0200 |
commit | 87602f5492b842f734dffe22f4e2f85dbc6ce713 (patch) | |
tree | 3e7e04bca15e8af5c981a78619e2d95f03b45c67 /src/module.c | |
parent | 826bb71c57d903f760c89406f93d19fe0c131de0 (diff) | |
download | wydawca-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.c | 141 |
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); +} |