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/config.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/config.c')
-rw-r--r-- | src/config.c | 271 |
1 files changed, 50 insertions, 221 deletions
diff --git a/src/config.c b/src/config.c index 05d76de..4da18c5 100644 --- a/src/config.c +++ b/src/config.c @@ -16,7 +16,7 @@ #include "wydawca.h" #include "sql.h" -#include <mail.h> + struct keyword { char *name; @@ -118,7 +118,7 @@ static struct archive_descr default_archive_descr = { }; static struct dictionary *default_dictionary[dictionary_count]; -static struct notification *default_notification = NULL; +struct notification *default_notification = NULL; /* safe_file_name: convert a file name possibly containig relative specs (../) into a safer form using only direct descendence. @@ -210,6 +210,7 @@ static struct keyword event_tab[] = { { "bad-directive-signature", ev_bad_directive_signature }, { "bad-detached-signature", ev_bad_detached_signature }, { "check-failure", ev_check_fail }, + { "statistics", ev_statistics }, {NULL} }; @@ -241,47 +242,11 @@ string_to_notification_event(grecs_locus_t *locus, const char *val, return 0; } -static struct keyword target_tab[] = { - { "read", notify_read }, /* Read recipients from the message - headers */ - { "message", notify_read }, - { "admin", notify_admin }, /* System administrator */ - { "owner", notify_owner }, /* Project admin */ - { "user", notify_user }, /* User (uploader) */ - { NULL } -}; - -const char * -notification_target_str(enum notification_target tgt) -{ - const char *ret; - if (tok_to_keyword(tgt, target_tab, &ret)) { - grecs_error(NULL, 0, - _("INTERNAL ERROR: " - "unknown notification target number: %d"), - tgt); - return NULL; - } - return ret; -} - -int -string_to_notification_target(grecs_locus_t *locus, const char *val, - enum notification_target *pret) -{ - int res; - if (keyword_to_tok(val, target_tab, &res)) { - grecs_error(locus, 0, - _("unknown notification target: %s"), val); - return 1; - } - *pret = res; - return 0; -} int -assert_string_arg(grecs_locus_t *locus, - enum grecs_callback_command cmd, const grecs_value_t *value) +wy_assert_string_arg(grecs_locus_t *locus, + enum grecs_callback_command cmd, + const grecs_value_t *value) { if (cmd != grecs_callback_set_value) { grecs_error(locus, 0, _("Unexpected block statement")); @@ -312,77 +277,6 @@ get_arg(grecs_value_t *value, unsigned n, int type) } static int -cb_mailer(enum grecs_callback_command cmd, grecs_node_t *node, - void *varptr, void *cb_data) -{ - int rc; - grecs_locus_t *locus = &node->locus; - grecs_value_t *value = node->v.value; - - if (assert_string_arg(locus, cmd, value)) - return 1; - rc = mu_mailer_create(&mailer, value->v.string); - if (rc) - grecs_error(&value->locus, 0, - _("cannot create mailer `%s': %s"), - value->v.string, - mu_strerror(rc)); - return rc; -} - -static int -cb_email_address(enum grecs_callback_command cmd, grecs_node_t *node, - void *varptr, void *cb_data) -{ - int rc = 1; - mu_address_t addr = NULL; - grecs_locus_t *locus = &node->locus; - grecs_value_t *value = node->v.value; - struct grecs_list_entry *ep; - - switch (value->type) { - case GRECS_TYPE_STRING: - rc = mu_address_create(&addr, value->v.string); - if (rc) { - grecs_error(&value->locus, 0, - _("%s: invalid email address: %s"), - value->v.string, mu_strerror(rc)); - return rc; - } - break; - - case GRECS_TYPE_LIST: - for (ep = value->v.list->head; ep; ep = ep->next) { - const grecs_value_t *vp = ep->data; - mu_address_t a; - if (assert_string_arg(locus, cmd, vp)) - return 1; - - rc = mu_address_create(&a, vp->v.string); - if (rc == 0) - rc = mu_address_union(&addr, a); - else { - grecs_error(&value->locus, 0, - _("%s: invalid email address: %s"), - vp->v.string, - mu_strerror(rc)); - } - mu_address_destroy(&a); - if (rc) - break; - } - break; - - case GRECS_TYPE_ARRAY: - grecs_error(locus, 0, _("too many arguments")); - return 1; - } - - *(mu_address_t *) varptr = addr; - return rc; -} - -static int cb_interval(enum grecs_callback_command cmd, grecs_node_t *node, void *varptr, void *cb_data) { @@ -393,7 +287,7 @@ cb_interval(enum grecs_callback_command cmd, grecs_node_t *node, grecs_value_t *value = node->v.value; /* FIXME 1: Support arrays */ - if (assert_string_arg(locus, cmd, value)) + if (wy_assert_string_arg(locus, cmd, value)) return 1; /* FIXME 2: Support ISO intervals? */ @@ -417,7 +311,7 @@ cb_absolute_name(enum grecs_callback_command cmd, grecs_value_t *value = node->v.value; /* FIXME 1: Support arrays */ - if (assert_string_arg(locus, cmd, value)) + if (wy_assert_string_arg(locus, cmd, value)) return 1; word = safe_file_name((char *)value->v.string); @@ -439,7 +333,7 @@ cb_set_umask(enum grecs_callback_command cmd, grecs_locus_t *locus = &node->locus; grecs_value_t *value = node->v.value; - if (assert_string_arg(locus, cmd, value)) + if (wy_assert_string_arg(locus, cmd, value)) return 1; m = strtoul(value->v.string, &p, 8) & 0777; if (*p) @@ -546,12 +440,6 @@ parse_statmask(grecs_locus_t *loc, grecs_value_t *val, unsigned long *pmask) return err; } -static int -cb_statistics(enum grecs_callback_command cmd, grecs_node_t *node, - void *varptr, void *cb_data) -{ - return parse_statmask(&node->locus, node->v.value, varptr); -} static int cb_sql_host(enum grecs_callback_command cmd, grecs_node_t *node, @@ -562,7 +450,7 @@ cb_sql_host(enum grecs_callback_command cmd, grecs_node_t *node, grecs_locus_t *locus = &node->locus; grecs_value_t *value = node->v.value; - if (assert_string_arg(locus, cmd, value)) + if (wy_assert_string_arg(locus, cmd, value)) return 1; p = strchr(value->v.string, ':'); @@ -667,7 +555,7 @@ cb_syslog_facility(enum grecs_callback_command cmd, grecs_node_t *node, grecs_value_t *value = node->v.value; int fac; - if (assert_string_arg(locus, cmd, value)) + if (wy_assert_string_arg(locus, cmd, value)) return 1; fac = wy_strtofac(value->v.string); @@ -680,40 +568,6 @@ cb_syslog_facility(enum grecs_callback_command cmd, grecs_node_t *node, return 0; } -static int -cb_define_message(enum grecs_callback_command cmd, grecs_node_t *node, - void *varptr, void *cb_data) -{ - const char *ident; - grecs_locus_t *locus = &node->locus; - grecs_value_t *value = node->v.value; - - if (cmd != grecs_callback_set_value) { - grecs_error(locus, 0, _("Unexpected block statement")); - return 1; - } - if (!value || value->type != GRECS_TYPE_ARRAY || value->v.arg.c != 2) { - grecs_error(locus, 0, _("expected two arguments")); - return 1; - } - - if (value->v.arg.v[0]->type != GRECS_TYPE_STRING) { - grecs_error(&value->v.arg.v[0]->locus, 0, - _("first argument not a string")); - return 1; - } - ident = value->v.arg.v[0]->v.string; - - if (value->v.arg.v[1]->type != GRECS_TYPE_STRING) { - grecs_error(&value->v.arg.v[1]->locus, 0, - _("second argument not a string")); - return 1; - } - - register_message_template(ident, value->v.arg.v[1]->v.string); - return 0; -} - static struct grecs_keyword syslog_kw[] = { { "facility", N_("name"), @@ -772,7 +626,7 @@ cb_backup(enum grecs_callback_command cmd, grecs_node_t *node, grecs_locus_t *locus = &node->locus; grecs_value_t *value = node->v.value; - if (assert_string_arg(locus, cmd, value)) + if (wy_assert_string_arg(locus, cmd, value)) return 1; *ptype = get_backup_version(&value->locus, NULL, value->v.string); return 0; @@ -852,19 +706,6 @@ cb_archive(enum grecs_callback_command cmd, grecs_node_t *node, return 0; } -static struct grecs_keyword mail_statistics_kw[] = { - { "message", N_("text"), - N_("Message text"), - grecs_type_string, GRECS_DFLT, &admin_stat_message }, - { "statistics", N_("items"), - N_("Send mail if one or more of these items are set"), - grecs_type_string, GRECS_DFLT, &mail_admin_mask, 0, cb_statistics }, - { "gpg-sign", - N_("key"), N_("Sign message with this key"), - grecs_type_string, GRECS_DFLT, &admin_stat_sign_key }, - { NULL } -}; - static int cb_event(enum grecs_callback_command cmd, grecs_node_t *node, void *varptr, void *cb_data) @@ -873,24 +714,17 @@ cb_event(enum grecs_callback_command cmd, grecs_node_t *node, grecs_locus_t *locus = &node->locus; grecs_value_t *value = node->v.value; - if (assert_string_arg(locus, cmd, value)) + if (wy_assert_string_arg(locus, cmd, value)) return 1; string_to_notification_event(&value->locus, value->v.string, pev); return 0; } static int -cb_recipient(enum grecs_callback_command cmd, grecs_node_t *node, - void *varptr, void *cb_data) +cb_statistics(enum grecs_callback_command cmd, grecs_node_t *node, + void *varptr, void *cb_data) { - enum notification_target *tgt = varptr; - grecs_locus_t *locus = &node->locus; - grecs_value_t *value = node->v.value; - - if (assert_string_arg(locus, cmd, value)) - return 1; - string_to_notification_target(&value->locus, value->v.string, tgt); - return 0; + return parse_statmask(&node->locus, node->v.value, varptr); } static struct grecs_keyword notify_event_kw[] = { @@ -898,19 +732,6 @@ static struct grecs_keyword notify_event_kw[] = { N_("Event on which to notify"), grecs_type_string, GRECS_DFLT, NULL, offsetof(struct notification, ev), cb_event }, - { "recipient", N_("who"), N_("Notify this recipient"), - grecs_type_string, GRECS_DFLT, - NULL, offsetof(struct notification, tgt), - cb_recipient }, - { "message", N_("text-or-id"), - N_("Text of the notification or identifier of a defined " - "message template"), - grecs_type_string, GRECS_DFLT, - NULL, offsetof(struct notification, msg) }, - { "gpg-sign", N_("key"), - N_("Sign message with this key"), - grecs_type_string, GRECS_DFLT, - NULL, offsetof(struct notification, sign_keys) }, { "module", N_("name"), N_("Name of the module to invoke on event"), grecs_type_string, GRECS_DFLT, @@ -918,6 +739,11 @@ static struct grecs_keyword notify_event_kw[] = { { "module-config", NULL, N_("Module-specific configuration data"), grecs_type_section, GRECS_INAC, NULL, 0, NULL, NULL, NULL }, + { "statistics", N_("items"), + N_("Send mail if one or more of these items are set"), + grecs_type_string, GRECS_DFLT, + NULL, offsetof(struct notification, statmask), cb_statistics }, + { NULL } }; @@ -938,9 +764,11 @@ cb_notify_event(enum grecs_callback_command cmd, grecs_node_t *node, case grecs_callback_section_end: ntf = *pdata; - if (!ntf->msg && !ntf->modname) - grecs_error(locus, 0, _("missing message definition")); + if (!ntf->modname) + grecs_error(locus, 0, _("missing module name")); else { + /* FIXME: Check if the module is defined. Better yer, + delay this check until config_finish */ struct notification **p = (struct notification **)varptr; ntf->next = *p; @@ -976,7 +804,7 @@ cb_dictionary_type(enum grecs_callback_command cmd, grecs_node_t *node, grecs_locus_t *locus = &node->locus; grecs_value_t *value = node->v.value; - if (assert_string_arg(locus, cmd, value)) + if (wy_assert_string_arg(locus, cmd, value)) return 1; *ptype = string_to_dictionary_type(value->v.string); if (*ptype == dictionary_none) @@ -1018,7 +846,7 @@ cb_dictionary_params(enum grecs_callback_command cmd, grecs_node_t *node, for (i = 0, ep = value->v.list->head; ep; ep = ep->next, i++) { const grecs_value_t *vp = ep->data; - if (assert_string_arg(locus, cmd, vp)) + if (wy_assert_string_arg(locus, cmd, vp)) break; meth->parmv[i] = grecs_strdup(vp->v.string); @@ -1126,7 +954,7 @@ cb_url(enum grecs_callback_command cmd, grecs_node_t *node, grecs_locus_t *locus = &node->locus; grecs_value_t *value = node->v.value; - if (assert_string_arg(locus, cmd, value)) + if (wy_assert_string_arg(locus, cmd, value)) return 1; url = wy_url_create(value->v.string); if (!url) { @@ -1268,7 +1096,7 @@ cb_user(enum grecs_callback_command cmd, grecs_node_t *node, grecs_locus_t *locus = &node->locus; grecs_value_t *value = node->v.value; - if (assert_string_arg(locus, cmd, value)) + if (wy_assert_string_arg(locus, cmd, value)) return 1; pw = getpwnam(value->v.string); @@ -1315,7 +1143,7 @@ cb_supp_groups(enum grecs_callback_command cmd, grecs_node_t *node, const grecs_value_t *vp = ep->data; struct group *grp; - if (assert_string_arg(locus, cmd, vp)) + if (wy_assert_string_arg(locus, cmd, vp)) break; grp = getgrnam(vp->v.string); if (!grp) { @@ -1369,7 +1197,7 @@ cb_upload_version(enum grecs_callback_command cmd, grecs_node_t *node, grecs_locus_t *locus = &node->locus; grecs_value_t *value = node->v.value; - if (assert_string_arg(locus, cmd, value)) + if (wy_assert_string_arg(locus, cmd, value)) return 1; if (directive_pack_version(value->v.string, &n)) { @@ -1415,6 +1243,12 @@ static struct grecs_keyword wydawca_kw[] = { { "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 }, @@ -1446,13 +1280,6 @@ static struct grecs_keyword wydawca_kw[] = { NULL, NULL, tcpwrapper_kw }, #endif - { "mailer", N_("url"), N_("Set mailer URL"), - grecs_type_string, GRECS_DFLT, &mailer, 0, cb_mailer }, - { "admin-address", N_("email"), N_("Set admin email address"), - grecs_type_string, GRECS_DFLT, &admin_address, 0, cb_email_address }, - { "from-address", N_("email"), N_("Set sender email address"), - grecs_type_string, GRECS_DFLT, &from_address, 0, cb_email_address }, - /* FIXME: Must be a built-in type? */ { "file-sweep-time", N_("interval"), N_("Define file sweep time"), grecs_type_string, GRECS_DFLT, &file_sweep_time, 0, cb_interval }, @@ -1467,27 +1294,16 @@ static struct grecs_keyword wydawca_kw[] = { N_("Control implicit signature archivation"), grecs_type_bool, GRECS_DFLT, &archive_signatures }, - { "statistics", N_("items"), N_("Print these stats at the end of run"), - grecs_type_string, GRECS_DFLT, &print_stats, 0, cb_statistics }, - { "sql", N_("id: string"), N_("Define SQL database"), grecs_type_section, GRECS_DFLT, NULL, 0, cb_sql, NULL, sql_kw }, { "syslog", NULL, N_("Configure syslog logging"), grecs_type_section, GRECS_DFLT, NULL, 0, NULL, NULL, syslog_kw }, - { "define-message", N_("ident: string> <text: string"), - N_("Define message text"), - grecs_type_string, GRECS_DFLT, NULL, 0, cb_define_message }, - { "archive", N_("type: string"), N_("Set up archivation"), grecs_type_section, GRECS_DFLT, &default_archive_descr, 0, cb_archive, NULL, archive_kw }, - { "mail-statistics", NULL, N_("Send statistics"), - grecs_type_section, GRECS_DFLT, NULL, 0, NULL, NULL, - mail_statistics_kw }, - { "notify-event", NULL, N_("Configure notification"), grecs_type_section, GRECS_DFLT, &default_notification, 0, cb_notify_event, NULL, notify_event_kw }, @@ -1545,6 +1361,19 @@ 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, + p->v.value)) + continue; + if (module_set_init(p->v.value->v.string, p)) + grecs_error(&p->v.value->locus, 0, + _("unknown module")); + } + } } |