Merge branch 'xz/send-email-batch-size'
authorJunio C Hamano <gitster@pobox.com>
Tue, 6 Mar 2018 22:54:02 +0000 (14:54 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 6 Mar 2018 22:54:02 +0000 (14:54 -0800)
"git send-email" learned to complain when the batch-size option is
not defined when the relogin-delay option is, since these two are
mutually required.

* xz/send-email-batch-size:
send-email: error out when relogin delay is missing

1  2 
git-send-email.perl
diff --combined git-send-email.perl
index bbf4deaa0d42ef2a843c2240000d7e34dfff0b62,5bd689958eab2affa3f6fbe66e8ad0c7eb39fe1a..435c7c9e26d75e8f6a4f635753f248fcf8106790
@@@ -25,12 -25,10 +25,12 @@@ use Getopt::Long
  use Text::ParseWords;
  use Term::ANSIColor;
  use File::Temp qw/ tempdir tempfile /;
 -use File::Spec::Functions qw(catfile);
 -use Error qw(:try);
 +use File::Spec::Functions qw(catdir catfile);
 +use Git::Error qw(:try);
 +use Cwd qw(abs_path cwd);
  use Git;
  use Git::I18N;
 +use Git::Mail::Address;
  
  Getopt::Long::Configure qw/ pass_through /;
  
@@@ -156,6 -154,7 +156,6 @@@ sub format_2822_time 
  }
  
  my $have_email_valid = eval { require Email::Valid; 1 };
 -my $have_mail_address = eval { require Mail::Address; 1 };
  my $smtp;
  my $auth;
  my $num_sent = 0;
@@@ -379,6 -378,10 +379,10 @@@ unless ($rc) 
  die __("Cannot run git format-patch from outside a repository\n")
        if $format_patch and not $repo;
  
+ die __("`batch-size` and `relogin` must be specified together " .
+       "(via command-line or configuration option)\n")
+       if defined $relogin_delay and not defined $batch_size;
  # Now, let's fill any that aren't set in with defaults:
  
  sub read_config {
@@@ -490,7 -493,11 +494,7 @@@ my ($repoauthor, $repocommitter)
  ($repocommitter) = Git::ident_person(@repo, 'committer');
  
  sub parse_address_line {
 -      if ($have_mail_address) {
 -              return map { $_->format } Mail::Address->parse($_[0]);
 -      } else {
 -              return Git::parse_mailboxes($_[0]);
 -      }
 +      return map { $_->format } Mail::Address->parse($_[0]);
  }
  
  sub split_addrs {
@@@ -886,9 -893,7 +890,9 @@@ if (defined $initial_reply_to) 
  }
  
  if (!defined $smtp_server) {
 -      foreach (qw( /usr/sbin/sendmail /usr/lib/sendmail )) {
 +      my @sendmail_paths = qw( /usr/sbin/sendmail /usr/lib/sendmail );
 +      push @sendmail_paths, map {"$_/sendmail"} split /:/, $ENV{PATH};
 +      foreach (@sendmail_paths) {
                if (-x $_) {
                        $smtp_server = $_;
                        last;
@@@ -1087,26 -1092,6 +1091,26 @@@ sub sanitize_address 
  
  }
  
 +sub strip_garbage_one_address {
 +      my ($addr) = @_;
 +      chomp $addr;
 +      if ($addr =~ /^(("[^"]*"|[^"<]*)? *<[^>]*>).*/) {
 +              # "Foo Bar" <foobar@example.com> [possibly garbage here]
 +              # Foo Bar <foobar@example.com> [possibly garbage here]
 +              return $1;
 +      }
 +      if ($addr =~ /^(<[^>]*>).*/) {
 +              # <foo@example.com> [possibly garbage here]
 +              # if garbage contains other addresses, they are ignored.
 +              return $1;
 +      }
 +      if ($addr =~ /^([^"#,\s]*)/) {
 +              # address without quoting: remove anything after the address
 +              return $1;
 +      }
 +      return $addr;
 +}
 +
  sub sanitize_address_list {
        return (map { sanitize_address($_) } @_);
  }
                        die __("The required SMTP server is not properly defined.")
                }
  
 +              require Net::SMTP;
 +              my $use_net_smtp_ssl = version->parse($Net::SMTP::VERSION) < version->parse("2.34");
 +              $smtp_domain ||= maildomain();
 +
                if ($smtp_encryption eq 'ssl') {
                        $smtp_server_port ||= 465; # ssmtp
 -                      require Net::SMTP::SSL;
 -                      $smtp_domain ||= maildomain();
                        require IO::Socket::SSL;
  
                        # Suppress "variable accessed once" warning.
                        # Net::SMTP::SSL->new() does not forward any SSL options
                        IO::Socket::SSL::set_client_defaults(
                                ssl_verify_params());
 -                      $smtp ||= Net::SMTP::SSL->new($smtp_server,
 -                                                    Hello => $smtp_domain,
 -                                                    Port => $smtp_server_port,
 -                                                    Debug => $debug_net_smtp);
 +
 +                      if ($use_net_smtp_ssl) {
 +                              require Net::SMTP::SSL;
 +                              $smtp ||= Net::SMTP::SSL->new($smtp_server,
 +                                                            Hello => $smtp_domain,
 +                                                            Port => $smtp_server_port,
 +                                                            Debug => $debug_net_smtp);
 +                      }
 +                      else {
 +                              $smtp ||= Net::SMTP->new($smtp_server,
 +                                                       Hello => $smtp_domain,
 +                                                       Port => $smtp_server_port,
 +                                                       Debug => $debug_net_smtp,
 +                                                       SSL => 1);
 +                      }
                }
                else {
 -                      require Net::SMTP;
 -                      $smtp_domain ||= maildomain();
                        $smtp_server_port ||= 25;
                        $smtp ||= Net::SMTP->new($smtp_server,
                                                 Hello => $smtp_domain,
                                                 Debug => $debug_net_smtp,
                                                 Port => $smtp_server_port);
                        if ($smtp_encryption eq 'tls' && $smtp) {
 -                              require Net::SMTP::SSL;
 -                              $smtp->command('STARTTLS');
 -                              $smtp->response();
 -                              if ($smtp->code == 220) {
 +                              if ($use_net_smtp_ssl) {
 +                                      $smtp->command('STARTTLS');
 +                                      $smtp->response();
 +                                      if ($smtp->code != 220) {
 +                                              die sprintf(__("Server does not support STARTTLS! %s"), $smtp->message);
 +                                      }
 +                                      require Net::SMTP::SSL;
                                        $smtp = Net::SMTP::SSL->start_SSL($smtp,
                                                                          ssl_verify_params())
 -                                              or die "STARTTLS failed! ".IO::Socket::SSL::errstr();
 -                                      $smtp_encryption = '';
 -                                      # Send EHLO again to receive fresh
 -                                      # supported commands
 -                                      $smtp->hello($smtp_domain);
 -                              } else {
 -                                      die sprintf(__("Server does not support STARTTLS! %s"), $smtp->message);
 +                                              or die sprintf(__("STARTTLS failed! %s"), IO::Socket::SSL::errstr());
 +                              }
 +                              else {
 +                                      $smtp->starttls(ssl_verify_params())
 +                                              or die sprintf(__("STARTTLS failed! %s"), IO::Socket::SSL::errstr());
                                }
 +                              $smtp_encryption = '';
 +                              # Send EHLO again to receive fresh
 +                              # supported commands
 +                              $smtp->hello($smtp_domain);
                        }
                }
  
@@@ -1608,12 -1577,10 +1612,12 @@@ foreach my $t (@files) 
        # Now parse the message body
        while(<$fh>) {
                $message .=  $_;
 -              if (/^(Signed-off-by|Cc): ([^>]*>?)/i) {
 +              if (/^(Signed-off-by|Cc): (.*)/i) {
                        chomp;
                        my ($what, $c) = ($1, $2);
 -                      chomp $c;
 +                      # strip garbage for the address we'll use:
 +                      $c = strip_garbage_one_address($c);
 +                      # sanitize a bit more to decide whether to suppress the address:
                        my $sc = sanitize_address($c);
                        if ($sc eq $sender) {
                                next if ($suppress_cc{'self'});
@@@ -1792,25 -1759,6 +1796,25 @@@ sub unique_email_list 
  
  sub validate_patch {
        my $fn = shift;
 +
 +      if ($repo) {
 +              my $validate_hook = catfile(catdir($repo->repo_path(), 'hooks'),
 +                                          'sendemail-validate');
 +              my $hook_error;
 +              if (-x $validate_hook) {
 +                      my $target = abs_path($fn);
 +                      # The hook needs a correct cwd and GIT_DIR.
 +                      my $cwd_save = cwd();
 +                      chdir($repo->wc_path() or $repo->repo_path())
 +                              or die("chdir: $!");
 +                      local $ENV{"GIT_DIR"} = $repo->repo_path();
 +                      $hook_error = "rejected by sendemail-validate hook"
 +                              if system($validate_hook, $target);
 +                      chdir($cwd_save) or die("chdir: $!");
 +              }
 +              return $hook_error if $hook_error;
 +      }
 +
        open(my $fh, '<', $fn)
                or die sprintf(__("unable to open %s: %s\n"), $fn, $!);
        while (my $line = <$fh>) {