X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=git-send-email.perl;h=8cc416115569e38317e63d1638d361d579518b73;hb=e7cf4e94c6f147953af4d079ca2e9ef0d7a29ae9;hp=111c981229bf2c0bc6afa4a22db011b68d93fdfa;hpb=339aec7acbd43f831ffc7dd193f53a34f918d4fb;p=git.git diff --git a/git-send-email.perl b/git-send-email.perl index 111c98122..8cc416115 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -24,6 +24,7 @@ use Text::ParseWords; use Data::Dumper; use Term::ANSIColor; use File::Temp qw/ tempdir tempfile /; +use File::Spec::Functions qw(catfile); use Error qw(:try); use Git; @@ -54,6 +55,7 @@ git send-email [options] --in-reply-to * Email "In-Reply-To:" --annotate * Review each patch that will be sent in an editor. --compose * Open an editor for introduction. + --8bit-encoding * Encoding to assume 8bit mails if undeclared Sending: --envelope-sender * Email envelope sender. @@ -84,6 +86,7 @@ git send-email [options] --[no-]validate * Perform patch sanity checks. Default on. --[no-]format-patch * understand any non optional arguments as `git format-patch` ones. + --force * Send even if safety checks would prevent it. EOT exit(1); @@ -161,6 +164,7 @@ if ($@) { my ($quiet, $dry_run) = (0, 0); my $format_patch; my $compose_filename; +my $force = 0; # Handle interactive edition of files. my $multiedit; @@ -191,6 +195,7 @@ my ($smtp_server, $smtp_server_port, $smtp_authuser, $smtp_encryption); my ($identity, $aliasfiletype, @alias_files, @smtp_host_parts, $smtp_domain); my ($validate, $confirm); my (@suppress_cc); +my ($auto_8bit_encoding); my ($debug_net_smtp) = 0; # Net::SMTP, see send_message() @@ -222,6 +227,7 @@ my %config_settings = ( "multiedit" => \$multiedit, "confirm" => \$confirm, "from" => \$sender, + "assume8bitencoding" => \$auto_8bit_encoding, ); # Help users prepare for 1.7.0 @@ -297,6 +303,8 @@ my $rc = GetOptions("sender|from=s" => \$sender, "thread!" => \$thread, "validate!" => \$validate, "format-patch!" => \$format_patch, + "8bit-encoding=s" => \$auto_8bit_encoding, + "force" => \$force, ); unless ($rc) { @@ -507,7 +515,7 @@ while (defined(my $f = shift @ARGV)) { opendir(DH,$f) or die "Failed to opendir $f: $!"; - push @files, grep { -f $_ } map { +$f . "/" . $_ } + push @files, grep { -f $_ } map { catfile($f, $_) } sort readdir(DH); closedir(DH); } elsif ((-f $f or -p $f) and !check_file_rev_conflict($f)) { @@ -669,6 +677,45 @@ sub ask { return undef; } +my %broken_encoding; + +sub file_declares_8bit_cte($) { + my $fn = shift; + open (my $fh, '<', $fn); + while (my $line = <$fh>) { + last if ($line =~ /^$/); + return 1 if ($line =~ /^Content-Transfer-Encoding: .*8bit.*$/); + } + close $fh; + return 0; +} + +foreach my $f (@files) { + next unless (body_or_subject_has_nonascii($f) + && !file_declares_8bit_cte($f)); + $broken_encoding{$f} = 1; +} + +if (!defined $auto_8bit_encoding && scalar %broken_encoding) { + print "The following files are 8bit, but do not declare " . + "a Content-Transfer-Encoding.\n"; + foreach my $f (sort keys %broken_encoding) { + print " $f\n"; + } + $auto_8bit_encoding = ask("Which 8bit encoding should I declare [UTF-8]? ", + default => "UTF-8"); +} + +if (!$force) { + for my $f (@files) { + if (get_patch_subject($f) =~ /\*\*\* SUBJECT HERE \*\*\*/) { + die "Refusing to send because the patch\n\t$f\n" + . "has the template subject '*** SUBJECT HERE ***'. " + . "Pass --force if you really want to send.\n"; + } + } +} + my $prompting = 0; if (!defined $sender) { $sender = $repoauthor || $repocommitter || ''; @@ -862,7 +909,7 @@ sub sanitize_address { sub valid_fqdn { my $domain = shift; - return !($^O eq 'darwin' && $domain =~ /\.local$/) && $domain =~ /\./; + return defined $domain && !($^O eq 'darwin' && $domain =~ /\.local$/) && $domain =~ /\./; } sub maildomain_net { @@ -1221,6 +1268,18 @@ foreach my $t (@files) { or die "(cc-cmd) failed to close pipe to '$cc_cmd'"; } + if ($broken_encoding{$t} && !$has_content_type) { + $has_content_type = 1; + push @xh, "MIME-Version: 1.0", + "Content-Type: text/plain; charset=$auto_8bit_encoding", + "Content-Transfer-Encoding: 8bit"; + $body_encoding = $auto_8bit_encoding; + } + + if ($broken_encoding{$t} && !is_rfc2047_quoted($subject)) { + $subject = quote_rfc2047($subject, $auto_8bit_encoding); + } + if (defined $author and $author ne $sender) { $message = "From: $author\n\n$message"; if (defined $author_encoding) { @@ -1233,6 +1292,7 @@ foreach my $t (@files) { } } else { + $has_content_type = 1; push @xh, 'MIME-Version: 1.0', "Content-Type: text/plain; charset=$author_encoding", @@ -1310,3 +1370,17 @@ sub file_has_nonascii { } return 0; } + +sub body_or_subject_has_nonascii { + my $fn = shift; + open(my $fh, '<', $fn) + or die "unable to open $fn: $!\n"; + while (my $line = <$fh>) { + last if $line =~ /^$/; + return 1 if $line =~ /^Subject.*[^[:ascii:]]/; + } + while (my $line = <$fh>) { + return 1 if $line =~ /[^[:ascii:]]/; + } + return 0; +}