aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Bugzilla/BugMail.pm167
-rw-r--r--Bugzilla/Flag.pm4
-rw-r--r--Bugzilla/Mailer.pm211
-rw-r--r--Bugzilla/Token.pm10
-rwxr-xr-xeditproducts.cgi6
-rwxr-xr-ximportxml.pl5
-rwxr-xr-xprocess_bug.cgi6
-rwxr-xr-xrelogin.cgi4
-rwxr-xr-xwhine.pl4
-rwxr-xr-xwhineatnews.pl4
10 files changed, 234 insertions, 187 deletions
diff --git a/Bugzilla/BugMail.pm b/Bugzilla/BugMail.pm
index 74e1145a7..ab8ca2f6f 100644
--- a/Bugzilla/BugMail.pm
+++ b/Bugzilla/BugMail.pm
@@ -39,15 +39,10 @@ use Bugzilla::Config qw(:DEFAULT $datadir);
use Bugzilla::Util;
use Bugzilla::Bug;
use Bugzilla::Component;
+use Bugzilla::Mailer;
use Date::Parse;
use Date::Format;
-use Mail::Mailer;
-use Mail::Header;
-use MIME::Base64;
-use MIME::QuotedPrint;
-use MIME::Parser;
-use Mail::Address;
use constant BIT_DIRECT => 1;
use constant BIT_WATCHING => 2;
@@ -670,166 +665,6 @@ sub sendMail {
return 1;
}
-sub MessageToMTA {
- my ($msg) = (@_);
- return if (Param('mail_delivery_method') eq "none");
-
- my ($header, $body) = $msg =~ /(.*?\n)\n(.*)/s ? ($1, $2) : ('', $msg);
- my $headers;
-
- if (Param('utf8') and (!is_7bit_clean($header) or !is_7bit_clean($body))) {
- ($headers, $body) = encode_message($msg);
- } else {
- my @header_lines = split(/\n/, $header);
- $headers = new Mail::Header \@header_lines, Modify => 0;
- }
-
- # Use trim to remove any whitespace (incl. newlines)
- my $from = trim($headers->get('from'));
-
- if (Param("mail_delivery_method") eq "sendmail" && $^O =~ /MSWin32/i) {
- my $cmd = '|' . SENDMAIL_EXE . ' -t -i';
- if ($from) {
- # We're on Windows, thus no danger of command injection
- # via $from. In other words, it is safe to embed $from.
- $cmd .= qq# -f"$from"#;
- }
- open(SENDMAIL, $cmd) ||
- die "Failed to execute " . SENDMAIL_EXE . ": $!\n";
- print SENDMAIL $headers->as_string;
- print SENDMAIL "\n";
- print SENDMAIL $body;
- close SENDMAIL;
- return;
- }
-
- my @args;
- if (Param("mail_delivery_method") eq "sendmail") {
- push @args, "-i";
- if ($from) {
- push(@args, "-f$from");
- }
- }
- if (Param("mail_delivery_method") eq "sendmail" && !Param("sendmailnow")) {
- push @args, "-ODeliveryMode=deferred";
- }
- if (Param("mail_delivery_method") eq "smtp") {
- push @args, Server => Param("smtpserver");
- if ($from) {
- $ENV{'MAILADDRESS'} = $from;
- }
- }
- my $mailer = new Mail::Mailer Param("mail_delivery_method"), @args;
- if (Param("mail_delivery_method") eq "testfile") {
- $Mail::Mailer::testfile::config{outfile} = "$datadir/mailer.testfile";
- }
-
- $mailer->open($headers->header_hashref);
- print $mailer $body;
- $mailer->close;
-}
-
-sub encode_qp_words {
- my ($line) = (@_);
- my @encoded;
- foreach my $word (split / /, $line) {
- if (!is_7bit_clean($word)) {
- push @encoded, '=?UTF-8?Q?_' . encode_qp($word, '') . '?=';
- } else {
- push @encoded, $word;
- }
- }
- return join(' ', @encoded);
-}
-
-sub encode_message {
- my ($msg) = @_;
-
- my $parser = MIME::Parser->new;
- $parser->output_to_core(1);
- $parser->tmp_to_core(1);
- my $entity = $parser->parse_data($msg);
- $entity = encode_message_entity($entity);
-
- my @header_lines = split(/\n/, $entity->header_as_string);
- my $head = new Mail::Header \@header_lines, Modify => 0;
-
- my $body = $entity->body_as_string;
-
- return ($head, $body);
-}
-
-sub encode_message_entity {
- my ($entity) = @_;
-
- my $head = $entity->head;
-
- # encode the subject
-
- my $subject = $head->get('subject');
- if (defined $subject && !is_7bit_clean($subject)) {
- $subject =~ s/[\r\n]+$//;
- $head->replace('subject', encode_qp_words($subject));
- }
-
- # encode addresses
-
- foreach my $field (qw(from to cc reply-to sender errors-to)) {
- my $high = $head->count($field) - 1;
- foreach my $index (0..$high) {
- my $value = $head->get($field, $index);
- my @addresses;
- my $changed = 0;
- foreach my $addr (Mail::Address->parse($value)) {
- my $phrase = $addr->phrase;
- if (is_7bit_clean($phrase)) {
- push @addresses, $addr->format;
- } else {
- push @addresses, encode_qp_phrase($phrase) .
- ' <' . $addr->address . '>';
- $changed = 1;
- }
- }
- $changed && $head->replace($field, join(', ', @addresses), $index);
- }
- }
-
- # process the body
-
- if (scalar($entity->parts)) {
- my $newparts = [];
- foreach my $part ($entity->parts) {
- my $newpart = encode_message_entity($part);
- push @$newparts, $newpart;
- }
- $entity->parts($newparts);
- }
- else {
- # Extract the body from the entity, for examination
- # At this point, we can rely on MIME::Tools to do our encoding for us!
- my $bodyhandle = $entity->bodyhandle;
- my $body = $bodyhandle->as_string;
- if (!is_7bit_clean($body)) {
- # count number of 7-bit chars, and use quoted-printable if more
- # than half the message is 7-bit clean
- my $count = ($body =~ tr/\x20-\x7E\x0A\x0D//);
- if ($count > length($body) / 2) {
- $head->mime_attr('Content-Transfer-Encoding' => 'quoted-printable');
- } else {
- $head->mime_attr('Content-Transfer-Encoding' => 'base64');
- }
- }
-
- # Set the content/type and charset of the part, if not set
- $head->mime_attr('Content-Type' => 'text/plain')
- unless defined $head->mime_attr('content-type');
- $head->mime_attr('Content-Type.charset' => 'UTF-8');
- }
-
- $head->fold(75);
- return $entity;
-}
-
# Send the login name and password of the newly created account to the user.
sub MailPassword {
my ($login, $password) = (@_);
diff --git a/Bugzilla/Flag.pm b/Bugzilla/Flag.pm
index 1d4f1ebe9..ef8ecd867 100644
--- a/Bugzilla/Flag.pm
+++ b/Bugzilla/Flag.pm
@@ -65,7 +65,7 @@ use Bugzilla::Config;
use Bugzilla::Util;
use Bugzilla::Error;
use Bugzilla::Attachment;
-use Bugzilla::BugMail;
+use Bugzilla::Mailer;
use Bugzilla::Constants;
use Bugzilla::Field;
@@ -903,7 +903,7 @@ sub notify {
ThrowTemplateError($template->error());
}
- Bugzilla::BugMail::MessageToMTA($message);
+ MessageToMTA($message);
}
}
diff --git a/Bugzilla/Mailer.pm b/Bugzilla/Mailer.pm
new file mode 100644
index 000000000..05ef82149
--- /dev/null
+++ b/Bugzilla/Mailer.pm
@@ -0,0 +1,211 @@
+# -*- Mode: perl; indent-tabs-mode: nil -*-
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code is the Bugzilla Bug Tracking System.
+#
+# The Initial Developer of the Original Code is Netscape Communications
+# Corporation. Portions created by Netscape are
+# Copyright (C) 1998 Netscape Communications Corporation. All
+# Rights Reserved.
+#
+# Contributor(s): Terry Weissman <terry@mozilla.org>,
+# Bryce Nesbitt <bryce-mozilla@nextbus.com>
+# Dan Mosedale <dmose@mozilla.org>
+# Alan Raetz <al_raetz@yahoo.com>
+# Jacob Steenhagen <jake@actex.net>
+# Matthew Tuck <matty@chariot.net.au>
+# Bradley Baetz <bbaetz@student.usyd.edu.au>
+# J. Paul Reed <preed@sigkill.com>
+# Gervase Markham <gerv@gerv.net>
+# Byron Jones <bugzilla@glob.com.au>
+# Frédéric Buclin <LpSolit@gmail.com>
+
+package Bugzilla::Mailer;
+
+use strict;
+
+use base qw(Exporter);
+@Bugzilla::Mailer::EXPORT = qw(MessageToMTA);
+
+use Bugzilla::Constants;
+use Bugzilla::Config qw(:DEFAULT $datadir);
+use Bugzilla::Util;
+
+use Mail::Header;
+use Mail::Mailer;
+use Mail::Address;
+use MIME::Parser;
+use MIME::QuotedPrint;
+use MIME::Base64;
+
+
+sub MessageToMTA {
+ my ($msg) = (@_);
+ return if (Param('mail_delivery_method') eq "none");
+
+ my ($header, $body) = $msg =~ /(.*?\n)\n(.*)/s ? ($1, $2) : ('', $msg);
+ my $headers;
+
+ if (Param('utf8') and (!is_7bit_clean($header) or !is_7bit_clean($body))) {
+ ($headers, $body) = encode_message($msg);
+ } else {
+ my @header_lines = split(/\n/, $header);
+ $headers = new Mail::Header \@header_lines, Modify => 0;
+ }
+
+ # Use trim to remove any whitespace (incl. newlines)
+ my $from = trim($headers->get('from'));
+
+ if (Param("mail_delivery_method") eq "sendmail" && $^O =~ /MSWin32/i) {
+ my $cmd = '|' . SENDMAIL_EXE . ' -t -i';
+ if ($from) {
+ # We're on Windows, thus no danger of command injection
+ # via $from. In other words, it is safe to embed $from.
+ $cmd .= qq# -f"$from"#;
+ }
+ open(SENDMAIL, $cmd) ||
+ die "Failed to execute " . SENDMAIL_EXE . ": $!\n";
+ print SENDMAIL $headers->as_string;
+ print SENDMAIL "\n";
+ print SENDMAIL $body;
+ close SENDMAIL;
+ return;
+ }
+
+ my @args;
+ if (Param("mail_delivery_method") eq "sendmail") {
+ push @args, "-i";
+ if ($from) {
+ push(@args, "-f$from");
+ }
+ }
+ if (Param("mail_delivery_method") eq "sendmail" && !Param("sendmailnow")) {
+ push @args, "-ODeliveryMode=deferred";
+ }
+ if (Param("mail_delivery_method") eq "smtp") {
+ push @args, Server => Param("smtpserver");
+ if ($from) {
+ $ENV{'MAILADDRESS'} = $from;
+ }
+ }
+ my $mailer = new Mail::Mailer Param("mail_delivery_method"), @args;
+ if (Param("mail_delivery_method") eq "testfile") {
+ $Mail::Mailer::testfile::config{outfile} = "$datadir/mailer.testfile";
+ }
+
+ $mailer->open($headers->header_hashref);
+ print $mailer $body;
+ $mailer->close;
+}
+
+sub encode_message {
+ my ($msg) = @_;
+
+ my $parser = MIME::Parser->new;
+ $parser->output_to_core(1);
+ $parser->tmp_to_core(1);
+ my $entity = $parser->parse_data($msg);
+ $entity = encode_message_entity($entity);
+
+ my @header_lines = split(/\n/, $entity->header_as_string);
+ my $head = new Mail::Header \@header_lines, Modify => 0;
+
+ my $body = $entity->body_as_string;
+
+ return ($head, $body);
+}
+
+sub encode_message_entity {
+ my ($entity) = @_;
+
+ my $head = $entity->head;
+
+ # encode the subject
+
+ my $subject = $head->get('subject');
+ if (defined $subject && !is_7bit_clean($subject)) {
+ $subject =~ s/[\r\n]+$//;
+ $head->replace('subject', encode_qp_words($subject));
+ }
+
+ # encode addresses
+
+ foreach my $field (qw(from to cc reply-to sender errors-to)) {
+ my $high = $head->count($field) - 1;
+ foreach my $index (0..$high) {
+ my $value = $head->get($field, $index);
+ my @addresses;
+ my $changed = 0;
+ foreach my $addr (Mail::Address->parse($value)) {
+ my $phrase = $addr->phrase;
+ if (is_7bit_clean($phrase)) {
+ push @addresses, $addr->format;
+ } else {
+ push @addresses, encode_qp_phrase($phrase) .
+ ' <' . $addr->address . '>';
+ $changed = 1;
+ }
+ }
+ $changed && $head->replace($field, join(', ', @addresses), $index);
+ }
+ }
+
+ # process the body
+
+ if (scalar($entity->parts)) {
+ my $newparts = [];
+ foreach my $part ($entity->parts) {
+ my $newpart = encode_message_entity($part);
+ push @$newparts, $newpart;
+ }
+ $entity->parts($newparts);
+ }
+ else {
+ # Extract the body from the entity, for examination
+ # At this point, we can rely on MIME::Tools to do our encoding for us!
+ my $bodyhandle = $entity->bodyhandle;
+ my $body = $bodyhandle->as_string;
+ if (!is_7bit_clean($body)) {
+ # count number of 7-bit chars, and use quoted-printable if more
+ # than half the message is 7-bit clean
+ my $count = ($body =~ tr/\x20-\x7E\x0A\x0D//);
+ if ($count > length($body) / 2) {
+ $head->mime_attr('Content-Transfer-Encoding' => 'quoted-printable');
+ } else {
+ $head->mime_attr('Content-Transfer-Encoding' => 'base64');
+ }
+ }
+
+ # Set the content/type and charset of the part, if not set
+ $head->mime_attr('Content-Type' => 'text/plain')
+ unless defined $head->mime_attr('content-type');
+ $head->mime_attr('Content-Type.charset' => 'UTF-8');
+ }
+
+ $head->fold(75);
+ return $entity;
+}
+
+sub encode_qp_words {
+ my ($line) = (@_);
+ my @encoded;
+ foreach my $word (split / /, $line) {
+ if (!is_7bit_clean($word)) {
+ push @encoded, '=?UTF-8?Q?_' . encode_qp($word, '') . '?=';
+ } else {
+ push @encoded, $word;
+ }
+ }
+ return join(' ', @encoded);
+}
+
+1;
diff --git a/Bugzilla/Token.pm b/Bugzilla/Token.pm
index cd03f9747..3cb4d6ffc 100644
--- a/Bugzilla/Token.pm
+++ b/Bugzilla/Token.pm
@@ -31,7 +31,7 @@ package Bugzilla::Token;
use Bugzilla::Config;
use Bugzilla::Error;
-use Bugzilla::BugMail;
+use Bugzilla::Mailer;
use Bugzilla::Util;
use Date::Format;
@@ -76,7 +76,7 @@ sub IssueEmailChangeToken {
$template->process("account/email/change-old.txt.tmpl", $vars, \$message)
|| ThrowTemplateError($template->error());
- Bugzilla::BugMail::MessageToMTA($message);
+ MessageToMTA($message);
$vars->{'token'} = $newtoken;
$vars->{'emailaddress'} = $new_email . Param('emailsuffix');
@@ -85,7 +85,7 @@ sub IssueEmailChangeToken {
$template->process("account/email/change-new.txt.tmpl", $vars, \$message)
|| ThrowTemplateError($template->error());
- Bugzilla::BugMail::MessageToMTA($message);
+ MessageToMTA($message);
}
# Generates a random token, adds it to the tokens table, and sends it
@@ -125,7 +125,7 @@ sub IssuePasswordToken {
$vars, \$message)
|| ThrowTemplateError($template->error());
- Bugzilla::BugMail::MessageToMTA($message);
+ MessageToMTA($message);
}
sub IssueSessionToken {
@@ -213,7 +213,7 @@ sub Cancel {
$template->process("account/cancel-token.txt.tmpl", $vars, \$message)
|| ThrowTemplateError($template->error());
- Bugzilla::BugMail::MessageToMTA($message);
+ MessageToMTA($message);
# Delete the token from the database.
DeleteToken($token);
diff --git a/editproducts.cgi b/editproducts.cgi
index 942375688..8fc074ef2 100755
--- a/editproducts.cgi
+++ b/editproducts.cgi
@@ -39,7 +39,7 @@ require "globals.pl";
use Bugzilla::Bug;
use Bugzilla::Series;
use Bugzilla::Config qw(:DEFAULT $datadir);
-use Bugzilla::BugMail;
+use Bugzilla::Mailer;
use Bugzilla::Product;
use Bugzilla::Classification;
use Bugzilla::Milestone;
@@ -905,7 +905,7 @@ if ($action eq 'update') {
"has changed;\nyou had too many votes " .
"for a single bug.");
foreach my $msg (@$msgs) {
- Bugzilla::BugMail::MessageToMTA($msg);
+ MessageToMTA($msg);
}
my $name = DBID_to_name($who);
@@ -958,7 +958,7 @@ if ($action eq 'update') {
"too many\ntotal votes, so all " .
"votes have been removed.");
foreach my $msg (@$msgs) {
- Bugzilla::BugMail::MessageToMTA($msg);
+ MessageToMTA($msg);
}
my $name = DBID_to_name($who);
diff --git a/importxml.pl b/importxml.pl
index 08be03e5a..c1cdc56b6 100755
--- a/importxml.pl
+++ b/importxml.pl
@@ -81,6 +81,7 @@ use Bugzilla::Milestone;
use Bugzilla::FlagType;
use Bugzilla::Config qw(:DEFAULT $datadir);
use Bugzilla::BugMail;
+use Bugzilla::Mailer;
use Bugzilla::User;
use Bugzilla::Util;
use Bugzilla::Constants;
@@ -153,7 +154,7 @@ sub MailMessage {
$header .= "From: Bugzilla <$from>\n";
$header .= "Subject: $subject\n\n";
my $sendmessage = $header . $message . "\n";
- Bugzilla::BugMail::MessageToMTA($sendmessage);
+ MessageToMTA($sendmessage);
}
}
@@ -1198,7 +1199,7 @@ Debug( "Reading xml", DEBUG_LEVEL );
local ($/);
$xml = <>;
-# If the email was encoded (BugMail::MessageToMTA() does it when using UTF-8),
+# If the email was encoded (Mailer::MessageToMTA() does it when using UTF-8),
# we have to decode it first, else the XML parsing will fail.
my $parser = MIME::Parser->new;
$parser->output_to_core(1);
diff --git a/process_bug.cgi b/process_bug.cgi
index 7c52254ee..9773dce6d 100755
--- a/process_bug.cgi
+++ b/process_bug.cgi
@@ -52,7 +52,7 @@ require "globals.pl";
use Bugzilla;
use Bugzilla::Constants;
use Bugzilla::Bug;
-use Bugzilla::BugMail;
+use Bugzilla::Mailer;
use Bugzilla::User;
use Bugzilla::Util;
use Bugzilla::Field;
@@ -743,7 +743,7 @@ if ($action eq Param('move-button-text')) {
|| ThrowTemplateError($template->error());
$msg .= "\n";
- Bugzilla::BugMail::MessageToMTA($msg);
+ MessageToMTA($msg);
# End the response page.
$template->process("bug/navigate.html.tmpl", $vars)
@@ -2137,7 +2137,7 @@ foreach my $id (@idlist) {
# Now is a good time to send email to voters.
foreach my $msg (@$msgs) {
- Bugzilla::BugMail::MessageToMTA($msg);
+ MessageToMTA($msg);
}
if ($duplicate) {
diff --git a/relogin.cgi b/relogin.cgi
index 0385b8e2f..418ed3555 100755
--- a/relogin.cgi
+++ b/relogin.cgi
@@ -28,7 +28,7 @@ use lib qw(.);
require "globals.pl";
use Bugzilla;
-use Bugzilla::BugMail;
+use Bugzilla::Mailer;
use Bugzilla::Constants;
use Bugzilla::Error;
use Bugzilla::Token;
@@ -163,7 +163,7 @@ elsif ($action eq 'begin-sudo') {
$template->process('email/sudo.txt.tmpl',
{ reason => $reason },
\$message);
- Bugzilla::BugMail::MessageToMTA($message);
+ MessageToMTA($message);
$vars->{'message'} = 'sudo_started';
$vars->{'target'} = $target_user->login;
diff --git a/whine.pl b/whine.pl
index 7e4ec5285..9f5a9acfe 100755
--- a/whine.pl
+++ b/whine.pl
@@ -33,7 +33,7 @@ use Bugzilla::Config qw(:DEFAULT $datadir);
use Bugzilla::Constants;
use Bugzilla::Search;
use Bugzilla::User;
-use Bugzilla::BugMail;
+use Bugzilla::Mailer;
use Bugzilla::Util;
# create some handles that we'll need
@@ -406,7 +406,7 @@ sub mail {
$template->process("whine/multipart-mime.txt.tmpl", $args, \$msg)
or die($template->error());
- Bugzilla::BugMail::MessageToMTA($msg);
+ MessageToMTA($msg);
delete $args->{'boundary'};
delete $args->{'alternatives'};
diff --git a/whineatnews.pl b/whineatnews.pl
index 62e6388ac..c3f0a7677 100755
--- a/whineatnews.pl
+++ b/whineatnews.pl
@@ -33,7 +33,7 @@ use lib '.';
require "globals.pl";
use Bugzilla;
-use Bugzilla::BugMail;
+use Bugzilla::Mailer;
use Bugzilla::Util;
# Whining is disabled if whinedays is zero
@@ -83,7 +83,7 @@ foreach my $email (sort (keys %bugs)) {
$msg .= " -> ${urlbase}show_bug.cgi?id=$i\n";
}
- Bugzilla::BugMail::MessageToMTA($msg);
+ MessageToMTA($msg);
print "$email " . join(" ", @{$bugs{$email}}) . "\n";
}