diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-02-16 01:30:44 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-02-16 01:37:24 +0200 |
commit | 5000c56d29cf616c8df80f8ec9a19682769f512e (patch) | |
tree | d2cc46fda9e8905bdd2fb81bffdaf3a58898be53 /src/mail.c | |
parent | a72cd5987c404080f18ba40bdc4c06811493ab1c (diff) | |
download | wydawca-5000c56d29cf616c8df80f8ec9a19682769f512e.tar.gz wydawca-5000c56d29cf616c8df80f8ec9a19682769f512e.tar.bz2 |
Rewrite configuration parser, drop dependency on GSC
* bootstrap: Replaced with a modified version from gnulib.
* configure.ac: Bump version to 1.9.90
(--without-preprocessor): New option
Require Mailutils 2.0
(AC_CONFIG_FILES): Remove lib, add gconf
* gconf/: New directory. Contains general-purpose configuration file
parser, distilled from Dico and Mailutils.
* src/Makefile.am (wydawca_SOURCES): Add interval.c
* src/pp-setup, src/update-2.0.awk: New files.
* src/config.c: Full rewrite.
* src/exec.c (start_prog): Use getdtablesize unconditionally.
* src/mail.c: Keep templates in a hash table.
Template references begin with a single @
* src/process.c, src/triplet.c, src/verify.c: Reflect changes to struct
directory_pair
* src/wydawca.c: Change configuration parsing.
* src/wydawca.h (enum access_method_id): New constants
(struct directory_pair): Replace four access methods with an array.
* Makefile.am (SUBDIRS): Remove lib, add gconf
* .gitignore, NEWS, doc/.gitignore, src/.gitignore
Diffstat (limited to 'src/mail.c')
-rw-r--r-- | src/mail.c | 141 |
1 files changed, 104 insertions, 37 deletions
@@ -1,5 +1,5 @@ /* wydawca - automatic release submission daemon - Copyright (C) 2007, 2008 Sergey Poznyakoff + Copyright (C) 2007, 2008, 2009 Sergey Poznyakoff Wydawca is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -16,16 +16,18 @@ #include "wydawca.h" #include <mail.h> +#include <hash.h> int mailer_opened; mu_mailer_t mailer; mu_address_t admin_address; mu_address_t from_address; unsigned long mail_admin_mask; -struct message_template *admin_stat_message_template; unsigned long owner_notification_flags; char *user_message_template[MAX_EVENT]; +char *admin_stat_message; + void mail_init () { @@ -107,55 +109,104 @@ mail_finish () struct message_template { - struct message_template *next; char *name; char *text; /* int mime; for future use */ }; -static struct message_template *message_list; +static Hash_table *tmpl_table; -void -register_message_template (char *name, char *text) +/* Calculate the hash of a string. */ +static size_t +tmpl_hasher (void const *data, unsigned n_buckets) +{ + struct message_template const *tmpl = data; + return hash_string (tmpl->name, n_buckets); +} + +/* Compare two strings for equality. */ +static bool +tmpl_compare (void const *data1, void const *data2) +{ + struct message_template const *tmpl1 = data1; + struct message_template const *tmpl2 = data2; + return strcmp (tmpl1->name, tmpl2->name) == 0; +} + +static void +tmpl_free (void *data) { - struct message_template *newp = xmalloc (sizeof *newp); - newp->name = name; - newp->text = text; - newp->next = message_list; - message_list = newp; + free (data); } struct message_template * -find_message_template (char *name) +alloc_message_template (const char *name, const char *text) { - struct message_template *p; + struct message_template *tmpl = xmalloc (sizeof (tmpl[0]) + + strlen (name) + 1 + + strlen (text) + 1); + char *p = (char*) (tmpl + 1); + tmpl->name = p; + strcpy (tmpl->name, name); + + p += strlen (p) + 1; + tmpl->text = p; + strcpy (tmpl->text, text); + return tmpl; +} - for (p = message_list; p; p = p->next) - if (strcmp (p->name, name) == 0) - break; - return p; +/* Register a template. + FIXME: Issue a warning if it is already registered. */ +void +register_message_template (const char *name, const char *text) +{ + struct message_template *tmpl, *s; + + s = alloc_message_template (name, text); + + if (!((tmpl_table + || (tmpl_table = hash_initialize (0, 0, + tmpl_hasher, + tmpl_compare, + tmpl_free))) + && (text = hash_insert (tmpl_table, s)))) + xalloc_die (); + + if (s != tmpl) + tmpl_free (s); } - -struct notification +const char * +resolve_message_template (const char *name) { - struct notification *next; - enum notification_event ev; - enum notification_target tgt; - struct message_template *msg; -}; + if (name[0] == '@') + { + if (name[1] == '@') + return name + 1; + else if (!tmpl_table) + return NULL; + else + { + struct message_template *p, tmpl; + + tmpl.name = (char*) name + 1; + p = hash_lookup (tmpl_table, &tmpl); + return p ? p->text : NULL; + } + } + return name; +} + static struct notification *notification_list; void -register_notification (enum notification_event ev, - enum notification_target tgt, - struct message_template *msg) +register_notification (const struct notification *notif) { struct notification *newp = xmalloc (sizeof *newp); - newp->ev = ev; - newp->tgt = tgt; - newp->msg = msg; + newp->ev = notif->ev; + newp->tgt = notif->tgt; + newp->msg = notif->msg; newp->next = notification_list; notification_list = newp; } @@ -166,9 +217,10 @@ mail_stats () { struct kw_expansion exp[MAX_STAT + 1]; time_t t; + const char *tmpl; char *text; - if (!stat_mask_p (mail_admin_mask) || !mailer) + if (!admin_stat_message || !stat_mask_p (mail_admin_mask) || !mailer) return; if (debug_level) @@ -193,7 +245,14 @@ mail_stats () make_stat_expansion (exp + 1); - text = expand_param (admin_stat_message_template->text, + tmpl = resolve_message_template (admin_stat_message); + if (!tmpl) + { + logmsg (LOG_ERR, "undefined message reference: %s", + admin_stat_message); + return; + } + text = expand_param (tmpl, exp, sizeof (exp) / sizeof (exp[0]), NULL); mail_send_message (admin_address, text); @@ -277,11 +336,13 @@ do_notify (struct file_triplet *trp, enum notification_event ev, break; case notify_user: - rcpt = get_recipient (trp->dpair->user_data_method, trp, &errp); + rcpt = get_recipient (trp->dpair->access_method[user_data_method], + trp, &errp); break; case notify_owner: - rcpt = get_recipient (trp->dpair->project_owner_method, trp, &errp); + rcpt = get_recipient (trp->dpair->access_method[project_owner_method], + trp, &errp); } if (!rcpt) @@ -307,9 +368,15 @@ do_notify (struct file_triplet *trp, enum notification_event ev, if (!dry_run_mode) { - char *text = triplet_expand_param (ntf->msg->text, trp); - mail_send_message (rcpt, text); - free (text); + const char *msg = resolve_message_template (ntf->msg); + if (!msg) + logmsg (LOG_ERR, "undefined message reference: %s", ntf->msg); + else + { + char *text = triplet_expand_param (msg, trp); + mail_send_message (rcpt, text); + free (text); + } } mu_address_destroy (&rcpt); |