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 @@ | |||
1 | /* wydawca - automatic release submission daemon | 1 | /* wydawca - automatic release submission daemon |
2 | Copyright (C) 2007, 2008 Sergey Poznyakoff | 2 | Copyright (C) 2007, 2008, 2009 Sergey Poznyakoff |
3 | 3 | ||
4 | Wydawca is free software; you can redistribute it and/or modify it | 4 | Wydawca is free software; you can redistribute it and/or modify it |
5 | under the terms of the GNU General Public License as published by the | 5 | under the terms of the GNU General Public License as published by the |
@@ -16,16 +16,18 @@ | |||
16 | 16 | ||
17 | #include "wydawca.h" | 17 | #include "wydawca.h" |
18 | #include <mail.h> | 18 | #include <mail.h> |
19 | #include <hash.h> | ||
19 | 20 | ||
20 | int mailer_opened; | 21 | int mailer_opened; |
21 | mu_mailer_t mailer; | 22 | mu_mailer_t mailer; |
22 | mu_address_t admin_address; | 23 | mu_address_t admin_address; |
23 | mu_address_t from_address; | 24 | mu_address_t from_address; |
24 | unsigned long mail_admin_mask; | 25 | unsigned long mail_admin_mask; |
25 | struct message_template *admin_stat_message_template; | ||
26 | unsigned long owner_notification_flags; | 26 | unsigned long owner_notification_flags; |
27 | char *user_message_template[MAX_EVENT]; | 27 | char *user_message_template[MAX_EVENT]; |
28 | 28 | ||
29 | char *admin_stat_message; | ||
30 | |||
29 | void | 31 | void |
30 | mail_init () | 32 | mail_init () |
31 | { | 33 | { |
@@ -107,55 +109,104 @@ mail_finish () | |||
107 | 109 | ||
108 | struct message_template | 110 | struct message_template |
109 | { | 111 | { |
110 | struct message_template *next; | ||
111 | char *name; | 112 | char *name; |
112 | char *text; | 113 | char *text; |
113 | /* int mime; for future use */ | 114 | /* int mime; for future use */ |
114 | }; | 115 | }; |
115 | 116 | ||
116 | static struct message_template *message_list; | 117 | static Hash_table *tmpl_table; |
117 | 118 | ||
118 | void | 119 | /* Calculate the hash of a string. */ |
119 | register_message_template (char *name, char *text) | 120 | static size_t |
121 | tmpl_hasher (void const *data, unsigned n_buckets) | ||
122 | { | ||
123 | struct message_template const *tmpl = data; | ||
124 | return hash_string (tmpl->name, n_buckets); | ||
125 | } | ||
126 | |||
127 | /* Compare two strings for equality. */ | ||
128 | static bool | ||
129 | tmpl_compare (void const *data1, void const *data2) | ||
130 | { | ||
131 | struct message_template const *tmpl1 = data1; | ||
132 | struct message_template const *tmpl2 = data2; | ||
133 | return strcmp (tmpl1->name, tmpl2->name) == 0; | ||
134 | } | ||
135 | |||
136 | static void | ||
137 | tmpl_free (void *data) | ||
120 | { | 138 | { |
121 | struct message_template *newp = xmalloc (sizeof *newp); | 139 | free (data); |
122 | newp->name = name; | ||
123 | newp->text = text; | ||
124 | newp->next = message_list; | ||
125 | message_list = newp; | ||
126 | } | 140 | } |
127 | 141 | ||
128 | struct message_template * | 142 | struct message_template * |
129 | find_message_template (char *name) | 143 | alloc_message_template (const char *name, const char *text) |
130 | { | 144 | { |
131 | struct message_template *p; | 145 | struct message_template *tmpl = xmalloc (sizeof (tmpl[0]) |
146 | + strlen (name) + 1 | ||
147 | + strlen (text) + 1); | ||
148 | char *p = (char*) (tmpl + 1); | ||
149 | tmpl->name = p; | ||
150 | strcpy (tmpl->name, name); | ||
151 | |||
152 | p += strlen (p) + 1; | ||
153 | tmpl->text = p; | ||
154 | strcpy (tmpl->text, text); | ||
155 | return tmpl; | ||
156 | } | ||
132 | 157 | ||
133 | for (p = message_list; p; p = p->next) | 158 | /* Register a template. |
134 | if (strcmp (p->name, name) == 0) | 159 | FIXME: Issue a warning if it is already registered. */ |
135 | break; | 160 | void |
136 | return p; | 161 | register_message_template (const char *name, const char *text) |
162 | { | ||
163 | struct message_template *tmpl, *s; | ||
164 | |||
165 | s = alloc_message_template (name, text); | ||
166 | |||
167 | if (!((tmpl_table | ||
168 | || (tmpl_table = hash_initialize (0, 0, | ||
169 | tmpl_hasher, | ||
170 | tmpl_compare, | ||
171 | tmpl_free))) | ||
172 | && (text = hash_insert (tmpl_table, s)))) | ||
173 | xalloc_die (); | ||
174 | |||
175 | if (s != tmpl) | ||
176 | tmpl_free (s); | ||
137 | } | 177 | } |
138 | 178 | ||
139 | 179 | const char * | |
140 | struct notification | 180 | resolve_message_template (const char *name) |
141 | { | 181 | { |
142 | struct notification *next; | 182 | if (name[0] == '@') |
143 | enum notification_event ev; | 183 | { |
144 | enum notification_target tgt; | 184 | if (name[1] == '@') |
145 | struct message_template *msg; | 185 | return name + 1; |
146 | }; | 186 | else if (!tmpl_table) |
187 | return NULL; | ||
188 | else | ||
189 | { | ||
190 | struct message_template *p, tmpl; | ||
191 | |||
192 | tmpl.name = (char*) name + 1; | ||
193 | p = hash_lookup (tmpl_table, &tmpl); | ||
194 | return p ? p->text : NULL; | ||
195 | } | ||
196 | } | ||
197 | return name; | ||
198 | } | ||
147 | 199 | ||
200 | |||
148 | static struct notification *notification_list; | 201 | static struct notification *notification_list; |
149 | 202 | ||
150 | void | 203 | void |
151 | register_notification (enum notification_event ev, | 204 | register_notification (const struct notification *notif) |
152 | enum notification_target tgt, | ||
153 | struct message_template *msg) | ||
154 | { | 205 | { |
155 | struct notification *newp = xmalloc (sizeof *newp); | 206 | struct notification *newp = xmalloc (sizeof *newp); |
156 | newp->ev = ev; | 207 | newp->ev = notif->ev; |
157 | newp->tgt = tgt; | 208 | newp->tgt = notif->tgt; |
158 | newp->msg = msg; | 209 | newp->msg = notif->msg; |
159 | newp->next = notification_list; | 210 | newp->next = notification_list; |
160 | notification_list = newp; | 211 | notification_list = newp; |
161 | } | 212 | } |
@@ -166,9 +217,10 @@ mail_stats () | |||
166 | { | 217 | { |
167 | struct kw_expansion exp[MAX_STAT + 1]; | 218 | struct kw_expansion exp[MAX_STAT + 1]; |
168 | time_t t; | 219 | time_t t; |
220 | const char *tmpl; | ||
169 | char *text; | 221 | char *text; |
170 | 222 | ||
171 | if (!stat_mask_p (mail_admin_mask) || !mailer) | 223 | if (!admin_stat_message || !stat_mask_p (mail_admin_mask) || !mailer) |
172 | return; | 224 | return; |
173 | 225 | ||
174 | if (debug_level) | 226 | if (debug_level) |
@@ -193,7 +245,14 @@ mail_stats () | |||
193 | 245 | ||
194 | make_stat_expansion (exp + 1); | 246 | make_stat_expansion (exp + 1); |
195 | 247 | ||
196 | text = expand_param (admin_stat_message_template->text, | 248 | tmpl = resolve_message_template (admin_stat_message); |
249 | if (!tmpl) | ||
250 | { | ||
251 | logmsg (LOG_ERR, "undefined message reference: %s", | ||
252 | admin_stat_message); | ||
253 | return; | ||
254 | } | ||
255 | text = expand_param (tmpl, | ||
197 | exp, sizeof (exp) / sizeof (exp[0]), NULL); | 256 | exp, sizeof (exp) / sizeof (exp[0]), NULL); |
198 | 257 | ||
199 | mail_send_message (admin_address, text); | 258 | mail_send_message (admin_address, text); |
@@ -277,11 +336,13 @@ do_notify (struct file_triplet *trp, enum notification_event ev, | |||
277 | break; | 336 | break; |
278 | 337 | ||
279 | case notify_user: | 338 | case notify_user: |
280 | rcpt = get_recipient (trp->dpair->user_data_method, trp, &errp); | 339 | rcpt = get_recipient (trp->dpair->access_method[user_data_method], |
340 | trp, &errp); | ||
281 | break; | 341 | break; |
282 | 342 | ||
283 | case notify_owner: | 343 | case notify_owner: |
284 | rcpt = get_recipient (trp->dpair->project_owner_method, trp, &errp); | 344 | rcpt = get_recipient (trp->dpair->access_method[project_owner_method], |
345 | trp, &errp); | ||
285 | } | 346 | } |
286 | 347 | ||
287 | if (!rcpt) | 348 | if (!rcpt) |
@@ -307,9 +368,15 @@ do_notify (struct file_triplet *trp, enum notification_event ev, | |||
307 | 368 | ||
308 | if (!dry_run_mode) | 369 | if (!dry_run_mode) |
309 | { | 370 | { |
310 | char *text = triplet_expand_param (ntf->msg->text, trp); | 371 | const char *msg = resolve_message_template (ntf->msg); |
311 | mail_send_message (rcpt, text); | 372 | if (!msg) |
312 | free (text); | 373 | logmsg (LOG_ERR, "undefined message reference: %s", ntf->msg); |
374 | else | ||
375 | { | ||
376 | char *text = triplet_expand_param (msg, trp); | ||
377 | mail_send_message (rcpt, text); | ||