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.

Reply via email to