summaryrefslogtreecommitdiff
path: root/git-send-email.perl
diff options
context:
space:
mode:
Diffstat (limited to 'git-send-email.perl')
-rwxr-xr-xgit-send-email.perl347
1 files changed, 215 insertions, 132 deletions
diff --git a/git-send-email.perl b/git-send-email.perl
index 2fa7818ca9..dc95656f75 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) = @_;
@@ -169,11 +177,15 @@ my $re_encoded_text = qr/[^? \000-\037\177-\377]+/;
my $re_encoded_word = qr/=\?($re_token)\?($re_token)\?($re_encoded_text)\?=/;
# Variables we fill in automatically, or via prompting:
-my (@to,$no_to,@initial_to,@cc,$no_cc,@initial_cc,@bcclist,$no_bcc,@xh,
+my (@to,@cc,@xh,$envelope_sender,
$initial_in_reply_to,$reply_to,$initial_subject,@files,
- $author,$sender,$smtp_authpass,$annotate,$use_xmailer,$compose,$time);
-
-my $envelope_sender;
+ $author,$sender,$smtp_authpass,$annotate,$compose,$time);
+# Things we either get from config, *or* are overridden on the
+# command-line.
+my ($no_cc, $no_to, $no_bcc, $no_identity);
+my (@config_to, @getopt_to);
+my (@config_cc, @getopt_cc);
+my (@config_bcc, @getopt_bcc);
# Example reply to:
#$initial_in_reply_to = ''; #<20050203173208.GA23964@foobar.com>';
@@ -220,33 +232,37 @@ sub do_edit {
}
# Variables with corresponding config settings
-my ($thread, $chain_reply_to, $suppress_from, $signed_off_by_cc);
+my ($suppress_from, $signed_off_by_cc);
my ($cover_cc, $cover_to);
my ($to_cmd, $cc_cmd);
my ($smtp_server, $smtp_server_port, @smtp_server_options);
my ($smtp_authuser, $smtp_encryption, $smtp_ssl_cert_path);
my ($batch_size, $relogin_delay);
my ($identity, $aliasfiletype, @alias_files, $smtp_domain, $smtp_auth);
-my ($validate, $confirm);
+my ($confirm);
my (@suppress_cc);
my ($auto_8bit_encoding);
my ($compose_encoding);
-my ($target_xfer_encoding);
-
+# Variables with corresponding config settings & hardcoded defaults
my ($debug_net_smtp) = 0; # Net::SMTP, see send_message()
+my $thread = 1;
+my $chain_reply_to = 0;
+my $use_xmailer = 1;
+my $validate = 1;
+my $target_xfer_encoding = 'auto';
my %config_bool_settings = (
- "thread" => [\$thread, 1],
- "chainreplyto" => [\$chain_reply_to, 0],
- "suppressfrom" => [\$suppress_from, undef],
- "signedoffbycc" => [\$signed_off_by_cc, undef],
- "cccover" => [\$cover_cc, undef],
- "tocover" => [\$cover_to, undef],
- "signedoffcc" => [\$signed_off_by_cc, undef], # Deprecated
- "validate" => [\$validate, 1],
- "multiedit" => [\$multiedit, undef],
- "annotate" => [\$annotate, undef],
- "xmailer" => [\$use_xmailer, 1]
+ "thread" => \$thread,
+ "chainreplyto" => \$chain_reply_to,
+ "suppressfrom" => \$suppress_from,
+ "signedoffbycc" => \$signed_off_by_cc,
+ "cccover" => \$cover_cc,
+ "tocover" => \$cover_to,
+ "signedoffcc" => \$signed_off_by_cc,
+ "validate" => \$validate,
+ "multiedit" => \$multiedit,
+ "annotate" => \$annotate,
+ "xmailer" => \$use_xmailer,
);
my %config_settings = (
@@ -259,12 +275,12 @@ my %config_settings = (
"smtpauth" => \$smtp_auth,
"smtpbatchsize" => \$batch_size,
"smtprelogindelay" => \$relogin_delay,
- "to" => \@initial_to,
+ "to" => \@config_to,
"tocmd" => \$to_cmd,
- "cc" => \@initial_cc,
+ "cc" => \@config_cc,
"cccmd" => \$cc_cmd,
"aliasfiletype" => \$aliasfiletype,
- "bcc" => \@bcclist,
+ "bcc" => \@config_bcc,
"suppresscc" => \@suppress_cc,
"envelopesender" => \$envelope_sender,
"confirm" => \$confirm,
@@ -307,12 +323,87 @@ sub signal_handler {
$SIG{TERM} = \&signal_handler;
$SIG{INT} = \&signal_handler;
+# Read our sendemail.* config
+sub read_config {
+ my ($configured, $prefix) = @_;
+
+ foreach my $setting (keys %config_bool_settings) {
+ my $target = $config_bool_settings{$setting};
+ my $v = Git::config_bool(@repo, "$prefix.$setting");
+ next unless defined $v;
+ next if $configured->{$setting}++;
+ $$target = $v;
+ }
+
+ foreach my $setting (keys %config_path_settings) {
+ my $target = $config_path_settings{$setting};
+ if (ref($target) eq "ARRAY") {
+ my @values = Git::config_path(@repo, "$prefix.$setting");
+ next unless @values;
+ next if $configured->{$setting}++;
+ @$target = @values;
+ }
+ else {
+ my $v = Git::config_path(@repo, "$prefix.$setting");
+ next unless defined $v;
+ next if $configured->{$setting}++;
+ $$target = $v;
+ }
+ }
+
+ foreach my $setting (keys %config_settings) {
+ my $target = $config_settings{$setting};
+ if (ref($target) eq "ARRAY") {
+ my @values = Git::config(@repo, "$prefix.$setting");
+ next unless @values;
+ next if $configured->{$setting}++;
+ @$target = @values;
+ }
+ else {
+ my $v = Git::config(@repo, "$prefix.$setting");
+ next unless defined $v;
+ next if $configured->{$setting}++;
+ $$target = $v;
+ }
+ }
+
+ if (!defined $smtp_encryption) {
+ my $setting = "$prefix.smtpencryption";
+ my $enc = Git::config(@repo, $setting);
+ return unless defined $enc;
+ return if $configured->{$setting}++;
+ if (defined $enc) {
+ $smtp_encryption = $enc;
+ } elsif (Git::config_bool(@repo, "$prefix.smtpssl")) {
+ $smtp_encryption = 'ssl';
+ }
+ }
+}
+
+# sendemail.identity yields to --identity. We must parse this
+# special-case first before the rest of the config is read.
+$identity = Git::config(@repo, "sendemail.identity");
+my $rc = GetOptions(
+ "identity=s" => \$identity,
+ "no-identity" => \$no_identity,
+);
+usage() unless $rc;
+undef $identity if $no_identity;
+
+# Now we know enough to read the config
+{
+ my %configured;
+ read_config(\%configured, "sendemail.$identity") if defined $identity;
+ read_config(\%configured, "sendemail");
+}
+
# Begin by accumulating all the variables (defined above), that we will end up
# needing, first, from the command line:
my $help;
-my $rc = GetOptions("h" => \$help,
- "dump-aliases" => \$dump_aliases);
+my $git_completion_helper;
+$rc = GetOptions("h" => \$help,
+ "dump-aliases" => \$dump_aliases);
usage() unless $rc;
die __("--dump-aliases incompatible with other options\n")
if !$help and $dump_aliases and @ARGV;
@@ -321,12 +412,12 @@ $rc = GetOptions(
"in-reply-to=s" => \$initial_in_reply_to,
"reply-to=s" => \$reply_to,
"subject=s" => \$initial_subject,
- "to=s" => \@initial_to,
+ "to=s" => \@getopt_to,
"to-cmd=s" => \$to_cmd,
"no-to" => \$no_to,
- "cc=s" => \@initial_cc,
+ "cc=s" => \@getopt_cc,
"no-cc" => \$no_cc,
- "bcc=s" => \@bcclist,
+ "bcc=s" => \@getopt_bcc,
"no-bcc" => \$no_bcc,
"chain-reply-to!" => \$chain_reply_to,
"no-chain-reply-to" => sub {$chain_reply_to = 0},
@@ -341,7 +432,7 @@ $rc = GetOptions(
"smtp-debug:i" => \$debug_net_smtp,
"smtp-domain:s" => \$smtp_domain,
"smtp-auth=s" => \$smtp_auth,
- "identity=s" => \$identity,
+ "no-smtp-auth" => sub {$smtp_auth = 'none'},
"annotate!" => \$annotate,
"no-annotate" => sub {$annotate = 0},
"compose" => \$compose,
@@ -373,9 +464,16 @@ $rc = GetOptions(
"no-xmailer" => sub {$use_xmailer = 0},
"batch-size=i" => \$batch_size,
"relogin-delay=i" => \$relogin_delay,
+ "git-completion-helper" => \$git_completion_helper,
);
+# Munge any "either config or getopt, not both" variables
+my @initial_to = @getopt_to ? @getopt_to : ($no_to ? () : @config_to);
+my @initial_cc = @getopt_cc ? @getopt_cc : ($no_cc ? () : @config_cc);
+my @initial_bcc = @getopt_bcc ? @getopt_bcc : ($no_bcc ? () : @config_bcc);
+
usage() if $help;
+completion_helper() if $git_completion_helper;
unless ($rc) {
usage();
}
@@ -387,65 +485,6 @@ 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 {
- my ($prefix) = @_;
-
- foreach my $setting (keys %config_bool_settings) {
- my $target = $config_bool_settings{$setting}->[0];
- $$target = Git::config_bool(@repo, "$prefix.$setting") unless (defined $$target);
- }
-
- foreach my $setting (keys %config_path_settings) {
- my $target = $config_path_settings{$setting};
- if (ref($target) eq "ARRAY") {
- unless (@$target) {
- my @values = Git::config_path(@repo, "$prefix.$setting");
- @$target = @values if (@values && defined $values[0]);
- }
- }
- else {
- $$target = Git::config_path(@repo, "$prefix.$setting") unless (defined $$target);
- }
- }
-
- foreach my $setting (keys %config_settings) {
- my $target = $config_settings{$setting};
- next if $setting eq "to" and defined $no_to;
- next if $setting eq "cc" and defined $no_cc;
- next if $setting eq "bcc" and defined $no_bcc;
- if (ref($target) eq "ARRAY") {
- unless (@$target) {
- my @values = Git::config(@repo, "$prefix.$setting");
- @$target = @values if (@values && defined $values[0]);
- }
- }
- else {
- $$target = Git::config(@repo, "$prefix.$setting") unless (defined $$target);
- }
- }
-
- if (!defined $smtp_encryption) {
- my $enc = Git::config(@repo, "$prefix.smtpencryption");
- if (defined $enc) {
- $smtp_encryption = $enc;
- } elsif (Git::config_bool(@repo, "$prefix.smtpssl")) {
- $smtp_encryption = 'ssl';
- }
- }
-}
-
-# read configuration from [sendemail "$identity"], fall back on [sendemail]
-$identity = Git::config(@repo, "sendemail.identity") unless (defined $identity);
-read_config("sendemail.$identity") if (defined $identity);
-read_config("sendemail");
-
-# fall back on builtin bool defaults
-foreach my $setting (values %config_bool_settings) {
- ${$setting->[0]} = $setting->[1] unless (defined (${$setting->[0]}));
-}
-
# 'default' encryption is none -- this only prevents a warning
$smtp_encryption = '' unless (defined $smtp_encryption);
@@ -453,14 +492,16 @@ $smtp_encryption = '' unless (defined $smtp_encryption);
my(%suppress_cc);
if (@suppress_cc) {
foreach my $entry (@suppress_cc) {
+ # Please update $__git_send_email_suppresscc_options
+ # in git-completion.bash when you add new options.
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 +512,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'};
@@ -482,6 +523,8 @@ my $confirm_unconfigured = !defined $confirm;
if ($confirm_unconfigured) {
$confirm = scalar %suppress_cc ? 'compose' : 'auto';
};
+# Please update $__git_send_email_confirm_options in
+# git-completion.bash when you add new options.
die sprintf(__("Unknown --confirm setting: '%s'\n"), $confirm)
unless $confirm =~ /^(?:auto|cc|compose|always|never)/;
@@ -575,6 +618,8 @@ my %parse_alias = (
if (/\(define-mail-alias\s+"(\S+?)"\s+"(\S+?)"\)/) {
$aliases{$1} = [ $2 ];
}}}
+ # Please update _git_config() in git-completion.bash when you
+ # add new MUAs.
);
if (@alias_files and $aliasfiletype and defined $parse_alias{$aliasfiletype}) {
@@ -645,7 +690,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);
}
@@ -923,7 +968,7 @@ sub expand_one_alias {
@initial_to = process_address_list(@initial_to);
@initial_cc = process_address_list(@initial_cc);
-@bcclist = process_address_list(@bcclist);
+@initial_bcc = process_address_list(@initial_bcc);
if ($thread && !defined $initial_in_reply_to && $prompting) {
$initial_in_reply_to = ask(
@@ -1183,7 +1228,7 @@ sub process_address_list {
# domain name that corresponds the IP address in the HELO/EHLO
# handshake. This is used to verify the connection and prevent
# spammers from trying to hide their identity. If the DNS and IP don't
-# match, the receiveing MTA may deny the connection.
+# match, the receiving MTA may deny the connection.
#
# Here is a deny example of Net::SMTP with the default "localhost.localdomain"
#
@@ -1241,7 +1286,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;
}
@@ -1330,9 +1375,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);
@@ -1341,7 +1391,7 @@ sub send_message {
}
@cc);
my $to = join (",\n\t", @recipients);
- @recipients = unique_email_list(@recipients,@cc,@bcclist);
+ @recipients = unique_email_list(@recipients,@cc,@initial_bcc);
@recipients = (map { extract_valid_address_or_die($_) } @recipients);
my $date = format_2822_time($time++);
my $gitversion = '@@GIT_VERSION@@';
@@ -1404,15 +1454,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 +1524,7 @@ EOF
SSL => 1);
}
}
- else {
+ elsif (!$smtp) {
$smtp_server_port ||= 25;
$smtp ||= Net::SMTP->new($smtp_server,
Hello => $smtp_domain,
@@ -1494,7 +1546,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 +1603,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 +1698,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,
@@ -1665,7 +1726,7 @@ foreach my $t (@files) {
# Now parse the message body
while(<$fh>) {
$message .= $_;
- if (/^(Signed-off-by|Cc): (.*)/i) {
+ if (/^([a-z][a-z-]*-by|Cc): (.*)/i) {
chomp;
my ($what, $c) = ($1, $2);
# strip garbage for the address we'll use:
@@ -1675,8 +1736,18 @@ foreach my $t (@files) {
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"),
@@ -1720,18 +1791,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 +1819,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 +1844,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
@@ -1813,7 +1889,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;
@@ -1823,13 +1899,16 @@ sub apply_transfer_encoding {
$message = MIME::Base64::decode($message)
if ($from eq 'base64');
+ $to = ($message =~ /(?:.{999,}|\r)/) ? '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 +1927,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 +1947,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;