diff options
Diffstat (limited to 'git-send-email.perl')
-rwxr-xr-x | git-send-email.perl | 91 |
1 files changed, 56 insertions, 35 deletions
diff --git a/git-send-email.perl b/git-send-email.perl index 8ec70e58ed..8eb63b5a2f 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -82,8 +82,11 @@ git send-email --dump-aliases Pass an empty string to disable certificate verification. --smtp-domain <str> * The domain name sent to HELO/EHLO handshake - --smtp-auth <str> * Space-separated list of allowed AUTH mechanisms. + --smtp-auth <str> * Space-separated list of allowed AUTH mechanisms, or + "none" to disable authentication. This setting forces to use one of the listed mechanisms. + --no-smtp-auth Disable SMTP authentication. Shorthand for + `--smtp-auth=none` --smtp-debug <0|1> * Disable, enable Net::SMTP debug. --batch-size <int> * send max <int> message per connection. @@ -94,7 +97,7 @@ git send-email --dump-aliases --identity <str> * Use the sendemail.<id> options. --to-cmd <str> * Email To: via `<str> \$patch_path` --cc-cmd <str> * Email Cc: via `<str> \$patch_path` - --suppress-cc <str> * author, self, sob, cc, cccmd, body, bodycc, all. + --suppress-cc <str> * author, self, sob, cc, cccmd, body, bodycc, misc-by, all. --[no-]cc-cover * Email Cc: addresses in the cover letter. --[no-]to-cover * Email To: addresses in the cover letter. --[no-]signed-off-by-cc * Send to Signed-off-by: addresses. Default on. @@ -119,6 +122,11 @@ EOT exit(1); } +sub completion_helper { + print Git::command('format-patch', '--git-completion-helper'); + exit(0); +} + # most mail servers generate the Date: header, but not all... sub format_2822_time { my ($time) = @_; @@ -231,7 +239,7 @@ my ($validate, $confirm); my (@suppress_cc); my ($auto_8bit_encoding); my ($compose_encoding); -my ($target_xfer_encoding); +my $target_xfer_encoding = 'auto'; my ($debug_net_smtp) = 0; # Net::SMTP, see send_message() @@ -311,6 +319,7 @@ $SIG{INT} = \&signal_handler; # needing, first, from the command line: my $help; +my $git_completion_helper; my $rc = GetOptions("h" => \$help, "dump-aliases" => \$dump_aliases); usage() unless $rc; @@ -341,6 +350,7 @@ $rc = GetOptions( "smtp-debug:i" => \$debug_net_smtp, "smtp-domain:s" => \$smtp_domain, "smtp-auth=s" => \$smtp_auth, + "no-smtp-auth" => sub {$smtp_auth = 'none'}, "identity=s" => \$identity, "annotate!" => \$annotate, "no-annotate" => sub {$annotate = 0}, @@ -373,9 +383,11 @@ $rc = GetOptions( "no-xmailer" => sub {$use_xmailer = 0}, "batch-size=i" => \$batch_size, "relogin-delay=i" => \$relogin_delay, + "git-completion-helper" => \$git_completion_helper, ); usage() if $help; +completion_helper() if $git_completion_helper; unless ($rc) { usage(); } @@ -454,13 +466,13 @@ my(%suppress_cc); if (@suppress_cc) { foreach my $entry (@suppress_cc) { die sprintf(__("Unknown --suppress-cc field: '%s'\n"), $entry) - unless $entry =~ /^(?:all|cccmd|cc|author|self|sob|body|bodycc)$/; + unless $entry =~ /^(?:all|cccmd|cc|author|self|sob|body|bodycc|misc-by)$/; $suppress_cc{$entry} = 1; } } if ($suppress_cc{'all'}) { - foreach my $entry (qw (cccmd cc author self sob body bodycc)) { + foreach my $entry (qw (cccmd cc author self sob body bodycc misc-by)) { $suppress_cc{$entry} = 1; } delete $suppress_cc{'all'}; @@ -471,7 +483,7 @@ $suppress_cc{'self'} = $suppress_from if defined $suppress_from; $suppress_cc{'sob'} = !$signed_off_by_cc if defined $signed_off_by_cc; if ($suppress_cc{'body'}) { - foreach my $entry (qw (sob bodycc)) { + foreach my $entry (qw (sob bodycc misc-by)) { $suppress_cc{$entry} = 1; } delete $suppress_cc{'body'}; @@ -645,7 +657,7 @@ if (@rev_list_opts) { if ($validate) { foreach my $f (@files) { unless (-p $f) { - my $error = validate_patch($f); + my $error = validate_patch($f, $target_xfer_encoding); $error and die sprintf(__("fatal: %s: %s\nwarning: no patches were sent\n"), $f, $error); } @@ -1241,7 +1253,7 @@ sub smtp_host_string { # (smtp_user was not specified), and 0 otherwise. sub smtp_auth_maybe { - if (!defined $smtp_authuser || $auth) { + if (!defined $smtp_authuser || $auth || (defined $smtp_auth && $smtp_auth eq "none")) { return 1; } @@ -1479,7 +1491,7 @@ EOF SSL => 1); } } - else { + elsif (!$smtp) { $smtp_server_port ||= 25; $smtp ||= Net::SMTP->new($smtp_server, Hello => $smtp_domain, @@ -1501,7 +1513,6 @@ EOF $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); @@ -1682,7 +1693,7 @@ sub process_file { # Now parse the message body while(<$fh>) { $message .= $_; - if (/^(Signed-off-by|Cc): (.*)/i) { + if (/^([a-z-]*-by|Cc): (.*)/i) { chomp; my ($what, $c) = ($1, $2); # strip garbage for the address we'll use: @@ -1692,8 +1703,18 @@ sub process_file { if ($sc eq $sender) { next if ($suppress_cc{'self'}); } else { - next if $suppress_cc{'sob'} and $what =~ /Signed-off-by/i; - next if $suppress_cc{'bodycc'} and $what =~ /Cc/i; + if ($what =~ /^Signed-off-by$/i) { + next if $suppress_cc{'sob'}; + } elsif ($what =~ /-by$/i) { + next if $suppress_cc{'misc-by'}; + } elsif ($what =~ /Cc/i) { + next if $suppress_cc{'bodycc'}; + } + } + if ($c !~ /.+@.+|<.+>/) { + printf("(body) Ignoring %s from line '%s'\n", + $what, $_) unless $quiet; + next; } push @cc, $c; printf(__("(body) Adding cc: %s from line '%s'\n"), @@ -1737,18 +1758,11 @@ sub process_file { } } } - if (defined $target_xfer_encoding) { - $xfer_encoding = '8bit' if not defined $xfer_encoding; - $message = apply_transfer_encoding( - $message, $xfer_encoding, $target_xfer_encoding); - $xfer_encoding = $target_xfer_encoding; - } - if (defined $xfer_encoding) { - push @xh, "Content-Transfer-Encoding: $xfer_encoding"; - } - if (defined $xfer_encoding or $has_content_type) { - unshift @xh, 'MIME-Version: 1.0' unless $has_mime_version; - } + $xfer_encoding = '8bit' if not defined $xfer_encoding; + ($message, $xfer_encoding) = apply_transfer_encoding( + $message, $xfer_encoding, $target_xfer_encoding); + push @xh, "Content-Transfer-Encoding: $xfer_encoding"; + unshift @xh, 'MIME-Version: 1.0' unless $has_mime_version; $needs_confirm = ( $confirm eq "always" or @@ -1842,7 +1856,7 @@ sub apply_transfer_encoding { my $from = shift; my $to = shift; - return $message if ($from eq $to and $from ne '7bit'); + return ($message, $to) if ($from eq $to and $from ne '7bit'); require MIME::QuotedPrint; require MIME::Base64; @@ -1852,13 +1866,16 @@ sub apply_transfer_encoding { $message = MIME::Base64::decode($message) if ($from eq 'base64'); + $to = ($message =~ /.{999,}/) ? 'quoted-printable' : '8bit' + if $to eq 'auto'; + die __("cannot send message as 7bit") if ($to eq '7bit' and $message =~ /[^[:ascii:]]/); - return $message + return ($message, $to) if ($to eq '7bit' or $to eq '8bit'); - return MIME::QuotedPrint::encode($message, "\n", 0) + return (MIME::QuotedPrint::encode($message, "\n", 0), $to) if ($to eq 'quoted-printable'); - return MIME::Base64::encode($message, "\n") + return (MIME::Base64::encode($message, "\n"), $to) if ($to eq 'base64'); die __("invalid transfer encoding"); } @@ -1877,7 +1894,7 @@ sub unique_email_list { } sub validate_patch { - my $fn = shift; + my ($fn, $xfer_encoding) = @_; if ($repo) { my $validate_hook = catfile(catdir($repo->repo_path(), 'hooks'), @@ -1897,11 +1914,15 @@ sub validate_patch { return $hook_error if $hook_error; } - open(my $fh, '<', $fn) - or die sprintf(__("unable to open %s: %s\n"), $fn, $!); - while (my $line = <$fh>) { - if (length($line) > 998) { - return sprintf(__("%s: patch contains a line longer than 998 characters"), $.); + # Any long lines will be automatically fixed if we use a suitable transfer + # encoding. + unless ($xfer_encoding =~ /^(?:auto|quoted-printable|base64)$/) { + open(my $fh, '<', $fn) + or die sprintf(__("unable to open %s: %s\n"), $fn, $!); + while (my $line = <$fh>) { + if (length($line) > 998) { + return sprintf(__("%s: patch contains a line longer than 998 characters"), $.); + } } } return; |