aboutsummaryrefslogtreecommitdiff
path: root/src/mail.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2009-02-16 01:30:44 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2009-02-16 01:37:24 +0200
commit5000c56d29cf616c8df80f8ec9a19682769f512e (patch)
treed2cc46fda9e8905bdd2fb81bffdaf3a58898be53 /src/mail.c
parenta72cd5987c404080f18ba40bdc4c06811493ab1c (diff)
downloadwydawca-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.c141
1 files changed, 104 insertions, 37 deletions
diff --git a/src/mail.c b/src/mail.c
index f519413..2b31437 100644
--- a/src/mail.c
+++ b/src/mail.c
@@ -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);

Return to:

Send suggestions and report system problems to the System administrator.