Merge branch 'ew/email' into next

* ew/email:
  send-email: lazy-load Email::Valid and make it optional
  send-email: try to order messages in email clients more correctly
  send-email: Change from Mail::Sendmail to Net::SMTP
  send-email: use built-in time() instead of /bin/date '+%s'
This commit is contained in:
Junio C Hamano 2006-03-25 17:44:09 -08:00
commit dad7230a1c

View File

@ -19,10 +19,16 @@
use strict; use strict;
use warnings; use warnings;
use Term::ReadLine; use Term::ReadLine;
use Mail::Sendmail qw(sendmail %mailcfg);
use Getopt::Long; use Getopt::Long;
use Data::Dumper; use Data::Dumper;
use Email::Valid; use Net::SMTP;
# most mail servers generate the Date: header, but not all...
$ENV{LC_ALL} = 'C';
use POSIX qw/strftime/;
my $have_email_valid = eval { require Email::Valid; 1 };
my $smtp;
sub unique_email_list(@); sub unique_email_list(@);
sub cleanup_compose_files(); sub cleanup_compose_files();
@ -31,7 +37,7 @@ sub cleanup_compose_files();
my $compose_filename = ".msg.$$"; my $compose_filename = ".msg.$$";
# Variables we fill in automatically, or via prompting: # Variables we fill in automatically, or via prompting:
my (@to,@cc,@initial_cc,$initial_reply_to,$initial_subject,@files,$from,$compose); my (@to,@cc,@initial_cc,$initial_reply_to,$initial_subject,@files,$from,$compose,$time);
# Behavior modification variables # Behavior modification variables
my ($chain_reply_to, $smtp_server, $quiet, $suppress_from, $no_signed_off_cc) = (1, "localhost", 0, 0, 0); my ($chain_reply_to, $smtp_server, $quiet, $suppress_from, $no_signed_off_cc) = (1, "localhost", 0, 0, 0);
@ -244,6 +250,16 @@ EOT
# Variables we set as part of the loop over files # Variables we set as part of the loop over files
our ($message_id, $cc, %mail, $subject, $reply_to, $message); our ($message_id, $cc, %mail, $subject, $reply_to, $message);
sub extract_valid_address {
my $address = shift;
if ($have_email_valid) {
return Email::Valid->address($address);
} else {
# less robust/correct than the monster regexp in Email::Valid,
# but still does a 99% job, and one less dependency
return ($address =~ /([^\"<>\s]+@[^<>\s]+)/);
}
}
# Usually don't need to change anything below here. # Usually don't need to change anything below here.
@ -253,13 +269,12 @@ our ($message_id, $cc, %mail, $subject, $reply_to, $message);
# 1 second since the last time we were called. # 1 second since the last time we were called.
# We'll setup a template for the message id, using the "from" address: # We'll setup a template for the message id, using the "from" address:
my $message_id_from = Email::Valid->address($from); my $message_id_from = extract_valid_address($from);
my $message_id_template = "<%s-git-send-email-$message_id_from>"; my $message_id_template = "<%s-git-send-email-$message_id_from>";
sub make_message_id sub make_message_id
{ {
my $date = `date "+\%s"`; my $date = time;
chomp($date);
my $pseudo_rand = int (rand(4200)); my $pseudo_rand = int (rand(4200));
$message_id = sprintf $message_id_template, "$date$pseudo_rand"; $message_id = sprintf $message_id_template, "$date$pseudo_rand";
#print "new message id = $message_id\n"; # Was useful for debugging #print "new message id = $message_id\n"; # Was useful for debugging
@ -268,38 +283,49 @@ sub make_message_id
$cc = ""; $cc = "";
$time = time - scalar $#files;
sub send_message sub send_message
{ {
my $to = join (", ", unique_email_list(@to)); my @recipients = unique_email_list(@to);
my $to = join (",\n\t", @recipients);
@recipients = unique_email_list(@recipients,@cc);
my $date = strftime('%a, %d %b %Y %H:%M:%S %z', localtime($time++));
%mail = ( To => $to, my $header = "From: $from
From => $from, To: $to
CC => $cc, Cc: $cc
Subject => $subject, Subject: $subject
Message => $message, Reply-To: $from
'Reply-to' => $from, Date: $date
'In-Reply-To' => $reply_to, Message-Id: $message_id
'Message-ID' => $message_id, X-Mailer: git-send-email @@GIT_VERSION@@
'X-Mailer' => "git-send-email", ";
); $header .= "In-Reply-To: $reply_to\n" if $reply_to;
$mail{smtp} = $smtp_server; $smtp ||= Net::SMTP->new( $smtp_server );
$mailcfg{mime} = 0; $smtp->mail( $from ) or die $smtp->message;
$smtp->to( @recipients ) or die $smtp->message;
#print Data::Dumper->Dump([\%mail],[qw(*mail)]); $smtp->data or die $smtp->message;
$smtp->datasend("$header\n$message") or die $smtp->message;
sendmail(%mail) or die $Mail::Sendmail::error; $smtp->dataend() or die $smtp->message;
$smtp->ok or die "Failed to send $subject\n".$smtp->message;
if ($quiet) { if ($quiet) {
printf "Sent %s\n", $subject; printf "Sent %s\n", $subject;
} else { } else {
print "OK. Log says:\n", $Mail::Sendmail::log; print "OK. Log says:
print "\n\n" Date: $date
Server: $smtp_server Port: 25
From: $from
Subject: $subject
Cc: $cc
To: $to
Result: ", $smtp->code, ' ', ($smtp->message =~ /\n([^\n]+\n)$/s), "\n";
} }
} }
$reply_to = $initial_reply_to; $reply_to = $initial_reply_to;
make_message_id(); make_message_id();
$subject = $initial_subject; $subject = $initial_subject;
@ -390,14 +416,14 @@ sub cleanup_compose_files() {
} }
$smtp->quit if $smtp;
sub unique_email_list(@) { sub unique_email_list(@) {
my %seen; my %seen;
my @emails; my @emails;
foreach my $entry (@_) { foreach my $entry (@_) {
my $clean = Email::Valid->address($entry); my $clean = extract_valid_address($entry);
next if $seen{$clean}++; next if $seen{$clean}++;
push @emails, $entry; push @emails, $entry;
} }