summaryrefslogtreecommitdiffabout
authorSergey Poznyakoff <gray@gnu.org.ua>2007-09-06 13:05:56 (GMT)
committer Sergey Poznyakoff <gray@gnu.org.ua>2007-09-06 13:05:56 (GMT)
commit747e41693d7f2a808b3314cf82b3af38f98daf2d (patch) (side-by-side diff)
treea023fea0ac96b2abdc2c98141d90a841544dbbf9
parentafd4995c30c273a02f81e80a972688936907853a (diff)
downloadwydawca-747e41693d7f2a808b3314cf82b3af38f98daf2d.tar.gz
wydawca-747e41693d7f2a808b3314cf82b3af38f98daf2d.tar.bz2
Redo mail notifications
git-svn-id: file:///svnroot/wydawca/trunk@316 6bb4bd81-ecc2-4fd4-a2d4-9571d19c0d33
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--ChangeLog16
-rwxr-xr-xbootstrap2
-rw-r--r--doc/wydawca.texi143
-rw-r--r--etc/messages.rc (renamed from src/wydawca.rc)110
-rw-r--r--etc/wydawca.rc63
-rw-r--r--src/config.c167
-rw-r--r--src/mail.c172
-rw-r--r--src/mail.h4
-rw-r--r--src/wydawca.h18
9 files changed, 491 insertions, 204 deletions
diff --git a/ChangeLog b/ChangeLog
index 33bc245..b1f0d95 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2007-09-06 Sergey Poznyakoff <gray@gnu.org.ua>
+
+ * bootstrap: Update
+ * doc/wydawca.texi: Update
+ * src/wydawca.h (notify_project_owner): Remove
+ (enum notification_target): New data type
+ (find_message_template, register_notification)
+ (notification_event_str, notification_target_str): New functions.
+ * src/config.c: Redo message template statements
+ * src/mail.c: Redo notifications
+ * src/mail.h (admin_stat_message_template): Change data type
+ (owner_notification_flags,user_message_template): Remove
+ * src/wydawca.rc: Moved to ...
+ * etc/wydawca.rc: ... here
+ * etc/messages.rc: New file
+
2007-09-05 Sergey Poznyakoff <gray@gnu.org.ua>
* doc/wydawca.texi: Update.
diff --git a/bootstrap b/bootstrap
index 5be1664..2199382 100755
--- a/bootstrap
+++ b/bootstrap
@@ -42,7 +42,7 @@ fi
test -d m4 || mkdir m4 || exit 1
test -d gnu || mkdir gnu || exit 1
-svn export http://svn.gnu.org.ua/sources/gsc/trunk/lib lib &&
+svn export --force http://svn.gnu.org.ua/sources/gsc/trunk/lib lib &&
gnulib-tool --source-base=gnu --import \
xalloc obstack getopt hash error progname getline mkdtemp save-cwd \
backupfile strerror vasprintf inttostr strftime &&
diff --git a/doc/wydawca.texi b/doc/wydawca.texi
index cc7b04c..b313e4f 100644
--- a/doc/wydawca.texi
+++ b/doc/wydawca.texi
@@ -969,6 +969,7 @@ from the name of the user @command{wydawca} runs as (usually
@menu
* mailer::
+* templates::
* admin notification::
* user notification::
@end menu
@@ -977,7 +978,7 @@ from the name of the user @command{wydawca} runs as (usually
@subsection Mailer
@cindex mailer
@kwindex mailer
- To send messages @command{wydawca} uses a special logical entity
+ To send messages, @command{wydawca} uses a special logical entity
called @dfn{mailer}. It is set in the configuration file using
@code{mailer} keyword:
@@ -1038,19 +1039,86 @@ mailer smtp://remote.server.net:24
@end group
@end smallexample
+@node templates
+@subsection Message Templates
+@cindex templates, notification messages
+@cindex notification message template
+@cindex message template
+ Each notification message is build from a message template, by
+expanding any occurrances of @samp{%@{@var{name}@}} within it with the value
+of macro-variable @var{name}. The sets of defined macro-variables
+depend on the type of the notification and are described below.
+
+@kwindex define-message
+ Message templates are defined using @code{define-message}
+statement. Its syntax is as follows:
+
+@smallexample
+define-message @var{id} [-]@var{delimiter}
+@var{lines}
+@var{delimiter}
+@end smallexample
+
+ The @var{id} is a symbolic identifier used to refer to this message
+in another configuration statements, @var{delimiter} is a delimiter
+used to mark the end of the message template, and @var{lines} are any
+number of lines that form the message template. If @var{delimiter} is
+prefixed by a minus sign, any leading whitespace will be removed from
+each template line, thus allowing to indent it in a natural
+way. Furthermore, the @var{delimiter} itself is optional. If it is
+omitted, the string @samp{end} is used to delimit the message.
+The following example illustrates the simplest way to define a message
+template:
+
+@smallexample
+define-message my-message
+Subject: test
+
+This is a test message.
+end
+@end smallexample
+
+ Following is the same message template, but indented in a more
+natural way. @samp{EOT} is used as a message delimiter:
+
+@smallexample
+define-message my-message -EOT
+ Subject: test
+
+ This is a test message.
+EOT
+@end smallexample
+
+ It is important to notice, that the message template must supply
+both @acronym{RFC} 822 headers, and message body, so it must always
+consist of two parts, separated by a single empty line. If you do not
+wish to supply any headers (which is unlikely, because a mail should
+at least have a @code{Subject} header), simply begin the message text
+with an empty line, like this:
+
+@smallexample
+define-message my-message -EOT
+
+ This is a test message.
+EOT
+@end smallexample
+
@node admin notification
@subsection Admin Notification
@kwindex mail-admin-stat
Sending notifications to the system administrator is enabled by
-@code{mail-admin-stat} statement. It takes as its argument a list of
-statistics keywords as described in @ref{statistics}. The notification
-will be sent only if statistics counters for at least one of the
-requested categories are not zero. For example, the following
-statement requires sending notifications only if there ocurred any
-errors or access violation attempts, or any bad signature was uploaded:
+@code{mail-admin-stat} statement. It takes two or more arguments.
+The first argument supplies the identifier of a message template,
+which should be previously defined by a @code{define-message}.
+The rest of arguments is a list of statistics keywords as described in
+@ref{statistics}. The notification will be sent only if statistics
+counters for at least one of the requested categories are not
+zero. For example, the following statement requires sending
+notifications only if there ocurred any errors or access violation
+attempts, or any bad signature was uploaded:
@smallexample
-mail-admin-stat errors access-violations bad-signatures
+mail-admin-stat stat-msg errors access-violations bad-signatures
@end smallexample
@kwindex
@@ -1063,36 +1131,8 @@ addresses, e.g.:
admin-address root@@gnu.org.ua, ftp-adm@@gnu.org.ua
@end smallexample
-@kwindex admin-stat-message
- Finally, the text of the notification is given using
-@code{admin-stat-message} statement. As any block statement,
-it ends with an @code{end} keyword on a line by itself. The lines
-between @code{admin-stat-message} and @code{end} statements compose
-the notification text. This text must consist of two parts, separated
-by a single empty line. The part before the empty line gives any
-@acronym{RFC} 822 headers, and the part after it supplies the email
-body. It is important that both parts be always present. If you do not
-wish to supply any headers, simply begin the message text with an
-empty line. Following is a simple example of the
-@code{admin-stat-message} statement:
-
-@smallexample
-admin-stat-message
-Subject: Wydawca stats
-
-On my recent run I have noticed some events that may
-need your attention.
-
-Regards,
-Wydawca
-end
-@end smallexample
-
-@cindex meta-variables in @code{admin-stat-message}
- Any occurrence of @samp{%@{@var{name}@}} in the text is replaced
-with the value of the meta-variable @var{name}. If such meta-variable
-is not defined, this string is passed unchanged. The meta-variables
-available for use in @code{admin-stat-message} text are:
+@cindex meta-variables in admin notifications
+The meta-variables available for use in admin notifications are:
@multitable @columnfractions 0.50 0.50
@headitem Variable @tab Replaced with
@@ -1129,11 +1169,10 @@ triplets.
@item stat:rmsymlinks @tab Number of symbolic links removed.
@end multitable
- These macro-variables can make the notification text be more
-informative, as shown in the following example:
+ An example definition of the admin notification template follows:
@smallexample
-admin-stat-message
+define-message stat-msg
Subject: Wydawca stats
This is to notify you that my run on %@{date@}
@@ -1496,21 +1535,29 @@ Sets the sender address for mail notifications.
@xref{notification}, for more information on this statement.
@end deffn
-@deffn {Wydawca Statement} mail-admin-stat @var{condition-list}
+@deffn {Wydawca Statement} mail-admin-stat @var{msg-id} @var{condition-list}
Defines statistics categories that trigger administrator
notifications.
@xref{admin notification}.
@end deffn
-@deffn {Wydawca Statement} admin-stat-message
-Defines the text of administrator notification message.
+@deffn {Wydawca Statement} define-message
+Define a message template. The full syntax is:
-@xref{admin notification}.
-@end deffn
+@smallexample
+define-message @var{id} [[-]@var{delimiter}]
+@var{lines}
+@var{delimiter}
+@end smallexample
+
+ The @var{id} supplies the template identifier, @var{lines} gives
+message headers and body, separated by a newline. If @var{delimiter}
+is prefixed by @samp{-}, any leading whitespace is removed from the
+template lines. If @var{delimiter} is not given, @samp{end} is
+assumed.
-@deffn {Wydawca Statement} user-message @var{condition}
-@FIXME{Description}
+@xref{templates}, for more information on message templates.
@end deffn
@deffn {Wydawca Statement} mailer @var{url}
diff --git a/src/wydawca.rc b/etc/messages.rc
index 5deba03..6589ea5 100644
--- a/src/wydawca.rc
+++ b/etc/messages.rc
@@ -1,25 +1,4 @@
-syslog-facility local1
-syslog-tag wydawca
-syslog-print-priority yes
-statistics all
-
-file-sweep-time 1 hour
-
-sql default
- host localhost:/tmp/mysql.sock
- database savane
- user savane
- password guessme
-end
-
-umask 022
-tar-program /bin/tar
-
-admin-address gray@localhost
-from-address wydawca@localhost
-mail-admin-stat all
-
-admin-stat-message
+define-message admin-stat
Subject: Wydawca stats
This is to notify you that the run of wydawca on %{date}
@@ -43,9 +22,7 @@ Regards,
Wydawca
end
-mail-user success bad-ownership bad-directive-signature bad-detached-signature
-
-user-message success
+define-message user-success
Subject: Upload of %{project} successful
Upload of %{project} to %{dir} finished successfully. Files uploaded:
@@ -57,11 +34,24 @@ Wydawca
The Project Submission Robot
end
-user-message bad-ownership
+define-message owner-success
+Subject: Upload of %{project} successful
+
+%{user:real-name} (%{user:email}) successfully uploaded files
+for %{project} to %{dir}. Files uploaded:
+
+%{triplet:upload}
+
+Regards,
+Wydawca
+The Project Submission Robot
+end
+
+define-message bad-ownership
Subject: Suspicious upload of %{project}
-Someone not authorized to make releases for %{project} has attempted to upload
-the following files to %{dir}:
+Someone not authorized to make releases for %{project}
+has attempted to upload the following files to %{dir}:
%{triplet:full}
@@ -76,7 +66,7 @@ Wydawca
The Project Submission Robot
end
-user-message bad-directive-signature
+define-message user-bad-directive-signature
Subject: Suspicious upload of %{project}
Someone (apparently you), has tried to make a release for %{project}.
@@ -89,12 +79,29 @@ This upload has been ignored and the files removed. If it was you who
attempted this upload, please make sure you use the right PGP key and
try again. If not, please let us know as soon as possible, so we can
track down the person trying to make believe he is you.
+
Regards,
Wydawca
The Project Submission Robot
end
-user-message bad-detached-signature
+define-message owner-bad-directive-signature
+Subject: Suspicious upload of %{project}
+
+%{user:real-name} (%{user:email}) has tried to make a release
+for %{project}. However, the signature of the directive file was wrong,
+which looks suspicious. The person uploaded the following files:
+
+%{triplet:full}
+
+This upload has been ignored and the files removed.
+
+Regards,
+Wydawca
+The Project Submission Robot
+end
+
+define-message user-bad-detached-signature
Subject: Suspicious upload of %{project}
Someone (apparently you), has tried to make a release for %{project}.
@@ -107,35 +114,26 @@ This upload has been ignored and the files removed. If it was you who
attempted this upload, please make sure you use the right PGP key and
try again. If not, please let us know as soon as possible, so we can
track down the person trying to make believe he is you.
+
Regards,
Wydawca
The Project Submission Robot
end
-project-owner sql default SELECT user.email, user.realname \
- FROM user,user_group,groups \
- WHERE user_group.user_id=user.user_id \
- AND user_group.group_id=groups.group_id \
- AND user_group.admin_flags = 'A' \
- AND groups.unix_group_name='%p'
-
-user-data sql default SELECT email, realname \
- FROM user \
- WHERE user_name='%{user}'
-
-directory
- source /home/ftp/incoming/ftp
- destination /home/ftp/gnu
- verify-user sql default SELECT user.user_name \
- FROM user,user_group,groups \
- WHERE user_group.user_id=user.user_id \
- AND user_group.group_id=groups.group_id \
- AND user_group.admin_flags = 'A' \
- AND groups.unix_group_name='%p' \
- AND user.user_name='%u'
- gpg-key sql default SELECT gpg_key FROM user WHERE user_name='%u'
- archive directory .archive
- #archive directory .archive numbered
- #archive directory /var/spool/archive
- #archive tar /var/spool/archive.tar
+define-message owner-bad-detached-signature
+Subject: Suspicious upload of %{project}
+
+%{user:real-name} (%{user:email}) has tried to make a release
+for %{project}. However, the detached signature file was wrong,
+which looks suspicious. The person uploaded the following files:
+
+%{triplet:full}
+
+This upload has been ignored and the files removed.
+
+Regards,
+Wydawca
+The Project Submission Robot
end
+
+
diff --git a/etc/wydawca.rc b/etc/wydawca.rc
new file mode 100644
index 0000000..2996513
--- a/dev/null
+++ b/etc/wydawca.rc
@@ -0,0 +1,63 @@
+syslog-facility local1
+syslog-tag wydawca
+syslog-print-priority yes
+statistics all
+
+file-sweep-time 1 hour
+
+sql default
+ host localhost:/tmp/mysql.sock
+ database savane
+ user savane
+ password guessme
+end
+
+umask 022
+tar-program /bin/tar
+
+project-owner sql default SELECT user.email, user.realname \
+ FROM user,user_group,groups \
+ WHERE user_group.user_id=user.user_id \
+ AND user_group.group_id=groups.group_id \
+ AND user_group.admin_flags = 'A' \
+ AND groups.unix_group_name='%p'
+
+user-data sql default SELECT email, realname \
+ FROM user \
+ WHERE user_name='%{user}'
+
+directory
+ source /home/ftp/incoming/ftp
+ destination /home/ftp/gnu
+ verify-user sql default SELECT user.user_name \
+ FROM user,user_group,groups \
+ WHERE user_group.user_id=user.user_id \
+ AND user_group.group_id=groups.group_id \
+ AND user_group.admin_flags = 'A' \
+ AND groups.unix_group_name='%p' \
+ AND user.user_name='%u'
+ gpg-key sql default SELECT gpg_key FROM user WHERE user_name='%u'
+ archive directory .archive
+ #archive directory .archive numbered
+ #archive directory /var/spool/archive
+ #archive tar /var/spool/archive.tar
+end
+
+
+include messages.rc
+
+admin-address gray@localhost
+from-address wydawca@localhost
+
+mail-admin-stat admin-stat all
+
+notify-event success user user-success
+notify-event success owner owner-success
+
+notify-event bad-ownership owner bad-ownership
+
+notify-event bad-directive-signature user user-bad-directive-signature
+notify-event bad-directive-signature owner owner-bad-directive-signature
+
+notify-event bad-detached-signature user user-bad-detached-signature
+notify-event bad-detached-signature owner owner-bad-detached-signature
diff --git a/src/config.c b/src/config.c
index 13f90ce..ed0bafd 100644
--- a/src/config.c
+++ b/src/config.c
@@ -832,6 +832,26 @@ static void
cfg_mail_admin_stat (gsc_config_file_t *file, char *kw, char *val,
void *unused)
{
+ char *word;
+
+ if (!val)
+ {
+ file->error_msg (file->file_name, file->line,
+ "missing message template identifier");
+ file->error_count++;
+ return;
+ }
+
+ word = get_word (&val);
+
+ admin_stat_message_template = find_message_template (word);
+ if (!admin_stat_message_template)
+ {
+ file->error_msg (file->file_name, file->line,
+ "no such message template: %s", word);
+ file->error_count++;
+ return;
+ }
_cfg_statmask (file, val, &mail_admin_mask);
}
@@ -918,16 +938,43 @@ _cfg_raw_read (gsc_config_file_t *file, char *val, struct obstack *stk)
file->error_count++;
}
}
-
+
static void
-cfg_admin_stat_message (gsc_config_file_t *file, char *kw, char *val,
- void *unused)
+cfg_define_message (gsc_config_file_t *file, char *kw, char *val, void *unused)
{
+ char *word;
+ if (!val)
+ {
+ file->error_msg (file->file_name, file->line,
+ "missing message identifier");
+ file->error_count++;
+ return;
+ }
+
+ word = xstrdup (get_word (&val));
if (_cfg_raw_read (file, val, &cfg_stk) == 0)
- admin_stat_message_template = obstack_finish (&cfg_stk);
+ register_message_template (word, obstack_finish (&cfg_stk));
}
+int
+string_to (char *what, char *str,
+ const char **args, int *vals,
+ int *pret,
+ gsc_config_file_t *file)
+{
+ ptrdiff_t x = ARGMATCH (str, args, vals);
+
+ if (x == (ptrdiff_t)-1)
+ {
+ file->error_msg (file->file_name, file->line,
+ "unknown %s: %s", what, str);
+ file->error_count++;
+ return 1;
+ }
+ *pret = vals[x];
+ return 0;
+}
static const char *event_args[] = {
"success",
@@ -937,7 +984,7 @@ static const char *event_args[] = {
NULL
};
-static enum notification_event event_types[] = {
+static int event_types[] = {
ev_success,
ev_bad_ownership,
ev_bad_directive_signature,
@@ -946,30 +993,69 @@ static enum notification_event event_types[] = {
ARGMATCH_VERIFY (event_args, event_types);
+const char *
+notification_event_str (enum notification_event evt)
+{
+ return event_args[evt];
+}
+
int
string_to_notification_event (gsc_config_file_t *file, char *val,
enum notification_event *pret)
{
- ptrdiff_t x = ARGMATCH (val, event_args, event_types);
-
- if (x == (ptrdiff_t)-1)
- {
- file->error_msg (file->file_name, file->line,
- "unknown notification type: %s", val);
- file->error_count++;
- return 1;
- }
- *pret = event_types[x];
- return 0;
+ int rc, res;
+ rc = string_to ("notification event", val,
+ event_args, event_types,
+ &res,
+ file);
+ *pret = res;
+ return rc;
+}
+
+static const char *target_args[] = {
+ "admin",
+ "user",
+ "owner",
+ NULL
+};
+
+static int target_types[] = {
+ notify_admin, /* System administrator */
+ notify_owner, /* Project admin */
+ notify_user /* User (uploader) */
+};
+
+ARGMATCH_VERIFY (target_args, target_types);
+
+const char *
+notification_target_str (enum notification_target tgt)
+{
+ return target_args[tgt];
+}
+
+int
+string_to_notification_target (gsc_config_file_t *file, char *val,
+ enum notification_target *pret)
+{
+ int rc, res;
+ rc = string_to ("notification target", val,
+ target_args, target_types,
+ &res,
+ file);
+ *pret = res;
+ return rc;
}
static void
-cfg_mail_user (gsc_config_file_t *file, char *kw, char *val, void *unused)
+cfg_notify_event (gsc_config_file_t *file, char *kw, char *val, void *unused)
{
- int i;
int argc;
char **argv;
-
+ enum notification_event evt;
+ enum notification_target tgt;
+ struct message_template *msg;
+ int rc;
+
if (argcv_get (val, NULL, NULL, &argc, &argv))
{
file->error_msg (file->file_name, file->line,
@@ -978,38 +1064,32 @@ cfg_mail_user (gsc_config_file_t *file, char *kw, char *val, void *unused)
return;
}
- for (i = 0; i < argc; i++)
+ if (argc != 3)
{
- enum notification_event evt;
-
- if (string_to_notification_event (file, argv[i], &evt))
- break;
- owner_notification_flags |= STAT_MASK (evt);
+ file->error_msg (file->file_name, file->line,
+ "wrong number of arguments");
+ file->error_count++;
+ argcv_free (argc, argv);
+ return;
}
- argcv_free (argc, argv);
-}
-
-static void
-cfg_user_message (gsc_config_file_t *file, char *kw, char *val, void *unused)
-{
- enum notification_event evt;
- char *word = get_word (&val);
- if (!*word)
+ rc = string_to_notification_event (file, argv[0], &evt)
+ | string_to_notification_target (file, argv[1], &tgt);
+ if ((msg = find_message_template (argv[2])) == NULL)
{
+ rc = 1;
file->error_msg (file->file_name, file->line,
- "not enough arguments");
+ "undefined message: %s", argv[2]);
file->error_count++;
- return;
}
-
- if (string_to_notification_event (file, word, &evt))
- return;
- if (_cfg_raw_read (file, val, &cfg_stk) == 0)
- user_message_template[evt] = obstack_finish (&cfg_stk);
+ if (rc == 0)
+ register_notification (evt, tgt, msg);
+
+ argcv_free (argc, argv);
}
+
static struct gsc_config_keyword kw_handler[] = {
@@ -1032,9 +1112,8 @@ static struct gsc_config_keyword kw_handler[] = {
{ "admin-address", cfg_admin_address },
{ "from-address", cfg_from_address },
{ "mail-admin-stat", cfg_mail_admin_stat },
- { "admin-stat-message", cfg_admin_stat_message },
- { "mail-user", cfg_mail_user },
- { "user-message", cfg_user_message },
+ { "define-message", cfg_define_message },
+ { "notify-event", cfg_notify_event },
{ NULL }
};
diff --git a/src/mail.c b/src/mail.c
index f16ed63..0648280 100644
--- a/src/mail.c
+++ b/src/mail.c
@@ -22,7 +22,7 @@ mu_mailer_t mailer;
mu_address_t admin_address;
mu_address_t from_address;
unsigned long mail_admin_mask;
-char *admin_stat_message_template;
+struct message_template *admin_stat_message_template;
unsigned long owner_notification_flags;
char *user_message_template[MAX_EVENT];
@@ -98,6 +98,70 @@ mail_send_message (mu_address_t rcpt, const char *text)
}
void
+mail_finish ()
+{
+ if (mailer_opened)
+ mu_mailer_close (mailer);
+}
+
+
+struct message_template
+{
+ struct message_template *next;
+ char *name;
+ char *text;
+ /* int mime; for future use */
+};
+
+static struct message_template *message_list;
+
+void
+register_message_template (char *name, char *text)
+{
+ struct message_template *newp = xmalloc (sizeof *newp);
+ newp->name = name;
+ newp->text = text;
+ newp->next = message_list;
+ message_list = newp;
+}
+
+struct message_template *
+find_message_template (char *name)
+{
+ struct message_template *p;
+
+ for (p = message_list; p; p = p->next)
+ if (strcmp (p->name, name) == 0)
+ break;
+ return p;
+}
+
+
+struct notification
+{
+ struct notification *next;
+ enum notification_event ev;
+ enum notification_target tgt;
+ struct message_template *msg;
+};
+
+static struct notification *notification_list;
+
+void
+register_notification (enum notification_event ev,
+ enum notification_target tgt,
+ struct message_template *msg)
+{
+ struct notification *newp = xmalloc (sizeof *newp);
+ newp->ev = ev;
+ newp->tgt = tgt;
+ newp->msg = msg;
+ newp->next = notification_list;
+ notification_list = newp;
+}
+
+
+void
mail_stats ()
{
struct kw_expansion exp[MAX_STAT + 1];
@@ -129,7 +193,7 @@ mail_stats ()
make_stat_expansion (exp + 1);
- text = expand_param (admin_stat_message_template,
+ text = expand_param (admin_stat_message_template->text,
exp, sizeof (exp) / sizeof (exp[0]), NULL);
mail_send_message (admin_address, text);
@@ -138,53 +202,26 @@ mail_stats ()
free_kwexp (exp, sizeof (exp) / sizeof (exp[0]));
}
-void
-mail_finish ()
+mu_address_t
+get_recipient (struct access_method *method, struct file_triplet *trp,
+ char **errp)
{
- if (mailer_opened)
- mu_mailer_close (mailer);
-}
-
-void
-notify_owner (struct file_triplet *trp, enum notification_event ev)
-{
- int rc;
- struct access_method *method;
- char *text;
- mu_address_t rcpt = NULL;
unsigned nrows, ncols, i;
struct kw_expansion kwexp[4];
-
- switch (ev)
- {
- case ev_success:
- case ev_bad_directive_signature:
- case ev_bad_detached_signature:
- method = trp->dpair->user_data_method;
- break;
-
- case ev_bad_ownership:
- method = trp->dpair->project_owner_method;
- break;
-
- default:
- abort ();
- }
+ mu_address_t rcpt = NULL;
+ char *text;
+ int rc;
if (method->type == method_none)
{
- logmsg (LOG_NOTICE,
- "NOT notifying project admins: project-owner not configured in "
- "[%s, %s]", trp->dpair->source_dir, trp->dpair->dest_dir);
- return;
+ *errp = "access method is not configured";
+ return NULL;
}
if (method_init (method))
{
- logmsg (LOG_ERR,
- "failed to initialize project-owner method: "
- "NOT notifying project admins");
- return;
+ *errp = "failed to initialize access method";
+ return NULL;
}
make_default_kwexp (kwexp, trp->user, trp->project);
@@ -195,9 +232,8 @@ notify_owner (struct file_triplet *trp, enum notification_event ev)
free (text);
if (rc)
{
- logmsg (LOG_ERR, "cannot obtain owner emails for %s",
- trp->project);
- return;
+ *errp = "cannot obtain recipient emails";
+ return NULL;
}
nrows = method_num_rows (method);
@@ -205,9 +241,8 @@ notify_owner (struct file_triplet *trp, enum notification_event ev)
if (nrows == 0)
{
- logmsg (LOG_ERR, "cannot obtain owner emails for %s",
- trp->project);
- return;
+ *errp = "cannot obtain recipient emails";
+ return NULL;
}
for (i = 0; i < nrows; i++)
@@ -226,6 +261,40 @@ notify_owner (struct file_triplet *trp, enum notification_event ev)
mu_address_destroy (&addr);
}
+ return rcpt;
+}
+
+void
+do_notify (struct file_triplet *trp, enum notification_event ev,
+ struct notification *ntf)
+{
+ int rc;
+ mu_address_t rcpt = NULL;
+ char *errp;
+
+ switch (ntf->tgt)
+ {
+ case notify_admin:
+ rcpt = admin_address;
+ break;
+
+ case notify_user:
+ rcpt = get_recipient (trp->dpair->user_data_method, trp, &errp);
+ break;
+
+ case notify_owner:
+ rcpt = get_recipient (trp->dpair->project_owner_method, trp, &errp);
+ }
+
+ if (!rcpt)
+ {
+ logmsg (LOG_ERR, "not notifying %s (project %s) about %s: %s",
+ notification_target_str (ntf->tgt),
+ trp->project,
+ notification_event_str (ev), errp);
+ return;
+ }
+
if (debug_level)
{
size_t size;
@@ -233,14 +302,14 @@ notify_owner (struct file_triplet *trp, enum notification_event ev)
mu_address_to_string (rcpt, NULL, 0, &size);
buf = xmalloc (size + 1);
mu_address_to_string (rcpt, buf, size + 1, NULL);
- logmsg (LOG_DEBUG, "Notifying admins of %s: %s", trp->project,
- buf);
+ logmsg (LOG_DEBUG, "notifying %s (project %s) about %s",
+ buf, trp->project, notification_event_str (ev));
free (buf);
}
if (!dry_run_mode)
{
- text = triplet_expand_param (user_message_template[ev], trp);
+ char *text = triplet_expand_param (ntf->msg->text, trp);
mail_send_message (rcpt, text);
free (text);
}
@@ -251,8 +320,11 @@ notify_owner (struct file_triplet *trp, enum notification_event ev)
void
notify (struct file_triplet *trp, enum notification_event ev)
{
+ struct notification *p;
+
fill_project_name (trp);
- if (owner_notification_flags & STAT_MASK (ev))
- notify_owner (trp, ev);
+ for (p = notification_list; p; p = p->next)
+ if (p->ev == ev)
+ do_notify (trp, ev, p);
/* FIXME */
}
diff --git a/src/mail.h b/src/mail.h
index 02c95b7..30f6649 100644
--- a/src/mail.h
+++ b/src/mail.h
@@ -20,9 +20,7 @@ extern mu_mailer_t mailer;
extern mu_address_t admin_address;
extern mu_address_t from_address;
extern unsigned long mail_admin_mask;
-extern char *admin_stat_message_template;
-extern unsigned long owner_notification_flags;
-extern char *user_message_template[MAX_EVENT];
+extern struct message_template *admin_stat_message_template;
void mail_init (void);
void mail_finish (void);
diff --git a/src/wydawca.h b/src/wydawca.h
index 0d38bd3..2de86f0 100644
--- a/src/wydawca.h
+++ b/src/wydawca.h
@@ -197,10 +197,24 @@ enum notification_event
MAX_EVENT
};
-void notify_project_owner (struct file_triplet *, enum notification_event);
-void notify_admin (struct file_triplet *, enum notification_event);
+enum notification_target
+ {
+ notify_admin, /* System administrator */
+ notify_owner, /* Project admin */
+ notify_user /* User (uploader) */
+ };
+
+struct message_template;
+struct message_template *find_message_template (char *name);
+void register_notification (enum notification_event ev,
+ enum notification_target tgt,
+ struct message_template *msg);
+
void notify (struct file_triplet *, enum notification_event);
+const char *notification_event_str (enum notification_event evt);
+const char *notification_target_str (enum notification_target tgt);
+
struct kw_expansion
{

Return to:

Send suggestions and report system problems to the System administrator.