aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2007-09-06 13:05:56 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2007-09-06 13:05:56 +0000
commit747e41693d7f2a808b3314cf82b3af38f98daf2d (patch)
treea023fea0ac96b2abdc2c98141d90a841544dbbf9 /src
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 (limited to 'src')
-rw-r--r--src/config.c167
-rw-r--r--src/mail.c172
-rw-r--r--src/mail.h4
-rw-r--r--src/wydawca.h18
-rw-r--r--src/wydawca.rc141
5 files changed, 262 insertions, 240 deletions
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
{
diff --git a/src/wydawca.rc b/src/wydawca.rc
deleted file mode 100644
index 5deba03..0000000
--- a/src/wydawca.rc
+++ /dev/null
@@ -1,141 +0,0 @@
-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
-Subject: Wydawca stats
-
-This is to notify you that the run of wydawca on %{date}
-caused the following results:
-
-errors ............................. %{stat:errors}
-warning ............................ %{stat:warnings}
-bad signatures ..................... %{stat:bad_signatures}
-access violation attempts .......... %{stat:access_violations}
-complete triplets .................. %{stat:complete_triplets}
-incomplete triplets ................ %{stat:incomplete_triplets}
-bad triplets ....................... %{stat:bad_triplets}
-expired triplets ................... %{stat:expired_triplets}
-triplet successes .................. %{stat:triplet_success}
-files uploaded ..................... %{stat:uploads}
-files archived ..................... %{stat:archives}
-symlinks created ................... %{stat:symlinks}
-symlinks removed ................... %{stat:rmsymlinks}
-
-Regards,
-Wydawca
-end
-
-mail-user success bad-ownership bad-directive-signature bad-detached-signature
-
-user-message success
-Subject: Upload of %{project} successful
-
-Upload of %{project} to %{dir} finished successfully. Files uploaded:
-
-%{triplet:upload}
-
-Regards,
-Wydawca
-The Project Submission Robot
-end
-
-user-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}:
-
-%{triplet:full}
-
-This upload has been ignored and the files removed. The person who attempted
-the upload was %{user:real-name}, user name %{user:name}, email %{user:email}.
-If you think this is an error and wish this user to be authorized to make
-releases for %{project}, please contact <puszcza-hackers@gnu.org.ua>.
-Otherwise, let us know so we could undertake appropriate measures.
-
-Regards,
-Wydawca
-The Project Submission Robot
-end
-
-user-message bad-directive-signature
-Subject: Suspicious upload of %{project}
-
-Someone (apparently you), 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. 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
-Subject: Suspicious upload of %{project}
-
-Someone (apparently you), has tried to make a release for %{project}.
-However, the detached signature signature was wrong, which looks
-suspicious. The person uploaded the following files:
-
-%{triplet:full}
-
-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
-end

Return to:

Send suggestions and report system problems to the System administrator.