--envelope-sender Specify the envelope sender used to send the emails.
+ --no-validate Don't perform any sanity checks on patches.
+
EOT
exit(1);
}
my $have_email_valid = eval { require Email::Valid; 1 };
my $smtp;
+my $auth;
sub unique_email_list(@);
sub cleanup_compose_files();
my ($thread, $chain_reply_to, $suppress_from, $signed_off_cc, $cc_cmd);
my ($smtp_server, $smtp_server_port, $smtp_authuser, $smtp_authpass, $smtp_ssl);
my ($identity, $aliasfiletype, @alias_files, @smtp_host_parts);
+my ($no_validate);
my %config_bool_settings = (
"thread" => [\$thread, 1],
"dry-run" => \$dry_run,
"envelope-sender=s" => \$envelope_sender,
"thread!" => \$thread,
+ "no-validate" => \$no_validate,
);
unless ($rc) {
($sender) = expand_aliases($sender) if defined $sender;
+# Now that all the defaults are set, process the rest of the command line
+# arguments and collect up the files that need to be processed.
+for my $f (@ARGV) {
+ if (-d $f) {
+ opendir(DH,$f)
+ or die "Failed to opendir $f: $!";
+
+ push @files, grep { -f $_ } map { +$f . "/" . $_ }
+ sort readdir(DH);
+
+ } elsif (-f $f) {
+ push @files, $f;
+
+ } else {
+ print STDERR "Skipping $f - not found.\n";
+ }
+}
+
+if (!$no_validate) {
+ foreach my $f (@files) {
+ my $error = validate_patch($f);
+ $error and die "fatal: $f: $error\nwarning: no patches were sent\n";
+ }
+}
+
+if (@files) {
+ unless ($quiet) {
+ print $_,"\n" for (@files);
+ }
+} else {
+ print STDERR "\nNo patch files specified!\n\n";
+ usage();
+}
+
my $prompting = 0;
if (!defined $sender) {
$sender = $repoauthor || $repocommitter;
} while (!defined $_);
$initial_reply_to = $_;
- $initial_reply_to =~ s/^\s+<?/</;
- $initial_reply_to =~ s/>?\s+$/>/;
+}
+if (defined $initial_reply_to && $_ ne "") {
+ $initial_reply_to =~ s/^\s*<?/</;
+ $initial_reply_to =~ s/>?\s*$/>/;
}
if (!defined $smtp_server) {
close(C);
my $editor = $ENV{GIT_EDITOR} || $repo->config("core.editor") || $ENV{VISUAL} || $ENV{EDITOR} || "vi";
- system($editor, $compose_filename);
+ system('sh', '-c', '$0 $@', $editor, $compose_filename);
open(C2,">",$compose_filename . ".final")
or die "Failed to open $compose_filename.final : " . $!;
exit(0);
}
- @files = ($compose_filename . ".final");
-}
-
-
-# Now that all the defaults are set, process the rest of the command line
-# arguments and collect up the files that need to be processed.
-for my $f (@ARGV) {
- if (-d $f) {
- opendir(DH,$f)
- or die "Failed to opendir $f: $!";
-
- push @files, grep { -f $_ } map { +$f . "/" . $_ }
- sort readdir(DH);
-
- } elsif (-f $f) {
- push @files, $f;
-
- } else {
- print STDERR "Skipping $f - not found.\n";
- }
-}
-
-if (@files) {
- unless ($quiet) {
- print $_,"\n" for (@files);
- }
-} else {
- print STDERR "\nNo patch files specified!\n\n";
- usage();
+ @files = ($compose_filename . ".final", @files);
}
# Variables we set as part of the loop over files
sub send_message
{
my @recipients = unique_email_list(@to);
- @cc = (map { sanitize_address($_) } @cc);
+ @cc = (grep { my $cc = extract_valid_address($_);
+ not grep { $cc eq $_ } @recipients
+ }
+ map { sanitize_address($_) }
+ @cc);
my $to = join (",\n\t", @recipients);
@recipients = unique_email_list(@recipients,@cc,@bcclist);
@recipients = (map { extract_valid_address($_) } @recipients);
$ccline = "\nCc: $cc";
}
my $sanitized_sender = sanitize_address($sender);
- make_message_id();
+ make_message_id() unless defined($message_id);
my $header = "From: $sanitized_sender
To: $to${ccline}
}
if ((defined $smtp_authuser) && (defined $smtp_authpass)) {
- $smtp->auth( $smtp_authuser, $smtp_authpass ) or die $smtp->message;
+ $auth ||= $smtp->auth( $smtp_authuser, $smtp_authpass ) or die $smtp->message;
}
$smtp->mail( $raw_from ) or die $smtp->message;
$smtp->to( @recipients ) or die $smtp->message;
}
push @xh, $_;
}
+ elsif (/^Message-Id: (.*)/i) {
+ $message_id = $1;
+ }
elsif (!/^Date:\s/ && /^[-A-Za-z]+:\s+\S/) {
push @xh, $_;
}
else {
push @xh,
'MIME-Version: 1.0',
- "Content-Type: text/plain; charset=$author_encoding";
+ "Content-Type: text/plain; charset=$author_encoding",
+ 'Content-Transfer-Encoding: 8bit';
}
}
}
$references = "$message_id";
}
}
+ $message_id = undef;
}
if ($compose) {
}
return @emails;
}
+
+sub validate_patch {
+ my $fn = shift;
+ open(my $fh, '<', $fn)
+ or die "unable to open $fn: $!\n";
+ while (my $line = <$fh>) {
+ if (length($line) > 998) {
+ return "$.: patch contains a line longer than 998 characters";
+ }
+ }
+ return undef;
+}