diff options
Diffstat (limited to 'git-send-email.perl')
-rwxr-xr-x | git-send-email.perl | 94 |
1 files changed, 61 insertions, 33 deletions
diff --git a/git-send-email.perl b/git-send-email.perl index 2fa7818ca9..2be5dac337 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -231,7 +231,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() @@ -645,7 +645,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); } @@ -1330,9 +1330,14 @@ sub file_name_is_absolute { return File::Spec::Functions::file_name_is_absolute($path); } -# Returns 1 if the message was sent, and 0 otherwise. -# In actuality, the whole program dies when there -# is an error sending a message. +# Prepares the email, then asks the user what to do. +# +# If the user chooses to send the email, it's sent and 1 is returned. +# If the user chooses not to send the email, 0 is returned. +# If the user decides they want to make further edits, -1 is returned and the +# caller is expected to call send_message again after the edits are performed. +# +# If an error occurs sending the email, this just dies. sub send_message { my @recipients = unique_email_list(@to); @@ -1404,15 +1409,17 @@ Message-Id: $message_id EOF } - # TRANSLATORS: Make sure to include [y] [n] [q] [a] in your + # TRANSLATORS: Make sure to include [y] [n] [e] [q] [a] in your # translation. The program will only accept English input # at this point. - $_ = ask(__("Send this email? ([y]es|[n]o|[q]uit|[a]ll): "), - valid_re => qr/^(?:yes|y|no|n|quit|q|all|a)/i, + $_ = ask(__("Send this email? ([y]es|[n]o|[e]dit|[q]uit|[a]ll): "), + valid_re => qr/^(?:yes|y|no|n|edit|e|quit|q|all|a)/i, default => $ask_default); die __("Send this email reply required") unless defined $_; if (/^n/i) { return 0; + } elsif (/^e/i) { + return -1; } elsif (/^q/i) { cleanup_compose_files(); exit(0); @@ -1472,7 +1479,7 @@ EOF SSL => 1); } } - else { + elsif (!$smtp) { $smtp_server_port ||= 25; $smtp ||= Net::SMTP->new($smtp_server, Hello => $smtp_domain, @@ -1494,7 +1501,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); @@ -1552,7 +1558,12 @@ $references = $initial_in_reply_to || ''; $subject = $initial_subject; $message_num = 0; -foreach my $t (@files) { +# Prepares the email, prompts the user, sends it out +# Returns 0 if an edit was done and the function should be called again, or 1 +# otherwise. +sub process_file { + my ($t) = @_; + open my $fh, "<", $t or die sprintf(__("can't open file %s"), $t); my $author = undef; @@ -1642,10 +1653,15 @@ foreach my $t (@files) { elsif (/^Content-Transfer-Encoding: (.*)/i) { $xfer_encoding = $1 if not defined $xfer_encoding; } + elsif (/^In-Reply-To: (.*)/i) { + $in_reply_to = $1; + } + elsif (/^References: (.*)/i) { + $references = $1; + } elsif (!/^Date:\s/i && /^[-A-Za-z]+:\s+\S/) { push @xh, $_; } - } else { # In the traditional # "send lots of email" format, @@ -1720,18 +1736,11 @@ foreach my $t (@files) { } } } - 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 @@ -1755,6 +1764,10 @@ foreach my $t (@files) { } my $message_was_sent = send_message(); + if ($message_was_sent == -1) { + do_edit($t); + return 0; + } # set up for the next message if ($thread && $message_was_sent && @@ -1776,6 +1789,14 @@ foreach my $t (@files) { undef $auth; sleep($relogin_delay) if defined $relogin_delay; } + + return 1; +} + +foreach my $t (@files) { + while (!process_file($t)) { + # user edited the file + } } # Execute a command (e.g. $to_cmd) to get a list of email addresses @@ -1823,13 +1844,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"); } @@ -1848,7 +1872,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'), @@ -1868,11 +1892,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; |