summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Weiss <holger@zedat.fu-berlin.de>2016-11-29 17:27:11 (GMT)
committerHolger Weiss <holger@zedat.fu-berlin.de>2016-11-29 17:27:11 (GMT)
commitb92a28a5fe38436fecd20b32b2ba1e68521f6430 (patch)
treeed4ef1ad7125b31c8a3bfd8fbdb1656bc6c4e286
parenta0e978dc078a72b1224a011defd0d905e5062dc8 (diff)
downloadsite-b92a28a5fe38436fecd20b32b2ba1e68521f6430.tar.gz
Remove Procmail filter for plugins@ address
We no longer forward GitHub notifications to the mailing list.
-rw-r--r--etc/procmailrc38
-rwxr-xr-xlibexec/filter-github-emails300
2 files changed, 0 insertions, 338 deletions
diff --git a/etc/procmailrc b/etc/procmailrc
deleted file mode 100644
index 7c7ecbd..0000000
--- a/etc/procmailrc
+++ /dev/null
@@ -1,38 +0,0 @@
1SHELL = /bin/sh
2PATH = /usr/bin:/bin
3MAILDIR = $HOME/mail
4LOGFILE = $HOME/log/procmail.log
5GITHUB_FILTER = $HOME/libexec/filter-github-emails
6DEFAULT_RECIPIENT = admin@monitoring-plugins.org
7EXTENSION = $1
8
9:0 c:
10backup
11
12:0
13* ! ^X-Loop: plugins@monitoring-plugins\.org
14{
15 :0 fhw
16 * ^From \/[^ ]+
17 | formail -A 'X-Loop: plugins@monitoring-plugins.org' \
18 -A "X-Original-From: $MATCH"
19
20 # Handle emails sent to <plugins+github@monitoring-plugins.org>.
21 :0
22 * EXTENSION ?? ^^github^^
23 {
24 :0 fw
25 | $GITHUB_FILTER
26
27 # Forward only if $GITHUB_FILTER rewrote the To: header.
28 :0
29 * ^To:.*\/devel@monitoring-plugins\.org
30 ! $MATCH
31 }
32
33 # Handle emails that shouldn't be forwarded to the list.
34 :0
35 ! $DEFAULT_RECIPIENT
36}
37
38# vim:set filetype=procmail:
diff --git a/libexec/filter-github-emails b/libexec/filter-github-emails
deleted file mode 100755
index 85ec1a3..0000000
--- a/libexec/filter-github-emails
+++ /dev/null
@@ -1,300 +0,0 @@
1#!/usr/bin/perl -T
2#
3# Copyright (c) 2014 Monitoring Plugins Development Team
4#
5# Originally written by Holger Weiss <holger@zedat.fu-berlin.de>.
6#
7# This program is free software; you may redistribute it and/or modify it under
8# the same terms as Perl itself.
9#
10
11#
12# This script receives GitHub email notifications and tries to distinguish
13# actual user comments from mere status change reports, so that they can be
14# filtered in different ways. While at it, the messages are also modified to
15# make them suitable for being forwarded to a mailing list.
16#
17# Note: If you edit this script, make sure to never use die() or exit().
18# Instead, call the following subroutine:
19#
20# - panic($format, @args);
21# Log an error message, print original message to standard output, exit
22# non-zero. Note that panic() expects printf(3)-style arguments. Don't
23# use variables within the format string (unless you're sure they will
24# never contain format specifications). Add them to the @args instead.
25#
26# Exceptions raised by imported modules should be cought by our $SIG{__DIE__}
27# handler.
28#
29# Also, never write output to STDERR. Instead, use one of the following
30# subroutines in order to write messages to syslog:
31#
32# - debug($format, @args);
33# Write a debug message to syslog, printf(3)-style.
34# - info($format, @args);
35# Write an informational message to syslog, printf(3)-style.
36# - notice($format, @args);
37# Write a notice to syslog, printf(3)-style.
38# - warning($format, @args);
39# Write a warning to syslog, printf(3)-style.
40# - error($format, @args);
41# Write an error to syslog, printf(3)-style.
42# - critical($format, @args);
43# Write a critical error to syslog, printf(3)-style.
44#
45
46use warnings;
47use strict;
48use Email::MIME;
49use File::Basename;
50use Sys::Syslog qw(:standard :macros);
51use Text::Wrap;
52
53use constant COMMENTS_TO =>
54 'Monitoring Plugins Development <devel@monitoring-plugins.org>';
55use constant STATUS_CHANGES_TO =>
56 'Monitoring Plugins Development <devel@monitoring-plugins.org>';
57use constant TIMEOUT => 15;
58
59$ENV{PATH} = '/usr/bin:/bin';
60$" = '';
61
62# Lines will have a length of no more than $columns - 1.
63$Text::Wrap::columns = 77;
64$Text::Wrap::huge = 'overflow';
65
66setlogmask(LOG_UPTO(LOG_INFO));
67openlog(basename($0), 'pid', 'mail');
68
69$SIG{__WARN__} = sub { panic('Caught warning: %s', $_[0] || '(null)') };
70$SIG{__DIE__} = sub { panic('Caught exception: %s', $_[0] || '(null)') };
71$SIG{ALRM} = sub { panic('Timeout after %d seconds', TIMEOUT) };
72$SIG{HUP} = sub { panic('Caught SIGHUP') };
73$SIG{INT} = sub { panic('Caught SIGINT') };
74$SIG{PIPE} = sub { panic('Caught SIGPIPE') };
75$SIG{TERM} = sub { panic('Caught SIGTERM') };
76$SIG{USR1} = sub { panic('Caught SIGUSR1') };
77$SIG{USR2} = sub { panic('Caught SIGUSR2') };
78
79alarm(TIMEOUT);
80
81my $MESSAGE_ID;
82my @MESSAGE = <>; # The complete email message.
83
84#
85# Log and exit.
86#
87
88sub _report {
89 my ($level, $format, @args) = @_;
90
91 chomp(@args);
92 syslog($level, "$format (%s)", @args, $MESSAGE_ID || 'null');
93}
94
95sub debug { _report(LOG_DEBUG, @_) }
96sub info { _report(LOG_INFO, @_) }
97sub notice { _report(LOG_NOTICE, @_) }
98sub warning { _report(LOG_WARNING, @_) }
99sub error { _report(LOG_ERR, @_) }
100sub critical { _report(LOG_CRIT, @_) }
101
102sub panic {
103 $SIG{$_} = 'DEFAULT' for keys %SIG;
104 critical(@_);
105 print @MESSAGE;
106 bye(1);
107}
108
109sub bye {
110 my $status = shift;
111
112 debug('Exiting with status %d', $status);
113 closelog;
114 exit($status);
115}
116
117#
118# Wrap overlong lines.
119#
120
121sub rewrap {
122 my $wrap = sub {
123 my $line = shift;
124 my $indent;
125
126 if ($line =~ /^(?: {4}|\t)/) {
127 return $line;
128 } elsif (/^([> ]+)/) {
129 $indent = $1;
130 } else {
131 $indent = '';
132 }
133 return wrap('', $indent, $line);
134 };
135 my @lines = split(/\n/, shift);
136 my @wrapped = map { $wrap->($_) } @lines;
137
138 debug('Rewrapping text');
139 return join("\n", @wrapped);
140}
141
142#
143# Write the email to STDOUT.
144#
145sub print_email {
146 my $email = shift;
147 my $text = $email->as_string;
148
149 # Email::MIME sometimes prepends an empty line :-/
150 $text =~ s/^[\r\n]+//;
151 print $email->as_string;
152}
153
154#
155# Look up MIME parts.
156#
157
158sub get_part {
159 my ($email, $type) = @_;
160
161 debug('Searching for %s part in email', $type);
162
163 foreach my $part ($email->subparts) {
164 next if $part->subparts;
165 return $part if $part->content_type =~ /\Q$type\E/i;
166 }
167 panic('Cannot find %s part in email', $type);
168}
169
170#
171# Edit a message.
172#
173
174sub edit_header {
175 my ($header, $recipient, $description) = @_;
176
177 debug('Editing header');
178
179 $header->header_set('Lines');
180 $header->header_set('Content-Length');
181 $header->header_set('Reply-To'); # Remove GitHub's reply address.
182 $header->header_set('To' => $recipient);
183 $header->header_set('X-MP-Content' => $description);
184
185 # Strip the [monitoring-plugins] tag.
186 my $subject = $header->header('Subject');
187 $subject =~ s/^\[monitoring-plugins\] (.+)/$1/;
188 $subject =~ s/^Re: \[monitoring-plugins\] (.+)/Re: $1/;
189 $header->header_set('Subject' => $subject);
190
191 return $header;
192}
193
194sub edit_text_body {
195 my $body = shift;
196 my ($s, $r);
197
198 debug('Editing text/plain body');
199
200 $body = rewrap($body); # While at it, wrap overlong lines.
201
202 $s = "\n---\nReply to this email directly or view it on GitHub:";
203 $r = "\n-- \nReply to this email on GitHub:";
204 $body =~ s/$s/$r/;
205
206 return $body;
207}
208
209sub edit_html_body {
210 my $body = shift;
211 my ($s, $r);
212
213 debug('Editing text/html body');
214
215 $s = 'Reply to this email directly or ';
216 $r = '';
217 $body =~ s/$s/$r/;
218
219 $s = 'view it on GitHub';
220 $r = 'Reply to this email on GitHub';
221 $body =~ s/$s/$r/;
222
223 return $body;
224}
225
226#
227# Check message type.
228#
229
230sub is_github_mail {
231 my $email = shift;
232
233 return $email->subparts == 2
234 and defined($email->header('From'))
235 and defined($email->header('X-GitHub-Recipient'))
236 and index($email->header('From'), 'notifications@github.com') != -1
237 and $email->header('X-GitHub-Recipient') eq 'monitoring-user';
238}
239
240sub is_github_status_change {
241 my $email = shift;
242 my $body = get_part($email, 'text/plain')->body_str;
243
244 if ($body =~ tr/\n// == 5) {
245 return 1 if $body =~ /^(?:Closed|Reopened) #\d+\.$/m;
246 return 1 if $body =~ /^Closed #\d+ via [0-9a-f]{40}\.$/m;
247 }
248 return 0;
249}
250
251#
252# Handle message type.
253#
254
255sub handle_github_mail {
256 my $email = shift;
257 my $text = get_part($email, 'text/plain');
258 my $html = get_part($email, 'text/html');
259 my $text_body = $text->body_str;
260 my $html_body = $html->body_str;
261
262 $text->body_str_set(edit_text_body($text_body));
263 $html->body_str_set(edit_html_body($html_body));
264 $email->parts_set([$text, $html]);
265
266 if (is_github_status_change($email)) {
267 info('Received a GitHub status change');
268 $email->header_obj_set(edit_header($email->header_obj,
269 STATUS_CHANGES_TO, 'GitHub status change'));
270 } else {
271 info('Received a GitHub comment');
272 $email->header_obj_set(edit_header($email->header_obj,
273 COMMENTS_TO, 'GitHub comment'));
274 }
275 print_email($email);
276}
277
278sub handle_non_github_mail {
279 my $email = shift;
280
281 notice('Received a non-GitHub message');
282 # Just spit out the email as-is.
283 print_email($email);
284}
285
286#
287# Action!
288#
289
290my $email = Email::MIME->new("@MESSAGE");
291
292$MESSAGE_ID = $email->header('Message-ID') || '(null)';
293$email->header_set('X-MP-Filter' => basename($0));
294
295if (is_github_mail($email)) {
296 handle_github_mail($email);
297} else {
298 handle_non_github_mail($email);
299}
300bye(0);