Package: devscripts Version: 2.10.4 Followup-For: Bug #420847 With the attached patch, bts supports direct SMTP. You can specify the SMTP host via the command-line option --smtp-host or via BTS_SMTP_HOST in ~/.devscripts . With no SMTP host specified, or no $EMAIL or $DEBEMAIL specified, bts will use sendmail or mail as it currently does; in the future, perhaps direct SMTP with BTS_SMTP_HOST=bugs.debian.org could become the default, to allow bts to work out-of-the-box for more people. The command line overrides the variables, so --sendmail overrides BTS_SMTP_HOST and --smtp-host overrides BTS_SENDMAIL_COMMAND.
To avoid duplicating the direct SMTP code, the patch factors the current sendmail code out of the two different mail-sending functions in bts.pl, and then adds the new direct SMTP code to the factored function. The patch introduces no new dependencies. It uses Net::SMTP, included in perl-modules. - Josh Triplett -- System Information: Debian Release: lenny/sid APT prefers unstable APT policy: (500, 'unstable'), (1, 'experimental') Architecture: i386 (i686) Kernel: Linux 2.6.22-rc1 (PREEMPT) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/bash Versions of packages devscripts depends on: ii debianutils 2.18 Miscellaneous utilities specific t ii dpkg-dev 1.14.2 package building tools for Debian ii libc6 2.5-7 GNU C Library: Shared libraries ii perl 5.8.8-7 Larry Wall's Practical Extraction ii sed 4.1.5-1 The GNU sed stream editor Versions of packages devscripts recommends: ii fakeroot 1.7.1 Gives a fake root environment -- no debconf information
diff -Naur devscripts-2.10.4.orig/scripts/bts.pl devscripts-2.10.4/scripts/bts.pl --- devscripts-2.10.4.orig/scripts/bts.pl 2007-04-23 10:50:34.000000000 -0700 +++ devscripts-2.10.4/scripts/bts.pl 2007-05-14 19:00:33.000000000 -0700 @@ -5,8 +5,10 @@ # # Written by Joey Hess <[EMAIL PROTECTED]> # Modifications by Julian Gilbey <[EMAIL PROTECTED]> +# Modifications by Josh Triplett <[EMAIL PROTECTED]> # Copyright 2001-2003 Joey Hess <[EMAIL PROTECTED]> # Modifications Copyright 2001-2003 Julian Gilbey <[EMAIL PROTECTED]> +# Modifications Copyright 2007 Josh Triplett <[EMAIL PROTECTED]> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -35,6 +37,7 @@ use File::Path; use File::Spec; use File::Temp qw/tempfile/; +use Net::SMTP; use Cwd; use IO::Handle; use lib '/usr/share/devscripts'; @@ -244,6 +247,15 @@ mailers, if they require a -t option, this must be included in the SENDMAILCMD, for example: --sendmail="/usr/sbin/mymailer -t" +=item --smtp-host=SMTPHOST + +Specify an SMTP host. If given, bts will send mail by talking directly to +this SMTP host rather than by invoking a sendmail command. + +Note that when sending directly via an SMTP host, specifying addresses in +--cc-addr that the SMTP host will not relay will cause the SMTP host to reject +the entire mail. + =item -f, --force-refresh Download a bug report again, even if it does not appear to have @@ -285,6 +297,7 @@ my $updatemode=0; my $mailreader='mutt -f %s'; my $sendmailcmd='/usr/sbin/sendmail'; +my $smtphost=''; # regexp for mailers which require a -t option my $sendmail_t='^/usr/sbin/sendmail$|^/usr/sbin/exim'; @@ -304,6 +317,7 @@ 'BTS_ONLY_NEW' => 'no', 'BTS_MAIL_READER' => 'mutt -f %s', 'BTS_SENDMAIL_COMMAND' => '/usr/sbin/sendmail', + 'BTS_SMTP_HOST' => '', ); my %config_default = %config_vars; @@ -335,7 +349,8 @@ $config_vars{'BTS_SENDMAIL_COMMAND'} =~ /./ or $config_vars{'BTS_SENDMAIL_COMMAND'}='/usr/sbin/sendmail'; - if ($config_vars{'BTS_SENDMAIL_COMMAND'} ne '/usr/sbin/sendmail') { + if (!length $config_vars{'BTS_SMTP_HOST'} + and $config_vars{'BTS_SENDMAIL_COMMAND'} ne '/usr/sbin/sendmail') { my $cmd = (split ' ', $config_vars{'BTS_SENDMAIL_COMMAND'})[0]; unless ($cmd =~ /^[A-Za-z0-9_\-\+\.\/]*$/) { warn "BTS_SENDMAIL_COMMAND contained funny characters: $cmd\nReverting to default value /usr/sbin/sendmail\n"; @@ -361,6 +376,7 @@ $updatemode = $config_vars{'BTS_ONLY_NEW'} eq 'yes' ? 1 : 0; $mailreader = $config_vars{'BTS_MAIL_READER'}; $sendmailcmd = $config_vars{'BTS_SENDMAIL_COMMAND'}; + $smtphost = $config_vars{'BTS_SMTP_HOST'}; } if (exists $ENV{'BUGSOFFLINE'}) { @@ -368,7 +384,7 @@ } my ($opt_help, $opt_version, $opt_noconf); -my ($opt_cachemode, $opt_mailreader, $opt_sendmail); +my ($opt_cachemode, $opt_mailreader, $opt_sendmail, $opt_smtphost); my $opt_cachedelay=5; my $mboxmode = 0; my $quiet=0; @@ -387,6 +403,7 @@ "mailreader|mail-reader=s" => \$opt_mailreader, "cc-addr=s" => \$ccemail, "sendmail=s" => \$opt_sendmail, + "smtp-host=s" => \$opt_smtphost, "f" => \$refreshmode, "force-refresh!" => \$refreshmode, "only-new!" => \$updatemode, @@ -409,6 +426,12 @@ } } +if ($opt_sendmail and $opt_smtphost) { + die 'bts: --sendmail and --smtp-host mutually exclusive'; +} + +$smtphost = $opt_smtphost if $opt_smtphost; + if ($opt_sendmail) { if ($opt_sendmail ne '/usr/sbin/sendmail' and $opt_sendmail ne $sendmailcmd) { @@ -422,7 +445,11 @@ } } } -$sendmailcmd = $opt_sendmail if $opt_sendmail; + +if ($opt_sendmail) { + $sendmailcmd = $opt_sendmail; + $smtphost = ''; +} if ($opt_cachemode) { if ($opt_cachemode =~ /^(min|mbox|full)$/) { @@ -1517,6 +1544,7 @@ $progname version $version Copyright (C) 2001-2003 by Joey Hess <[EMAIL PROTECTED]>. Modifications Copyright (C) 2002-2004 by Julian Gilbey <[EMAIL PROTECTED]>. +Modifications Copyright (C) 2007 by Josh Triplett <[EMAIL PROTECTED]>. It is licensed under the terms of the GPL, either version 2 of the License, or (at your option) any later version. EOF @@ -1560,6 +1588,7 @@ ones --no-force-refresh Don\'t do so (default) --sendmail=cmd Sendmail command to use (default /usr/sbin/sendmail) + --smtp-host=host SMTP host to use --help, -h Display this message --version, -v Display version and copyright info @@ -1635,6 +1664,84 @@ $body .= "$_[1]\n"; } +# Extract an array of email addresses from a string +sub extract_addresses { + my $s = shift; + my @addresses; + + # Original regular expression from git-send-email, slightly modified + while ($s =~ /([^,<>"[EMAIL PROTECTED]@[^.,<>"[EMAIL PROTECTED](?:\.[^.,<>"[EMAIL PROTECTED])+)(.*)/) { + push @addresses, $1; + $s = $2; + } + return @addresses; +} + +# Send one full mail message using the smtphost or sendmail. +sub send_mail { + my ($from, $to, $cc, $subject, $body) = @_; + + my @fromaddresses = extract_addresses($from); + my $fromaddress = $fromaddresses[0]; + # Message-ID algorithm from git-send-email + my $msgid = sprintf("%s-%s", time(), int(rand(4200)))."-bts-$fromaddress"; + my $date = `date -R`; + chomp $date; + + my $message = fold_from_header("From: $from") . "\n"; + $message .= "To: $to\n" if length $to; + $message .= "Cc: $cc\n" if length $cc; + $message .= "Subject: $subject\n" + . "Date: $date\n" + . "X-BTS-Version: $version\n" + . "Message-ID: <$msgid>\n" + . "\n" + . "# Automatically generated email from bts," + . " devscripts version $version\n" + . "$body\n"; + + if (length $smtphost) { + my $smtp = Net::SMTP->new($smtphost) + or die "bts: failed to open SMTP connection to $smtphost"; + $smtp->mail($fromaddress) + or die "bts: failed to set SMTP from address $fromaddress"; + my @addresses = extract_addresses($to); + push @addresses, extract_addresses($cc); + foreach my $address (@addresses) { + $smtp->recipient($address) + or die "bts: failed to set SMTP recipient $address"; + } + $smtp->data($message) + or die "bts: failed to send message as SMTP DATA"; + $smtp->quit + or die "bts: failed to quit SMTP connection"; + } + else { + my $pid = open(MAIL, "|-"); + if (! defined $pid) { + die "bts: Couldn't fork: $!\n"; + } + $SIG{'PIPE'} = sub { die "bts: pipe for $sendmailcmd broke\n"; }; + if ($pid) { + # parent + print MAIL $message; + close MAIL or die "bts: sendmail error: $!\n"; + } + else { + # child + if ($debug) { + exec("/bin/cat") + or die "bts: error running cat: $!\n"; + } else { + my @mailcmd = split ' ', $sendmailcmd; + push @mailcmd, "-t" if $sendmailcmd =~ /$sendmail_t/; + exec @mailcmd + or die "bts: error running sendmail: $!\n"; + } + } + } +} + # Sends all cached mail to the bts (duh). sub mailbtsall { my $subject=shift; @@ -1668,43 +1775,9 @@ my $charset = `locale charmap`; chomp $charset; $charset =~ s/^ANSI_X3\.4-19(68|86)$/US-ASCII/; - my $fromline = fold_from_header("From: " . - MIME_encode_mimewords($from, 'Charset' => $charset)); - my $date = `date -R`; - chomp $date; + $from = MIME_encode_mimewords($from, 'Charset' => $charset); - my $pid = open(MAIL, "|-"); - if (! defined $pid) { - die "bts: Couldn't fork: $!\n"; - } - $SIG{'PIPE'} = sub { die "bts: pipe for $sendmailcmd broke\n"; }; - if ($pid) { - # parent - print MAIL <<"EOM"; -$fromline -To: $btsemail -Cc: $ccemail -Subject: $subject -Date: $date -X-BTS-Version: $version - -# Automatically generated email from bts, devscripts version $version -$body -EOM - close MAIL or die "bts: sendmail error: $!\n"; - } - else { - # child - if ($debug) { - exec("/bin/cat") - or die "bts: error running cat: $!\n"; - } else { - my @mailcmd = split ' ', $sendmailcmd; - push @mailcmd, "-t" if $sendmailcmd =~ /$sendmail_t/; - exec @mailcmd - or die "bts: error running sendmail: $!\n"; - } - } + send_mail($from, $btsemail, $ccemail, $subject, $body); } else { # No DEBEMAIL unless (system("command -v mail >/dev/null 2>&1") == 0) { @@ -1740,40 +1813,7 @@ my ($subject, $body, $to, $from) = @_; if (defined $from) { - my $date = `date -R`; - chomp $date; - - my $pid = open(MAIL, "|-"); - if (! defined $pid) { - die "bts: Couldn't fork: $!\n"; - } - $SIG{'PIPE'} = sub { die "bts: pipe for $sendmailcmd broke\n"; }; - if ($pid) { - # parent - print MAIL <<"EOM"; -From: $from -To: $to -Subject: $subject -Date: $date -X-BTS-Version: $version - -# Automatically generated email from bts, devscripts version $version -$body -EOM - close MAIL or die "bts: sendmail error: $!\n"; - } - else { - # child - if ($debug) { - exec("/bin/cat") - or die "bts: error running cat: $!\n"; - } else { - my @mailcmd = split ' ', $sendmailcmd; - push @mailcmd, "-t" if $sendmailcmd =~ /$sendmail_t/; - exec @mailcmd - or die "bts: error running sendmail: $!\n"; - } - } + send_mail($from, $to, '', $subject, $body); } else { # No $from unless (system("command -v mail >/dev/null 2>&1") == 0) { @@ -2929,7 +2969,8 @@ This program is Copyright (C) 2001-2003 by Joey Hess <[EMAIL PROTECTED]>. Many modifications have been made, Copyright (C) 2002-2005 Julian -Gilbey <[EMAIL PROTECTED]>. +Gilbey <[EMAIL PROTECTED]> and Copyright (C) 2007 Josh Triplett +<[EMAIL PROTECTED]>. It is licensed under the terms of the GPL, either version 2 of the License, or (at your option) any later version.