aboutsummaryrefslogtreecommitdiff
path: root/src/config.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/config.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/config.c')
-rw-r--r--src/config.c271
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"));
+ }
+ }
}

Return to:

Send suggestions and report system problems to the System administrator.