send-email: --batch-size to work around some SMTP server limit
[git] / git-send-email.perl
1 #!/usr/bin/perl
2 #
3 # Copyright 2002,2005 Greg Kroah-Hartman <greg@kroah.com>
4 # Copyright 2005 Ryan Anderson <ryan@michonline.com>
5 #
6 # GPL v2 (See COPYING)
7 #
8 # Ported to support git "mbox" format files by Ryan Anderson <ryan@michonline.com>
9 #
10 # Sends a collection of emails to the given email addresses, disturbingly fast.
11 #
12 # Supports two formats:
13 # 1. mbox format files (ignoring most headers and MIME formatting - this is designed for sending patches)
14 # 2. The original format support by Greg's script:
15 #    first line of the message is who to CC,
16 #    and second line is the subject of the message.
17 #
18
19 use 5.008;
20 use strict;
21 use warnings;
22 use POSIX qw/strftime/;
23 use Term::ReadLine;
24 use Getopt::Long;
25 use Text::ParseWords;
26 use Term::ANSIColor;
27 use File::Temp qw/ tempdir tempfile /;
28 use File::Spec::Functions qw(catfile);
29 use Error qw(:try);
30 use Git;
31 use Git::I18N;
32
33 Getopt::Long::Configure qw/ pass_through /;
34
35 package FakeTerm;
36 sub new {
37         my ($class, $reason) = @_;
38         return bless \$reason, shift;
39 }
40 sub readline {
41         my $self = shift;
42         die "Cannot use readline on FakeTerm: $$self";
43 }
44 package main;
45
46
47 sub usage {
48         print <<EOT;
49 git send-email [options] <file | directory | rev-list options >
50 git send-email --dump-aliases
51
52   Composing:
53     --from                  <str>  * Email From:
54     --[no-]to               <str>  * Email To:
55     --[no-]cc               <str>  * Email Cc:
56     --[no-]bcc              <str>  * Email Bcc:
57     --subject               <str>  * Email "Subject:"
58     --in-reply-to           <str>  * Email "In-Reply-To:"
59     --[no-]xmailer                 * Add "X-Mailer:" header (default).
60     --[no-]annotate                * Review each patch that will be sent in an editor.
61     --compose                      * Open an editor for introduction.
62     --compose-encoding      <str>  * Encoding to assume for introduction.
63     --8bit-encoding         <str>  * Encoding to assume 8bit mails if undeclared
64     --transfer-encoding     <str>  * Transfer encoding to use (quoted-printable, 8bit, base64)
65
66   Sending:
67     --envelope-sender       <str>  * Email envelope sender.
68     --smtp-server       <str:int>  * Outgoing SMTP server to use. The port
69                                      is optional. Default 'localhost'.
70     --smtp-server-option    <str>  * Outgoing SMTP server option to use.
71     --smtp-server-port      <int>  * Outgoing SMTP server port.
72     --smtp-user             <str>  * Username for SMTP-AUTH.
73     --smtp-pass             <str>  * Password for SMTP-AUTH; not necessary.
74     --smtp-encryption       <str>  * tls or ssl; anything else disables.
75     --smtp-ssl                     * Deprecated. Use '--smtp-encryption ssl'.
76     --smtp-ssl-cert-path    <str>  * Path to ca-certificates (either directory or file).
77                                      Pass an empty string to disable certificate
78                                      verification.
79     --smtp-domain           <str>  * The domain name sent to HELO/EHLO handshake
80     --smtp-auth             <str>  * Space-separated list of allowed AUTH mechanisms.
81                                      This setting forces to use one of the listed mechanisms.
82     --smtp-debug            <0|1>  * Disable, enable Net::SMTP debug.
83
84     --batch-size            <int>  * send max <int> message per connection.
85     --relogin-delay         <int>  * delay <int> seconds between two successive login.
86                                      This option can only be used with --batch-size
87
88   Automating:
89     --identity              <str>  * Use the sendemail.<id> options.
90     --to-cmd                <str>  * Email To: via `<str> \$patch_path`
91     --cc-cmd                <str>  * Email Cc: via `<str> \$patch_path`
92     --suppress-cc           <str>  * author, self, sob, cc, cccmd, body, bodycc, all.
93     --[no-]cc-cover                * Email Cc: addresses in the cover letter.
94     --[no-]to-cover                * Email To: addresses in the cover letter.
95     --[no-]signed-off-by-cc        * Send to Signed-off-by: addresses. Default on.
96     --[no-]suppress-from           * Send to self. Default off.
97     --[no-]chain-reply-to          * Chain In-Reply-To: fields. Default off.
98     --[no-]thread                  * Use In-Reply-To: field. Default on.
99
100   Administering:
101     --confirm               <str>  * Confirm recipients before sending;
102                                      auto, cc, compose, always, or never.
103     --quiet                        * Output one line of info per email.
104     --dry-run                      * Don't actually send the emails.
105     --[no-]validate                * Perform patch sanity checks. Default on.
106     --[no-]format-patch            * understand any non optional arguments as
107                                      `git format-patch` ones.
108     --force                        * Send even if safety checks would prevent it.
109
110   Information:
111     --dump-aliases                 * Dump configured aliases and exit.
112
113 EOT
114         exit(1);
115 }
116
117 # most mail servers generate the Date: header, but not all...
118 sub format_2822_time {
119         my ($time) = @_;
120         my @localtm = localtime($time);
121         my @gmttm = gmtime($time);
122         my $localmin = $localtm[1] + $localtm[2] * 60;
123         my $gmtmin = $gmttm[1] + $gmttm[2] * 60;
124         if ($localtm[0] != $gmttm[0]) {
125                 die __("local zone differs from GMT by a non-minute interval\n");
126         }
127         if ((($gmttm[6] + 1) % 7) == $localtm[6]) {
128                 $localmin += 1440;
129         } elsif ((($gmttm[6] - 1) % 7) == $localtm[6]) {
130                 $localmin -= 1440;
131         } elsif ($gmttm[6] != $localtm[6]) {
132                 die __("local time offset greater than or equal to 24 hours\n");
133         }
134         my $offset = $localmin - $gmtmin;
135         my $offhour = $offset / 60;
136         my $offmin = abs($offset % 60);
137         if (abs($offhour) >= 24) {
138                 die __("local time offset greater than or equal to 24 hours\n");
139         }
140
141         return sprintf("%s, %2d %s %d %02d:%02d:%02d %s%02d%02d",
142                        qw(Sun Mon Tue Wed Thu Fri Sat)[$localtm[6]],
143                        $localtm[3],
144                        qw(Jan Feb Mar Apr May Jun
145                           Jul Aug Sep Oct Nov Dec)[$localtm[4]],
146                        $localtm[5]+1900,
147                        $localtm[2],
148                        $localtm[1],
149                        $localtm[0],
150                        ($offset >= 0) ? '+' : '-',
151                        abs($offhour),
152                        $offmin,
153                        );
154 }
155
156 my $have_email_valid = eval { require Email::Valid; 1 };
157 my $have_mail_address = eval { require Mail::Address; 1 };
158 my $smtp;
159 my $auth;
160 my $num_sent = 0;
161
162 # Regexes for RFC 2047 productions.
163 my $re_token = qr/[^][()<>@,;:\\"\/?.= \000-\037\177-\377]+/;
164 my $re_encoded_text = qr/[^? \000-\037\177-\377]+/;
165 my $re_encoded_word = qr/=\?($re_token)\?($re_token)\?($re_encoded_text)\?=/;
166
167 # Variables we fill in automatically, or via prompting:
168 my (@to,$no_to,@initial_to,@cc,$no_cc,@initial_cc,@bcclist,$no_bcc,@xh,
169         $initial_reply_to,$initial_subject,@files,
170         $author,$sender,$smtp_authpass,$annotate,$use_xmailer,$compose,$time);
171
172 my $envelope_sender;
173
174 # Example reply to:
175 #$initial_reply_to = ''; #<20050203173208.GA23964@foobar.com>';
176
177 my $repo = eval { Git->repository() };
178 my @repo = $repo ? ($repo) : ();
179 my $term = eval {
180         $ENV{"GIT_SEND_EMAIL_NOTTY"}
181                 ? new Term::ReadLine 'git-send-email', \*STDIN, \*STDOUT
182                 : new Term::ReadLine 'git-send-email';
183 };
184 if ($@) {
185         $term = new FakeTerm "$@: going non-interactive";
186 }
187
188 # Behavior modification variables
189 my ($quiet, $dry_run) = (0, 0);
190 my $format_patch;
191 my $compose_filename;
192 my $force = 0;
193 my $dump_aliases = 0;
194
195 # Handle interactive edition of files.
196 my $multiedit;
197 my $editor;
198
199 sub do_edit {
200         if (!defined($editor)) {
201                 $editor = Git::command_oneline('var', 'GIT_EDITOR');
202         }
203         if (defined($multiedit) && !$multiedit) {
204                 map {
205                         system('sh', '-c', $editor.' "$@"', $editor, $_);
206                         if (($? & 127) || ($? >> 8)) {
207                                 die(__("the editor exited uncleanly, aborting everything"));
208                         }
209                 } @_;
210         } else {
211                 system('sh', '-c', $editor.' "$@"', $editor, @_);
212                 if (($? & 127) || ($? >> 8)) {
213                         die(__("the editor exited uncleanly, aborting everything"));
214                 }
215         }
216 }
217
218 # Variables with corresponding config settings
219 my ($thread, $chain_reply_to, $suppress_from, $signed_off_by_cc);
220 my ($cover_cc, $cover_to);
221 my ($to_cmd, $cc_cmd);
222 my ($smtp_server, $smtp_server_port, @smtp_server_options);
223 my ($smtp_authuser, $smtp_encryption, $smtp_ssl_cert_path);
224 my ($batch_size, $relogin_delay);
225 my ($identity, $aliasfiletype, @alias_files, $smtp_domain, $smtp_auth);
226 my ($validate, $confirm);
227 my (@suppress_cc);
228 my ($auto_8bit_encoding);
229 my ($compose_encoding);
230 my ($target_xfer_encoding);
231
232 my ($debug_net_smtp) = 0;               # Net::SMTP, see send_message()
233
234 my %config_bool_settings = (
235     "thread" => [\$thread, 1],
236     "chainreplyto" => [\$chain_reply_to, 0],
237     "suppressfrom" => [\$suppress_from, undef],
238     "signedoffbycc" => [\$signed_off_by_cc, undef],
239     "cccover" => [\$cover_cc, undef],
240     "tocover" => [\$cover_to, undef],
241     "signedoffcc" => [\$signed_off_by_cc, undef],      # Deprecated
242     "validate" => [\$validate, 1],
243     "multiedit" => [\$multiedit, undef],
244     "annotate" => [\$annotate, undef],
245     "xmailer" => [\$use_xmailer, 1]
246 );
247
248 my %config_settings = (
249     "smtpserver" => \$smtp_server,
250     "smtpserverport" => \$smtp_server_port,
251     "smtpserveroption" => \@smtp_server_options,
252     "smtpuser" => \$smtp_authuser,
253     "smtppass" => \$smtp_authpass,
254     "smtpdomain" => \$smtp_domain,
255     "smtpauth" => \$smtp_auth,
256     "smtpbatchsize" => \$batch_size,
257     "smtprelogindelay" => \$relogin_delay,
258     "to" => \@initial_to,
259     "tocmd" => \$to_cmd,
260     "cc" => \@initial_cc,
261     "cccmd" => \$cc_cmd,
262     "aliasfiletype" => \$aliasfiletype,
263     "bcc" => \@bcclist,
264     "suppresscc" => \@suppress_cc,
265     "envelopesender" => \$envelope_sender,
266     "confirm"   => \$confirm,
267     "from" => \$sender,
268     "assume8bitencoding" => \$auto_8bit_encoding,
269     "composeencoding" => \$compose_encoding,
270     "transferencoding" => \$target_xfer_encoding,
271 );
272
273 my %config_path_settings = (
274     "aliasesfile" => \@alias_files,
275     "smtpsslcertpath" => \$smtp_ssl_cert_path,
276 );
277
278 # Handle Uncouth Termination
279 sub signal_handler {
280
281         # Make text normal
282         print color("reset"), "\n";
283
284         # SMTP password masked
285         system "stty echo";
286
287         # tmp files from --compose
288         if (defined $compose_filename) {
289                 if (-e $compose_filename) {
290                         printf __("'%s' contains an intermediate version ".
291                                   "of the email you were composing.\n"),
292                                   $compose_filename;
293                 }
294                 if (-e ($compose_filename . ".final")) {
295                         printf __("'%s.final' contains the composed email.\n"),
296                                   $compose_filename;
297                 }
298         }
299
300         exit;
301 };
302
303 $SIG{TERM} = \&signal_handler;
304 $SIG{INT}  = \&signal_handler;
305
306 # Begin by accumulating all the variables (defined above), that we will end up
307 # needing, first, from the command line:
308
309 my $help;
310 my $rc = GetOptions("h" => \$help,
311                     "dump-aliases" => \$dump_aliases);
312 usage() unless $rc;
313 die __("--dump-aliases incompatible with other options\n")
314     if !$help and $dump_aliases and @ARGV;
315 $rc = GetOptions(
316                     "sender|from=s" => \$sender,
317                     "in-reply-to=s" => \$initial_reply_to,
318                     "subject=s" => \$initial_subject,
319                     "to=s" => \@initial_to,
320                     "to-cmd=s" => \$to_cmd,
321                     "no-to" => \$no_to,
322                     "cc=s" => \@initial_cc,
323                     "no-cc" => \$no_cc,
324                     "bcc=s" => \@bcclist,
325                     "no-bcc" => \$no_bcc,
326                     "chain-reply-to!" => \$chain_reply_to,
327                     "no-chain-reply-to" => sub {$chain_reply_to = 0},
328                     "smtp-server=s" => \$smtp_server,
329                     "smtp-server-option=s" => \@smtp_server_options,
330                     "smtp-server-port=s" => \$smtp_server_port,
331                     "smtp-user=s" => \$smtp_authuser,
332                     "smtp-pass:s" => \$smtp_authpass,
333                     "smtp-ssl" => sub { $smtp_encryption = 'ssl' },
334                     "smtp-encryption=s" => \$smtp_encryption,
335                     "smtp-ssl-cert-path=s" => \$smtp_ssl_cert_path,
336                     "smtp-debug:i" => \$debug_net_smtp,
337                     "smtp-domain:s" => \$smtp_domain,
338                     "smtp-auth=s" => \$smtp_auth,
339                     "identity=s" => \$identity,
340                     "annotate!" => \$annotate,
341                     "no-annotate" => sub {$annotate = 0},
342                     "compose" => \$compose,
343                     "quiet" => \$quiet,
344                     "cc-cmd=s" => \$cc_cmd,
345                     "suppress-from!" => \$suppress_from,
346                     "no-suppress-from" => sub {$suppress_from = 0},
347                     "suppress-cc=s" => \@suppress_cc,
348                     "signed-off-cc|signed-off-by-cc!" => \$signed_off_by_cc,
349                     "no-signed-off-cc|no-signed-off-by-cc" => sub {$signed_off_by_cc = 0},
350                     "cc-cover|cc-cover!" => \$cover_cc,
351                     "no-cc-cover" => sub {$cover_cc = 0},
352                     "to-cover|to-cover!" => \$cover_to,
353                     "no-to-cover" => sub {$cover_to = 0},
354                     "confirm=s" => \$confirm,
355                     "dry-run" => \$dry_run,
356                     "envelope-sender=s" => \$envelope_sender,
357                     "thread!" => \$thread,
358                     "no-thread" => sub {$thread = 0},
359                     "validate!" => \$validate,
360                     "no-validate" => sub {$validate = 0},
361                     "transfer-encoding=s" => \$target_xfer_encoding,
362                     "format-patch!" => \$format_patch,
363                     "no-format-patch" => sub {$format_patch = 0},
364                     "8bit-encoding=s" => \$auto_8bit_encoding,
365                     "compose-encoding=s" => \$compose_encoding,
366                     "force" => \$force,
367                     "xmailer!" => \$use_xmailer,
368                     "no-xmailer" => sub {$use_xmailer = 0},
369                     "batch-size=i" => \$batch_size,
370                     "relogin-delay=i" => \$relogin_delay,
371          );
372
373 usage() if $help;
374 unless ($rc) {
375     usage();
376 }
377
378 die __("Cannot run git format-patch from outside a repository\n")
379         if $format_patch and not $repo;
380
381 # Now, let's fill any that aren't set in with defaults:
382
383 sub read_config {
384         my ($prefix) = @_;
385
386         foreach my $setting (keys %config_bool_settings) {
387                 my $target = $config_bool_settings{$setting}->[0];
388                 $$target = Git::config_bool(@repo, "$prefix.$setting") unless (defined $$target);
389         }
390
391         foreach my $setting (keys %config_path_settings) {
392                 my $target = $config_path_settings{$setting};
393                 if (ref($target) eq "ARRAY") {
394                         unless (@$target) {
395                                 my @values = Git::config_path(@repo, "$prefix.$setting");
396                                 @$target = @values if (@values && defined $values[0]);
397                         }
398                 }
399                 else {
400                         $$target = Git::config_path(@repo, "$prefix.$setting") unless (defined $$target);
401                 }
402         }
403
404         foreach my $setting (keys %config_settings) {
405                 my $target = $config_settings{$setting};
406                 next if $setting eq "to" and defined $no_to;
407                 next if $setting eq "cc" and defined $no_cc;
408                 next if $setting eq "bcc" and defined $no_bcc;
409                 if (ref($target) eq "ARRAY") {
410                         unless (@$target) {
411                                 my @values = Git::config(@repo, "$prefix.$setting");
412                                 @$target = @values if (@values && defined $values[0]);
413                         }
414                 }
415                 else {
416                         $$target = Git::config(@repo, "$prefix.$setting") unless (defined $$target);
417                 }
418         }
419
420         if (!defined $smtp_encryption) {
421                 my $enc = Git::config(@repo, "$prefix.smtpencryption");
422                 if (defined $enc) {
423                         $smtp_encryption = $enc;
424                 } elsif (Git::config_bool(@repo, "$prefix.smtpssl")) {
425                         $smtp_encryption = 'ssl';
426                 }
427         }
428 }
429
430 # read configuration from [sendemail "$identity"], fall back on [sendemail]
431 $identity = Git::config(@repo, "sendemail.identity") unless (defined $identity);
432 read_config("sendemail.$identity") if (defined $identity);
433 read_config("sendemail");
434
435 # fall back on builtin bool defaults
436 foreach my $setting (values %config_bool_settings) {
437         ${$setting->[0]} = $setting->[1] unless (defined (${$setting->[0]}));
438 }
439
440 # 'default' encryption is none -- this only prevents a warning
441 $smtp_encryption = '' unless (defined $smtp_encryption);
442
443 # Set CC suppressions
444 my(%suppress_cc);
445 if (@suppress_cc) {
446         foreach my $entry (@suppress_cc) {
447                 die sprintf(__("Unknown --suppress-cc field: '%s'\n"), $entry)
448                         unless $entry =~ /^(?:all|cccmd|cc|author|self|sob|body|bodycc)$/;
449                 $suppress_cc{$entry} = 1;
450         }
451 }
452
453 if ($suppress_cc{'all'}) {
454         foreach my $entry (qw (cccmd cc author self sob body bodycc)) {
455                 $suppress_cc{$entry} = 1;
456         }
457         delete $suppress_cc{'all'};
458 }
459
460 # If explicit old-style ones are specified, they trump --suppress-cc.
461 $suppress_cc{'self'} = $suppress_from if defined $suppress_from;
462 $suppress_cc{'sob'} = !$signed_off_by_cc if defined $signed_off_by_cc;
463
464 if ($suppress_cc{'body'}) {
465         foreach my $entry (qw (sob bodycc)) {
466                 $suppress_cc{$entry} = 1;
467         }
468         delete $suppress_cc{'body'};
469 }
470
471 # Set confirm's default value
472 my $confirm_unconfigured = !defined $confirm;
473 if ($confirm_unconfigured) {
474         $confirm = scalar %suppress_cc ? 'compose' : 'auto';
475 };
476 die sprintf(__("Unknown --confirm setting: '%s'\n"), $confirm)
477         unless $confirm =~ /^(?:auto|cc|compose|always|never)/;
478
479 # Debugging, print out the suppressions.
480 if (0) {
481         print "suppressions:\n";
482         foreach my $entry (keys %suppress_cc) {
483                 printf "  %-5s -> $suppress_cc{$entry}\n", $entry;
484         }
485 }
486
487 my ($repoauthor, $repocommitter);
488 ($repoauthor) = Git::ident_person(@repo, 'author');
489 ($repocommitter) = Git::ident_person(@repo, 'committer');
490
491 sub parse_address_line {
492         if ($have_mail_address) {
493                 return map { $_->format } Mail::Address->parse($_[0]);
494         } else {
495                 return Git::parse_mailboxes($_[0]);
496         }
497 }
498
499 sub split_addrs {
500         return quotewords('\s*,\s*', 1, @_);
501 }
502
503 my %aliases;
504
505 sub parse_sendmail_alias {
506         local $_ = shift;
507         if (/"/) {
508                 printf STDERR __("warning: sendmail alias with quotes is not supported: %s\n"), $_;
509         } elsif (/:include:/) {
510                 printf STDERR __("warning: `:include:` not supported: %s\n"), $_;
511         } elsif (/[\/|]/) {
512                 printf STDERR __("warning: `/file` or `|pipe` redirection not supported: %s\n"), $_;
513         } elsif (/^(\S+?)\s*:\s*(.+)$/) {
514                 my ($alias, $addr) = ($1, $2);
515                 $aliases{$alias} = [ split_addrs($addr) ];
516         } else {
517                 printf STDERR __("warning: sendmail line is not recognized: %s\n"), $_;
518         }
519 }
520
521 sub parse_sendmail_aliases {
522         my $fh = shift;
523         my $s = '';
524         while (<$fh>) {
525                 chomp;
526                 next if /^\s*$/ || /^\s*#/;
527                 $s .= $_, next if $s =~ s/\\$// || s/^\s+//;
528                 parse_sendmail_alias($s) if $s;
529                 $s = $_;
530         }
531         $s =~ s/\\$//; # silently tolerate stray '\' on last line
532         parse_sendmail_alias($s) if $s;
533 }
534
535 my %parse_alias = (
536         # multiline formats can be supported in the future
537         mutt => sub { my $fh = shift; while (<$fh>) {
538                 if (/^\s*alias\s+(?:-group\s+\S+\s+)*(\S+)\s+(.*)$/) {
539                         my ($alias, $addr) = ($1, $2);
540                         $addr =~ s/#.*$//; # mutt allows # comments
541                         # commas delimit multiple addresses
542                         my @addr = split_addrs($addr);
543
544                         # quotes may be escaped in the file,
545                         # unescape them so we do not double-escape them later.
546                         s/\\"/"/g foreach @addr;
547                         $aliases{$alias} = \@addr
548                 }}},
549         mailrc => sub { my $fh = shift; while (<$fh>) {
550                 if (/^alias\s+(\S+)\s+(.*?)\s*$/) {
551                         # spaces delimit multiple addresses
552                         $aliases{$1} = [ quotewords('\s+', 0, $2) ];
553                 }}},
554         pine => sub { my $fh = shift; my $f='\t[^\t]*';
555                 for (my $x = ''; defined($x); $x = $_) {
556                         chomp $x;
557                         $x .= $1 while(defined($_ = <$fh>) && /^ +(.*)$/);
558                         $x =~ /^(\S+)$f\t\(?([^\t]+?)\)?(:?$f){0,2}$/ or next;
559                         $aliases{$1} = [ split_addrs($2) ];
560                 }},
561         elm => sub  { my $fh = shift;
562                       while (<$fh>) {
563                           if (/^(\S+)\s+=\s+[^=]+=\s(\S+)/) {
564                               my ($alias, $addr) = ($1, $2);
565                                $aliases{$alias} = [ split_addrs($addr) ];
566                           }
567                       } },
568         sendmail => \&parse_sendmail_aliases,
569         gnus => sub { my $fh = shift; while (<$fh>) {
570                 if (/\(define-mail-alias\s+"(\S+?)"\s+"(\S+?)"\)/) {
571                         $aliases{$1} = [ $2 ];
572                 }}}
573 );
574
575 if (@alias_files and $aliasfiletype and defined $parse_alias{$aliasfiletype}) {
576         foreach my $file (@alias_files) {
577                 open my $fh, '<', $file or die "opening $file: $!\n";
578                 $parse_alias{$aliasfiletype}->($fh);
579                 close $fh;
580         }
581 }
582
583 if ($dump_aliases) {
584     print "$_\n" for (sort keys %aliases);
585     exit(0);
586 }
587
588 # is_format_patch_arg($f) returns 0 if $f names a patch, or 1 if
589 # $f is a revision list specification to be passed to format-patch.
590 sub is_format_patch_arg {
591         return unless $repo;
592         my $f = shift;
593         try {
594                 $repo->command('rev-parse', '--verify', '--quiet', $f);
595                 if (defined($format_patch)) {
596                         return $format_patch;
597                 }
598                 die sprintf(__ <<EOF, $f, $f);
599 File '%s' exists but it could also be the range of commits
600 to produce patches for.  Please disambiguate by...
601
602     * Saying "./%s" if you mean a file; or
603     * Giving --format-patch option if you mean a range.
604 EOF
605         } catch Git::Error::Command with {
606                 # Not a valid revision.  Treat it as a filename.
607                 return 0;
608         }
609 }
610
611 # Now that all the defaults are set, process the rest of the command line
612 # arguments and collect up the files that need to be processed.
613 my @rev_list_opts;
614 while (defined(my $f = shift @ARGV)) {
615         if ($f eq "--") {
616                 push @rev_list_opts, "--", @ARGV;
617                 @ARGV = ();
618         } elsif (-d $f and !is_format_patch_arg($f)) {
619                 opendir my $dh, $f
620                         or die sprintf(__("Failed to opendir %s: %s"), $f, $!);
621
622                 push @files, grep { -f $_ } map { catfile($f, $_) }
623                                 sort readdir $dh;
624                 closedir $dh;
625         } elsif ((-f $f or -p $f) and !is_format_patch_arg($f)) {
626                 push @files, $f;
627         } else {
628                 push @rev_list_opts, $f;
629         }
630 }
631
632 if (@rev_list_opts) {
633         die __("Cannot run git format-patch from outside a repository\n")
634                 unless $repo;
635         push @files, $repo->command('format-patch', '-o', tempdir(CLEANUP => 1), @rev_list_opts);
636 }
637
638 @files = handle_backup_files(@files);
639
640 if ($validate) {
641         foreach my $f (@files) {
642                 unless (-p $f) {
643                         my $error = validate_patch($f);
644                         $error and die sprintf(__("fatal: %s: %s\nwarning: no patches were sent\n"),
645                                                   $f, $error);
646                 }
647         }
648 }
649
650 if (@files) {
651         unless ($quiet) {
652                 print $_,"\n" for (@files);
653         }
654 } else {
655         print STDERR __("\nNo patch files specified!\n\n");
656         usage();
657 }
658
659 sub get_patch_subject {
660         my $fn = shift;
661         open (my $fh, '<', $fn);
662         while (my $line = <$fh>) {
663                 next unless ($line =~ /^Subject: (.*)$/);
664                 close $fh;
665                 return "GIT: $1\n";
666         }
667         close $fh;
668         die sprintf(__("No subject line in %s?"), $fn);
669 }
670
671 if ($compose) {
672         # Note that this does not need to be secure, but we will make a small
673         # effort to have it be unique
674         $compose_filename = ($repo ?
675                 tempfile(".gitsendemail.msg.XXXXXX", DIR => $repo->repo_path()) :
676                 tempfile(".gitsendemail.msg.XXXXXX", DIR => "."))[1];
677         open my $c, ">", $compose_filename
678                 or die sprintf(__("Failed to open for writing %s: %s"), $compose_filename, $!);
679
680
681         my $tpl_sender = $sender || $repoauthor || $repocommitter || '';
682         my $tpl_subject = $initial_subject || '';
683         my $tpl_reply_to = $initial_reply_to || '';
684
685         print $c <<EOT1, Git::prefix_lines("GIT: ", __ <<EOT2), <<EOT3;
686 From $tpl_sender # This line is ignored.
687 EOT1
688 Lines beginning in "GIT:" will be removed.
689 Consider including an overall diffstat or table of contents
690 for the patch you are writing.
691
692 Clear the body content if you don't wish to send a summary.
693 EOT2
694 From: $tpl_sender
695 Subject: $tpl_subject
696 In-Reply-To: $tpl_reply_to
697
698 EOT3
699         for my $f (@files) {
700                 print $c get_patch_subject($f);
701         }
702         close $c;
703
704         if ($annotate) {
705                 do_edit($compose_filename, @files);
706         } else {
707                 do_edit($compose_filename);
708         }
709
710         open my $c2, ">", $compose_filename . ".final"
711                 or die sprintf(__("Failed to open %s.final: %s"), $compose_filename, $!);
712
713         open $c, "<", $compose_filename
714                 or die sprintf(__("Failed to open %s: %s"), $compose_filename, $!);
715
716         my $need_8bit_cte = file_has_nonascii($compose_filename);
717         my $in_body = 0;
718         my $summary_empty = 1;
719         if (!defined $compose_encoding) {
720                 $compose_encoding = "UTF-8";
721         }
722         while(<$c>) {
723                 next if m/^GIT:/;
724                 if ($in_body) {
725                         $summary_empty = 0 unless (/^\n$/);
726                 } elsif (/^\n$/) {
727                         $in_body = 1;
728                         if ($need_8bit_cte) {
729                                 print $c2 "MIME-Version: 1.0\n",
730                                          "Content-Type: text/plain; ",
731                                            "charset=$compose_encoding\n",
732                                          "Content-Transfer-Encoding: 8bit\n";
733                         }
734                 } elsif (/^MIME-Version:/i) {
735                         $need_8bit_cte = 0;
736                 } elsif (/^Subject:\s*(.+)\s*$/i) {
737                         $initial_subject = $1;
738                         my $subject = $initial_subject;
739                         $_ = "Subject: " .
740                                 quote_subject($subject, $compose_encoding) .
741                                 "\n";
742                 } elsif (/^In-Reply-To:\s*(.+)\s*$/i) {
743                         $initial_reply_to = $1;
744                         next;
745                 } elsif (/^From:\s*(.+)\s*$/i) {
746                         $sender = $1;
747                         next;
748                 } elsif (/^(?:To|Cc|Bcc):/i) {
749                         print __("To/Cc/Bcc fields are not interpreted yet, they have been ignored\n");
750                         next;
751                 }
752                 print $c2 $_;
753         }
754         close $c;
755         close $c2;
756
757         if ($summary_empty) {
758                 print __("Summary email is empty, skipping it\n");
759                 $compose = -1;
760         }
761 } elsif ($annotate) {
762         do_edit(@files);
763 }
764
765 sub ask {
766         my ($prompt, %arg) = @_;
767         my $valid_re = $arg{valid_re};
768         my $default = $arg{default};
769         my $confirm_only = $arg{confirm_only};
770         my $resp;
771         my $i = 0;
772         return defined $default ? $default : undef
773                 unless defined $term->IN and defined fileno($term->IN) and
774                        defined $term->OUT and defined fileno($term->OUT);
775         while ($i++ < 10) {
776                 $resp = $term->readline($prompt);
777                 if (!defined $resp) { # EOF
778                         print "\n";
779                         return defined $default ? $default : undef;
780                 }
781                 if ($resp eq '' and defined $default) {
782                         return $default;
783                 }
784                 if (!defined $valid_re or $resp =~ /$valid_re/) {
785                         return $resp;
786                 }
787                 if ($confirm_only) {
788                         my $yesno = $term->readline(
789                                 # TRANSLATORS: please keep [y/N] as is.
790                                 sprintf(__("Are you sure you want to use <%s> [y/N]? "), $resp));
791                         if (defined $yesno && $yesno =~ /y/i) {
792                                 return $resp;
793                         }
794                 }
795         }
796         return;
797 }
798
799 my %broken_encoding;
800
801 sub file_declares_8bit_cte {
802         my $fn = shift;
803         open (my $fh, '<', $fn);
804         while (my $line = <$fh>) {
805                 last if ($line =~ /^$/);
806                 return 1 if ($line =~ /^Content-Transfer-Encoding: .*8bit.*$/);
807         }
808         close $fh;
809         return 0;
810 }
811
812 foreach my $f (@files) {
813         next unless (body_or_subject_has_nonascii($f)
814                      && !file_declares_8bit_cte($f));
815         $broken_encoding{$f} = 1;
816 }
817
818 if (!defined $auto_8bit_encoding && scalar %broken_encoding) {
819         print __("The following files are 8bit, but do not declare " .
820                  "a Content-Transfer-Encoding.\n");
821         foreach my $f (sort keys %broken_encoding) {
822                 print "    $f\n";
823         }
824         $auto_8bit_encoding = ask(__("Which 8bit encoding should I declare [UTF-8]? "),
825                                   valid_re => qr/.{4}/, confirm_only => 1,
826                                   default => "UTF-8");
827 }
828
829 if (!$force) {
830         for my $f (@files) {
831                 if (get_patch_subject($f) =~ /\Q*** SUBJECT HERE ***\E/) {
832                         die sprintf(__("Refusing to send because the patch\n\t%s\n"
833                                 . "has the template subject '*** SUBJECT HERE ***'. "
834                                 . "Pass --force if you really want to send.\n"), $f);
835                 }
836         }
837 }
838
839 if (defined $sender) {
840         $sender =~ s/^\s+|\s+$//g;
841         ($sender) = expand_aliases($sender);
842 } else {
843         $sender = $repoauthor || $repocommitter || '';
844 }
845
846 # $sender could be an already sanitized address
847 # (e.g. sendemail.from could be manually sanitized by user).
848 # But it's a no-op to run sanitize_address on an already sanitized address.
849 $sender = sanitize_address($sender);
850
851 my $to_whom = __("To whom should the emails be sent (if anyone)?");
852 my $prompting = 0;
853 if (!@initial_to && !defined $to_cmd) {
854         my $to = ask("$to_whom ",
855                      default => "",
856                      valid_re => qr/\@.*\./, confirm_only => 1);
857         push @initial_to, parse_address_line($to) if defined $to; # sanitized/validated later
858         $prompting++;
859 }
860
861 sub expand_aliases {
862         return map { expand_one_alias($_) } @_;
863 }
864
865 my %EXPANDED_ALIASES;
866 sub expand_one_alias {
867         my $alias = shift;
868         if ($EXPANDED_ALIASES{$alias}) {
869                 die sprintf(__("fatal: alias '%s' expands to itself\n"), $alias);
870         }
871         local $EXPANDED_ALIASES{$alias} = 1;
872         return $aliases{$alias} ? expand_aliases(@{$aliases{$alias}}) : $alias;
873 }
874
875 @initial_to = process_address_list(@initial_to);
876 @initial_cc = process_address_list(@initial_cc);
877 @bcclist = process_address_list(@bcclist);
878
879 if ($thread && !defined $initial_reply_to && $prompting) {
880         $initial_reply_to = ask(
881                 __("Message-ID to be used as In-Reply-To for the first email (if any)? "),
882                 default => "",
883                 valid_re => qr/\@.*\./, confirm_only => 1);
884 }
885 if (defined $initial_reply_to) {
886         $initial_reply_to =~ s/^\s*<?//;
887         $initial_reply_to =~ s/>?\s*$//;
888         $initial_reply_to = "<$initial_reply_to>" if $initial_reply_to ne '';
889 }
890
891 if (!defined $smtp_server) {
892         foreach (qw( /usr/sbin/sendmail /usr/lib/sendmail )) {
893                 if (-x $_) {
894                         $smtp_server = $_;
895                         last;
896                 }
897         }
898         $smtp_server ||= 'localhost'; # could be 127.0.0.1, too... *shrug*
899 }
900
901 if ($compose && $compose > 0) {
902         @files = ($compose_filename . ".final", @files);
903 }
904
905 # Variables we set as part of the loop over files
906 our ($message_id, %mail, $subject, $reply_to, $references, $message,
907         $needs_confirm, $message_num, $ask_default);
908
909 sub extract_valid_address {
910         my $address = shift;
911         my $local_part_regexp = qr/[^<>"\s@]+/;
912         my $domain_regexp = qr/[^.<>"\s@]+(?:\.[^.<>"\s@]+)+/;
913
914         # check for a local address:
915         return $address if ($address =~ /^($local_part_regexp)$/);
916
917         $address =~ s/^\s*<(.*)>\s*$/$1/;
918         if ($have_email_valid) {
919                 return scalar Email::Valid->address($address);
920         }
921
922         # less robust/correct than the monster regexp in Email::Valid,
923         # but still does a 99% job, and one less dependency
924         return $1 if $address =~ /($local_part_regexp\@$domain_regexp)/;
925         return;
926 }
927
928 sub extract_valid_address_or_die {
929         my $address = shift;
930         $address = extract_valid_address($address);
931         die sprintf(__("error: unable to extract a valid address from: %s\n"), $address)
932                 if !$address;
933         return $address;
934 }
935
936 sub validate_address {
937         my $address = shift;
938         while (!extract_valid_address($address)) {
939                 printf STDERR __("error: unable to extract a valid address from: %s\n"), $address;
940                 # TRANSLATORS: Make sure to include [q] [d] [e] in your
941                 # translation. The program will only accept English input
942                 # at this point.
943                 $_ = ask(__("What to do with this address? ([q]uit|[d]rop|[e]dit): "),
944                         valid_re => qr/^(?:quit|q|drop|d|edit|e)/i,
945                         default => 'q');
946                 if (/^d/i) {
947                         return undef;
948                 } elsif (/^q/i) {
949                         cleanup_compose_files();
950                         exit(0);
951                 }
952                 $address = ask("$to_whom ",
953                         default => "",
954                         valid_re => qr/\@.*\./, confirm_only => 1);
955         }
956         return $address;
957 }
958
959 sub validate_address_list {
960         return (grep { defined $_ }
961                 map { validate_address($_) } @_);
962 }
963
964 # Usually don't need to change anything below here.
965
966 # we make a "fake" message id by taking the current number
967 # of seconds since the beginning of Unix time and tacking on
968 # a random number to the end, in case we are called quicker than
969 # 1 second since the last time we were called.
970
971 # We'll setup a template for the message id, using the "from" address:
972
973 my ($message_id_stamp, $message_id_serial);
974 sub make_message_id {
975         my $uniq;
976         if (!defined $message_id_stamp) {
977                 $message_id_stamp = strftime("%Y%m%d%H%M%S.$$", gmtime(time));
978                 $message_id_serial = 0;
979         }
980         $message_id_serial++;
981         $uniq = "$message_id_stamp-$message_id_serial";
982
983         my $du_part;
984         for ($sender, $repocommitter, $repoauthor) {
985                 $du_part = extract_valid_address(sanitize_address($_));
986                 last if (defined $du_part and $du_part ne '');
987         }
988         if (not defined $du_part or $du_part eq '') {
989                 require Sys::Hostname;
990                 $du_part = 'user@' . Sys::Hostname::hostname();
991         }
992         my $message_id_template = "<%s-%s>";
993         $message_id = sprintf($message_id_template, $uniq, $du_part);
994         #print "new message id = $message_id\n"; # Was useful for debugging
995 }
996
997
998
999 $time = time - scalar $#files;
1000
1001 sub unquote_rfc2047 {
1002         local ($_) = @_;
1003         my $charset;
1004         my $sep = qr/[ \t]+/;
1005         s{$re_encoded_word(?:$sep$re_encoded_word)*}{
1006                 my @words = split $sep, $&;
1007                 foreach (@words) {
1008                         m/$re_encoded_word/;
1009                         $charset = $1;
1010                         my $encoding = $2;
1011                         my $text = $3;
1012                         if ($encoding eq 'q' || $encoding eq 'Q') {
1013                                 $_ = $text;
1014                                 s/_/ /g;
1015                                 s/=([0-9A-F]{2})/chr(hex($1))/egi;
1016                         } else {
1017                                 # other encodings not supported yet
1018                         }
1019                 }
1020                 join '', @words;
1021         }eg;
1022         return wantarray ? ($_, $charset) : $_;
1023 }
1024
1025 sub quote_rfc2047 {
1026         local $_ = shift;
1027         my $encoding = shift || 'UTF-8';
1028         s/([^-a-zA-Z0-9!*+\/])/sprintf("=%02X", ord($1))/eg;
1029         s/(.*)/=\?$encoding\?q\?$1\?=/;
1030         return $_;
1031 }
1032
1033 sub is_rfc2047_quoted {
1034         my $s = shift;
1035         length($s) <= 75 &&
1036         $s =~ m/^(?:"[[:ascii:]]*"|$re_encoded_word)$/o;
1037 }
1038
1039 sub subject_needs_rfc2047_quoting {
1040         my $s = shift;
1041
1042         return ($s =~ /[^[:ascii:]]/) || ($s =~ /=\?/);
1043 }
1044
1045 sub quote_subject {
1046         local $subject = shift;
1047         my $encoding = shift || 'UTF-8';
1048
1049         if (subject_needs_rfc2047_quoting($subject)) {
1050                 return quote_rfc2047($subject, $encoding);
1051         }
1052         return $subject;
1053 }
1054
1055 # use the simplest quoting being able to handle the recipient
1056 sub sanitize_address {
1057         my ($recipient) = @_;
1058
1059         # remove garbage after email address
1060         $recipient =~ s/(.*>).*$/$1/;
1061
1062         my ($recipient_name, $recipient_addr) = ($recipient =~ /^(.*?)\s*(<.*)/);
1063
1064         if (not $recipient_name) {
1065                 return $recipient;
1066         }
1067
1068         # if recipient_name is already quoted, do nothing
1069         if (is_rfc2047_quoted($recipient_name)) {
1070                 return $recipient;
1071         }
1072
1073         # remove non-escaped quotes
1074         $recipient_name =~ s/(^|[^\\])"/$1/g;
1075
1076         # rfc2047 is needed if a non-ascii char is included
1077         if ($recipient_name =~ /[^[:ascii:]]/) {
1078                 $recipient_name = quote_rfc2047($recipient_name);
1079         }
1080
1081         # double quotes are needed if specials or CTLs are included
1082         elsif ($recipient_name =~ /[][()<>@,;:\\".\000-\037\177]/) {
1083                 $recipient_name =~ s/([\\\r])/\\$1/g;
1084                 $recipient_name = qq["$recipient_name"];
1085         }
1086
1087         return "$recipient_name $recipient_addr";
1088
1089 }
1090
1091 sub sanitize_address_list {
1092         return (map { sanitize_address($_) } @_);
1093 }
1094
1095 sub process_address_list {
1096         my @addr_list = map { parse_address_line($_) } @_;
1097         @addr_list = expand_aliases(@addr_list);
1098         @addr_list = sanitize_address_list(@addr_list);
1099         @addr_list = validate_address_list(@addr_list);
1100         return @addr_list;
1101 }
1102
1103 # Returns the local Fully Qualified Domain Name (FQDN) if available.
1104 #
1105 # Tightly configured MTAa require that a caller sends a real DNS
1106 # domain name that corresponds the IP address in the HELO/EHLO
1107 # handshake. This is used to verify the connection and prevent
1108 # spammers from trying to hide their identity. If the DNS and IP don't
1109 # match, the receiveing MTA may deny the connection.
1110 #
1111 # Here is a deny example of Net::SMTP with the default "localhost.localdomain"
1112 #
1113 # Net::SMTP=GLOB(0x267ec28)>>> EHLO localhost.localdomain
1114 # Net::SMTP=GLOB(0x267ec28)<<< 550 EHLO argument does not match calling host
1115 #
1116 # This maildomain*() code is based on ideas in Perl library Test::Reporter
1117 # /usr/share/perl5/Test/Reporter/Mail/Util.pm ==> sub _maildomain ()
1118
1119 sub valid_fqdn {
1120         my $domain = shift;
1121         return defined $domain && !($^O eq 'darwin' && $domain =~ /\.local$/) && $domain =~ /\./;
1122 }
1123
1124 sub maildomain_net {
1125         my $maildomain;
1126
1127         if (eval { require Net::Domain; 1 }) {
1128                 my $domain = Net::Domain::domainname();
1129                 $maildomain = $domain if valid_fqdn($domain);
1130         }
1131
1132         return $maildomain;
1133 }
1134
1135 sub maildomain_mta {
1136         my $maildomain;
1137
1138         if (eval { require Net::SMTP; 1 }) {
1139                 for my $host (qw(mailhost localhost)) {
1140                         my $smtp = Net::SMTP->new($host);
1141                         if (defined $smtp) {
1142                                 my $domain = $smtp->domain;
1143                                 $smtp->quit;
1144
1145                                 $maildomain = $domain if valid_fqdn($domain);
1146
1147                                 last if $maildomain;
1148                         }
1149                 }
1150         }
1151
1152         return $maildomain;
1153 }
1154
1155 sub maildomain {
1156         return maildomain_net() || maildomain_mta() || 'localhost.localdomain';
1157 }
1158
1159 sub smtp_host_string {
1160         if (defined $smtp_server_port) {
1161                 return "$smtp_server:$smtp_server_port";
1162         } else {
1163                 return $smtp_server;
1164         }
1165 }
1166
1167 # Returns 1 if authentication succeeded or was not necessary
1168 # (smtp_user was not specified), and 0 otherwise.
1169
1170 sub smtp_auth_maybe {
1171         if (!defined $smtp_authuser || $auth) {
1172                 return 1;
1173         }
1174
1175         # Workaround AUTH PLAIN/LOGIN interaction defect
1176         # with Authen::SASL::Cyrus
1177         eval {
1178                 require Authen::SASL;
1179                 Authen::SASL->import(qw(Perl));
1180         };
1181
1182         # Check mechanism naming as defined in:
1183         # https://tools.ietf.org/html/rfc4422#page-8
1184         if ($smtp_auth && $smtp_auth !~ /^(\b[A-Z0-9-_]{1,20}\s*)*$/) {
1185                 die "invalid smtp auth: '${smtp_auth}'";
1186         }
1187
1188         # TODO: Authentication may fail not because credentials were
1189         # invalid but due to other reasons, in which we should not
1190         # reject credentials.
1191         $auth = Git::credential({
1192                 'protocol' => 'smtp',
1193                 'host' => smtp_host_string(),
1194                 'username' => $smtp_authuser,
1195                 # if there's no password, "git credential fill" will
1196                 # give us one, otherwise it'll just pass this one.
1197                 'password' => $smtp_authpass
1198         }, sub {
1199                 my $cred = shift;
1200
1201                 if ($smtp_auth) {
1202                         my $sasl = Authen::SASL->new(
1203                                 mechanism => $smtp_auth,
1204                                 callback => {
1205                                         user => $cred->{'username'},
1206                                         pass => $cred->{'password'},
1207                                         authname => $cred->{'username'},
1208                                 }
1209                         );
1210
1211                         return !!$smtp->auth($sasl);
1212                 }
1213
1214                 return !!$smtp->auth($cred->{'username'}, $cred->{'password'});
1215         });
1216
1217         return $auth;
1218 }
1219
1220 sub ssl_verify_params {
1221         eval {
1222                 require IO::Socket::SSL;
1223                 IO::Socket::SSL->import(qw/SSL_VERIFY_PEER SSL_VERIFY_NONE/);
1224         };
1225         if ($@) {
1226                 print STDERR "Not using SSL_VERIFY_PEER due to out-of-date IO::Socket::SSL.\n";
1227                 return;
1228         }
1229
1230         if (!defined $smtp_ssl_cert_path) {
1231                 # use the OpenSSL defaults
1232                 return (SSL_verify_mode => SSL_VERIFY_PEER());
1233         }
1234
1235         if ($smtp_ssl_cert_path eq "") {
1236                 return (SSL_verify_mode => SSL_VERIFY_NONE());
1237         } elsif (-d $smtp_ssl_cert_path) {
1238                 return (SSL_verify_mode => SSL_VERIFY_PEER(),
1239                         SSL_ca_path => $smtp_ssl_cert_path);
1240         } elsif (-f $smtp_ssl_cert_path) {
1241                 return (SSL_verify_mode => SSL_VERIFY_PEER(),
1242                         SSL_ca_file => $smtp_ssl_cert_path);
1243         } else {
1244                 die sprintf(__("CA path \"%s\" does not exist"), $smtp_ssl_cert_path);
1245         }
1246 }
1247
1248 sub file_name_is_absolute {
1249         my ($path) = @_;
1250
1251         # msys does not grok DOS drive-prefixes
1252         if ($^O eq 'msys') {
1253                 return ($path =~ m#^/# || $path =~ m#^[a-zA-Z]\:#)
1254         }
1255
1256         require File::Spec::Functions;
1257         return File::Spec::Functions::file_name_is_absolute($path);
1258 }
1259
1260 # Returns 1 if the message was sent, and 0 otherwise.
1261 # In actuality, the whole program dies when there
1262 # is an error sending a message.
1263
1264 sub send_message {
1265         my @recipients = unique_email_list(@to);
1266         @cc = (grep { my $cc = extract_valid_address_or_die($_);
1267                       not grep { $cc eq $_ || $_ =~ /<\Q${cc}\E>$/ } @recipients
1268                     }
1269                @cc);
1270         my $to = join (",\n\t", @recipients);
1271         @recipients = unique_email_list(@recipients,@cc,@bcclist);
1272         @recipients = (map { extract_valid_address_or_die($_) } @recipients);
1273         my $date = format_2822_time($time++);
1274         my $gitversion = '@@GIT_VERSION@@';
1275         if ($gitversion =~ m/..GIT_VERSION../) {
1276             $gitversion = Git::version();
1277         }
1278
1279         my $cc = join(",\n\t", unique_email_list(@cc));
1280         my $ccline = "";
1281         if ($cc ne '') {
1282                 $ccline = "\nCc: $cc";
1283         }
1284         make_message_id() unless defined($message_id);
1285
1286         my $header = "From: $sender
1287 To: $to${ccline}
1288 Subject: $subject
1289 Date: $date
1290 Message-Id: $message_id
1291 ";
1292         if ($use_xmailer) {
1293                 $header .= "X-Mailer: git-send-email $gitversion\n";
1294         }
1295         if ($reply_to) {
1296
1297                 $header .= "In-Reply-To: $reply_to\n";
1298                 $header .= "References: $references\n";
1299         }
1300         if (@xh) {
1301                 $header .= join("\n", @xh) . "\n";
1302         }
1303
1304         my @sendmail_parameters = ('-i', @recipients);
1305         my $raw_from = $sender;
1306         if (defined $envelope_sender && $envelope_sender ne "auto") {
1307                 $raw_from = $envelope_sender;
1308         }
1309         $raw_from = extract_valid_address($raw_from);
1310         unshift (@sendmail_parameters,
1311                         '-f', $raw_from) if(defined $envelope_sender);
1312
1313         if ($needs_confirm && !$dry_run) {
1314                 print "\n$header\n";
1315                 if ($needs_confirm eq "inform") {
1316                         $confirm_unconfigured = 0; # squelch this message for the rest of this run
1317                         $ask_default = "y"; # assume yes on EOF since user hasn't explicitly asked for confirmation
1318                         print __ <<EOF ;
1319     The Cc list above has been expanded by additional
1320     addresses found in the patch commit message. By default
1321     send-email prompts before sending whenever this occurs.
1322     This behavior is controlled by the sendemail.confirm
1323     configuration setting.
1324
1325     For additional information, run 'git send-email --help'.
1326     To retain the current behavior, but squelch this message,
1327     run 'git config --global sendemail.confirm auto'.
1328
1329 EOF
1330                 }
1331                 # TRANSLATORS: Make sure to include [y] [n] [q] [a] in your
1332                 # translation. The program will only accept English input
1333                 # at this point.
1334                 $_ = ask(__("Send this email? ([y]es|[n]o|[q]uit|[a]ll): "),
1335                          valid_re => qr/^(?:yes|y|no|n|quit|q|all|a)/i,
1336                          default => $ask_default);
1337                 die __("Send this email reply required") unless defined $_;
1338                 if (/^n/i) {
1339                         return 0;
1340                 } elsif (/^q/i) {
1341                         cleanup_compose_files();
1342                         exit(0);
1343                 } elsif (/^a/i) {
1344                         $confirm = 'never';
1345                 }
1346         }
1347
1348         unshift (@sendmail_parameters, @smtp_server_options);
1349
1350         if ($dry_run) {
1351                 # We don't want to send the email.
1352         } elsif (file_name_is_absolute($smtp_server)) {
1353                 my $pid = open my $sm, '|-';
1354                 defined $pid or die $!;
1355                 if (!$pid) {
1356                         exec($smtp_server, @sendmail_parameters) or die $!;
1357                 }
1358                 print $sm "$header\n$message";
1359                 close $sm or die $!;
1360         } else {
1361
1362                 if (!defined $smtp_server) {
1363                         die __("The required SMTP server is not properly defined.")
1364                 }
1365
1366                 if ($smtp_encryption eq 'ssl') {
1367                         $smtp_server_port ||= 465; # ssmtp
1368                         require Net::SMTP::SSL;
1369                         $smtp_domain ||= maildomain();
1370                         require IO::Socket::SSL;
1371
1372                         # Suppress "variable accessed once" warning.
1373                         {
1374                                 no warnings 'once';
1375                                 $IO::Socket::SSL::DEBUG = 1;
1376                         }
1377
1378                         # Net::SMTP::SSL->new() does not forward any SSL options
1379                         IO::Socket::SSL::set_client_defaults(
1380                                 ssl_verify_params());
1381                         $smtp ||= Net::SMTP::SSL->new($smtp_server,
1382                                                       Hello => $smtp_domain,
1383                                                       Port => $smtp_server_port,
1384                                                       Debug => $debug_net_smtp);
1385                 }
1386                 else {
1387                         require Net::SMTP;
1388                         $smtp_domain ||= maildomain();
1389                         $smtp_server_port ||= 25;
1390                         $smtp ||= Net::SMTP->new($smtp_server,
1391                                                  Hello => $smtp_domain,
1392                                                  Debug => $debug_net_smtp,
1393                                                  Port => $smtp_server_port);
1394                         if ($smtp_encryption eq 'tls' && $smtp) {
1395                                 require Net::SMTP::SSL;
1396                                 $smtp->command('STARTTLS');
1397                                 $smtp->response();
1398                                 if ($smtp->code == 220) {
1399                                         $smtp = Net::SMTP::SSL->start_SSL($smtp,
1400                                                                           ssl_verify_params())
1401                                                 or die "STARTTLS failed! ".IO::Socket::SSL::errstr();
1402                                         $smtp_encryption = '';
1403                                         # Send EHLO again to receive fresh
1404                                         # supported commands
1405                                         $smtp->hello($smtp_domain);
1406                                 } else {
1407                                         die sprintf(__("Server does not support STARTTLS! %s"), $smtp->message);
1408                                 }
1409                         }
1410                 }
1411
1412                 if (!$smtp) {
1413                         die __("Unable to initialize SMTP properly. Check config and use --smtp-debug."),
1414                             " VALUES: server=$smtp_server ",
1415                             "encryption=$smtp_encryption ",
1416                             "hello=$smtp_domain",
1417                             defined $smtp_server_port ? " port=$smtp_server_port" : "";
1418                 }
1419
1420                 smtp_auth_maybe or die $smtp->message;
1421
1422                 $smtp->mail( $raw_from ) or die $smtp->message;
1423                 $smtp->to( @recipients ) or die $smtp->message;
1424                 $smtp->data or die $smtp->message;
1425                 $smtp->datasend("$header\n") or die $smtp->message;
1426                 my @lines = split /^/, $message;
1427                 foreach my $line (@lines) {
1428                         $smtp->datasend("$line") or die $smtp->message;
1429                 }
1430                 $smtp->dataend() or die $smtp->message;
1431                 $smtp->code =~ /250|200/ or die sprintf(__("Failed to send %s\n"), $subject).$smtp->message;
1432         }
1433         if ($quiet) {
1434                 printf($dry_run ? __("Dry-Sent %s\n") : __("Sent %s\n"), $subject);
1435         } else {
1436                 print($dry_run ? __("Dry-OK. Log says:\n") : __("OK. Log says:\n"));
1437                 if (!file_name_is_absolute($smtp_server)) {
1438                         print "Server: $smtp_server\n";
1439                         print "MAIL FROM:<$raw_from>\n";
1440                         foreach my $entry (@recipients) {
1441                             print "RCPT TO:<$entry>\n";
1442                         }
1443                 } else {
1444                         print "Sendmail: $smtp_server ".join(' ',@sendmail_parameters)."\n";
1445                 }
1446                 print $header, "\n";
1447                 if ($smtp) {
1448                         print __("Result: "), $smtp->code, ' ',
1449                                 ($smtp->message =~ /\n([^\n]+\n)$/s), "\n";
1450                 } else {
1451                         print __("Result: OK\n");
1452                 }
1453         }
1454
1455         return 1;
1456 }
1457
1458 $reply_to = $initial_reply_to;
1459 $references = $initial_reply_to || '';
1460 $subject = $initial_subject;
1461 $message_num = 0;
1462
1463 foreach my $t (@files) {
1464         open my $fh, "<", $t or die sprintf(__("can't open file %s"), $t);
1465
1466         my $author = undef;
1467         my $sauthor = undef;
1468         my $author_encoding;
1469         my $has_content_type;
1470         my $body_encoding;
1471         my $xfer_encoding;
1472         my $has_mime_version;
1473         @to = ();
1474         @cc = ();
1475         @xh = ();
1476         my $input_format = undef;
1477         my @header = ();
1478         $message = "";
1479         $message_num++;
1480         # First unfold multiline header fields
1481         while(<$fh>) {
1482                 last if /^\s*$/;
1483                 if (/^\s+\S/ and @header) {
1484                         chomp($header[$#header]);
1485                         s/^\s+/ /;
1486                         $header[$#header] .= $_;
1487             } else {
1488                         push(@header, $_);
1489                 }
1490         }
1491         # Now parse the header
1492         foreach(@header) {
1493                 if (/^From /) {
1494                         $input_format = 'mbox';
1495                         next;
1496                 }
1497                 chomp;
1498                 if (!defined $input_format && /^[-A-Za-z]+:\s/) {
1499                         $input_format = 'mbox';
1500                 }
1501
1502                 if (defined $input_format && $input_format eq 'mbox') {
1503                         if (/^Subject:\s+(.*)$/i) {
1504                                 $subject = $1;
1505                         }
1506                         elsif (/^From:\s+(.*)$/i) {
1507                                 ($author, $author_encoding) = unquote_rfc2047($1);
1508                                 $sauthor = sanitize_address($author);
1509                                 next if $suppress_cc{'author'};
1510                                 next if $suppress_cc{'self'} and $sauthor eq $sender;
1511                                 printf(__("(mbox) Adding cc: %s from line '%s'\n"),
1512                                         $1, $_) unless $quiet;
1513                                 push @cc, $1;
1514                         }
1515                         elsif (/^To:\s+(.*)$/i) {
1516                                 foreach my $addr (parse_address_line($1)) {
1517                                         printf(__("(mbox) Adding to: %s from line '%s'\n"),
1518                                                 $addr, $_) unless $quiet;
1519                                         push @to, $addr;
1520                                 }
1521                         }
1522                         elsif (/^Cc:\s+(.*)$/i) {
1523                                 foreach my $addr (parse_address_line($1)) {
1524                                         my $qaddr = unquote_rfc2047($addr);
1525                                         my $saddr = sanitize_address($qaddr);
1526                                         if ($saddr eq $sender) {
1527                                                 next if ($suppress_cc{'self'});
1528                                         } else {
1529                                                 next if ($suppress_cc{'cc'});
1530                                         }
1531                                         printf(__("(mbox) Adding cc: %s from line '%s'\n"),
1532                                                 $addr, $_) unless $quiet;
1533                                         push @cc, $addr;
1534                                 }
1535                         }
1536                         elsif (/^Content-type:/i) {
1537                                 $has_content_type = 1;
1538                                 if (/charset="?([^ "]+)/) {
1539                                         $body_encoding = $1;
1540                                 }
1541                                 push @xh, $_;
1542                         }
1543                         elsif (/^MIME-Version/i) {
1544                                 $has_mime_version = 1;
1545                                 push @xh, $_;
1546                         }
1547                         elsif (/^Message-Id: (.*)/i) {
1548                                 $message_id = $1;
1549                         }
1550                         elsif (/^Content-Transfer-Encoding: (.*)/i) {
1551                                 $xfer_encoding = $1 if not defined $xfer_encoding;
1552                         }
1553                         elsif (!/^Date:\s/i && /^[-A-Za-z]+:\s+\S/) {
1554                                 push @xh, $_;
1555                         }
1556
1557                 } else {
1558                         # In the traditional
1559                         # "send lots of email" format,
1560                         # line 1 = cc
1561                         # line 2 = subject
1562                         # So let's support that, too.
1563                         $input_format = 'lots';
1564                         if (@cc == 0 && !$suppress_cc{'cc'}) {
1565                                 printf(__("(non-mbox) Adding cc: %s from line '%s'\n"),
1566                                         $_, $_) unless $quiet;
1567                                 push @cc, $_;
1568                         } elsif (!defined $subject) {
1569                                 $subject = $_;
1570                         }
1571                 }
1572         }
1573         # Now parse the message body
1574         while(<$fh>) {
1575                 $message .=  $_;
1576                 if (/^(Signed-off-by|Cc): ([^>]*>?)/i) {
1577                         chomp;
1578                         my ($what, $c) = ($1, $2);
1579                         chomp $c;
1580                         my $sc = sanitize_address($c);
1581                         if ($sc eq $sender) {
1582                                 next if ($suppress_cc{'self'});
1583                         } else {
1584                                 next if $suppress_cc{'sob'} and $what =~ /Signed-off-by/i;
1585                                 next if $suppress_cc{'bodycc'} and $what =~ /Cc/i;
1586                         }
1587                         push @cc, $c;
1588                         printf(__("(body) Adding cc: %s from line '%s'\n"),
1589                                 $c, $_) unless $quiet;
1590                 }
1591         }
1592         close $fh;
1593
1594         push @to, recipients_cmd("to-cmd", "to", $to_cmd, $t)
1595                 if defined $to_cmd;
1596         push @cc, recipients_cmd("cc-cmd", "cc", $cc_cmd, $t)
1597                 if defined $cc_cmd && !$suppress_cc{'cccmd'};
1598
1599         if ($broken_encoding{$t} && !$has_content_type) {
1600                 $xfer_encoding = '8bit' if not defined $xfer_encoding;
1601                 $has_content_type = 1;
1602                 push @xh, "Content-Type: text/plain; charset=$auto_8bit_encoding";
1603                 $body_encoding = $auto_8bit_encoding;
1604         }
1605
1606         if ($broken_encoding{$t} && !is_rfc2047_quoted($subject)) {
1607                 $subject = quote_subject($subject, $auto_8bit_encoding);
1608         }
1609
1610         if (defined $sauthor and $sauthor ne $sender) {
1611                 $message = "From: $author\n\n$message";
1612                 if (defined $author_encoding) {
1613                         if ($has_content_type) {
1614                                 if ($body_encoding eq $author_encoding) {
1615                                         # ok, we already have the right encoding
1616                                 }
1617                                 else {
1618                                         # uh oh, we should re-encode
1619                                 }
1620                         }
1621                         else {
1622                                 $xfer_encoding = '8bit' if not defined $xfer_encoding;
1623                                 $has_content_type = 1;
1624                                 push @xh,
1625                                   "Content-Type: text/plain; charset=$author_encoding";
1626                         }
1627                 }
1628         }
1629         if (defined $target_xfer_encoding) {
1630                 $xfer_encoding = '8bit' if not defined $xfer_encoding;
1631                 $message = apply_transfer_encoding(
1632                         $message, $xfer_encoding, $target_xfer_encoding);
1633                 $xfer_encoding = $target_xfer_encoding;
1634         }
1635         if (defined $xfer_encoding) {
1636                 push @xh, "Content-Transfer-Encoding: $xfer_encoding";
1637         }
1638         if (defined $xfer_encoding or $has_content_type) {
1639                 unshift @xh, 'MIME-Version: 1.0' unless $has_mime_version;
1640         }
1641
1642         $needs_confirm = (
1643                 $confirm eq "always" or
1644                 ($confirm =~ /^(?:auto|cc)$/ && @cc) or
1645                 ($confirm =~ /^(?:auto|compose)$/ && $compose && $message_num == 1));
1646         $needs_confirm = "inform" if ($needs_confirm && $confirm_unconfigured && @cc);
1647
1648         @to = process_address_list(@to);
1649         @cc = process_address_list(@cc);
1650
1651         @to = (@initial_to, @to);
1652         @cc = (@initial_cc, @cc);
1653
1654         if ($message_num == 1) {
1655                 if (defined $cover_cc and $cover_cc) {
1656                         @initial_cc = @cc;
1657                 }
1658                 if (defined $cover_to and $cover_to) {
1659                         @initial_to = @to;
1660                 }
1661         }
1662
1663         my $message_was_sent = send_message();
1664
1665         # set up for the next message
1666         if ($thread && $message_was_sent &&
1667                 ($chain_reply_to || !defined $reply_to || length($reply_to) == 0 ||
1668                 $message_num == 1)) {
1669                 $reply_to = $message_id;
1670                 if (length $references > 0) {
1671                         $references .= "\n $message_id";
1672                 } else {
1673                         $references = "$message_id";
1674                 }
1675         }
1676         $message_id = undef;
1677         $num_sent++;
1678         if (defined $batch_size && $num_sent == $batch_size) {
1679                 $num_sent = 0;
1680                 $smtp->quit if defined $smtp;
1681                 undef $smtp;
1682                 undef $auth;
1683                 sleep($relogin_delay) if defined $relogin_delay;
1684         }
1685 }
1686
1687 # Execute a command (e.g. $to_cmd) to get a list of email addresses
1688 # and return a results array
1689 sub recipients_cmd {
1690         my ($prefix, $what, $cmd, $file) = @_;
1691
1692         my @addresses = ();
1693         open my $fh, "-|", "$cmd \Q$file\E"
1694             or die sprintf(__("(%s) Could not execute '%s'"), $prefix, $cmd);
1695         while (my $address = <$fh>) {
1696                 $address =~ s/^\s*//g;
1697                 $address =~ s/\s*$//g;
1698                 $address = sanitize_address($address);
1699                 next if ($address eq $sender and $suppress_cc{'self'});
1700                 push @addresses, $address;
1701                 printf(__("(%s) Adding %s: %s from: '%s'\n"),
1702                        $prefix, $what, $address, $cmd) unless $quiet;
1703                 }
1704         close $fh
1705             or die sprintf(__("(%s) failed to close pipe to '%s'"), $prefix, $cmd);
1706         return @addresses;
1707 }
1708
1709 cleanup_compose_files();
1710
1711 sub cleanup_compose_files {
1712         unlink($compose_filename, $compose_filename . ".final") if $compose;
1713 }
1714
1715 $smtp->quit if $smtp;
1716
1717 sub apply_transfer_encoding {
1718         my $message = shift;
1719         my $from = shift;
1720         my $to = shift;
1721
1722         return $message if ($from eq $to and $from ne '7bit');
1723
1724         require MIME::QuotedPrint;
1725         require MIME::Base64;
1726
1727         $message = MIME::QuotedPrint::decode($message)
1728                 if ($from eq 'quoted-printable');
1729         $message = MIME::Base64::decode($message)
1730                 if ($from eq 'base64');
1731
1732         die __("cannot send message as 7bit")
1733                 if ($to eq '7bit' and $message =~ /[^[:ascii:]]/);
1734         return $message
1735                 if ($to eq '7bit' or $to eq '8bit');
1736         return MIME::QuotedPrint::encode($message, "\n", 0)
1737                 if ($to eq 'quoted-printable');
1738         return MIME::Base64::encode($message, "\n")
1739                 if ($to eq 'base64');
1740         die __("invalid transfer encoding");
1741 }
1742
1743 sub unique_email_list {
1744         my %seen;
1745         my @emails;
1746
1747         foreach my $entry (@_) {
1748                 my $clean = extract_valid_address_or_die($entry);
1749                 $seen{$clean} ||= 0;
1750                 next if $seen{$clean}++;
1751                 push @emails, $entry;
1752         }
1753         return @emails;
1754 }
1755
1756 sub validate_patch {
1757         my $fn = shift;
1758         open(my $fh, '<', $fn)
1759                 or die sprintf(__("unable to open %s: %s\n"), $fn, $!);
1760         while (my $line = <$fh>) {
1761                 if (length($line) > 998) {
1762                         return sprintf(__("%s: patch contains a line longer than 998 characters"), $.);
1763                 }
1764         }
1765         return;
1766 }
1767
1768 sub handle_backup {
1769         my ($last, $lastlen, $file, $known_suffix) = @_;
1770         my ($suffix, $skip);
1771
1772         $skip = 0;
1773         if (defined $last &&
1774             ($lastlen < length($file)) &&
1775             (substr($file, 0, $lastlen) eq $last) &&
1776             ($suffix = substr($file, $lastlen)) !~ /^[a-z0-9]/i) {
1777                 if (defined $known_suffix && $suffix eq $known_suffix) {
1778                         printf(__("Skipping %s with backup suffix '%s'.\n"), $file, $known_suffix);
1779                         $skip = 1;
1780                 } else {
1781                         # TRANSLATORS: please keep "[y|N]" as is.
1782                         my $answer = ask(sprintf(__("Do you really want to send %s? [y|N]: "), $file),
1783                                          valid_re => qr/^(?:y|n)/i,
1784                                          default => 'n');
1785                         $skip = ($answer ne 'y');
1786                         if ($skip) {
1787                                 $known_suffix = $suffix;
1788                         }
1789                 }
1790         }
1791         return ($skip, $known_suffix);
1792 }
1793
1794 sub handle_backup_files {
1795         my @file = @_;
1796         my ($last, $lastlen, $known_suffix, $skip, @result);
1797         for my $file (@file) {
1798                 ($skip, $known_suffix) = handle_backup($last, $lastlen,
1799                                                        $file, $known_suffix);
1800                 push @result, $file unless $skip;
1801                 $last = $file;
1802                 $lastlen = length($file);
1803         }
1804         return @result;
1805 }
1806
1807 sub file_has_nonascii {
1808         my $fn = shift;
1809         open(my $fh, '<', $fn)
1810                 or die sprintf(__("unable to open %s: %s\n"), $fn, $!);
1811         while (my $line = <$fh>) {
1812                 return 1 if $line =~ /[^[:ascii:]]/;
1813         }
1814         return 0;
1815 }
1816
1817 sub body_or_subject_has_nonascii {
1818         my $fn = shift;
1819         open(my $fh, '<', $fn)
1820                 or die sprintf(__("unable to open %s: %s\n"), $fn, $!);
1821         while (my $line = <$fh>) {
1822                 last if $line =~ /^$/;
1823                 return 1 if $line =~ /^Subject.*[^[:ascii:]]/;
1824         }
1825         while (my $line = <$fh>) {
1826                 return 1 if $line =~ /[^[:ascii:]]/;
1827         }
1828         return 0;
1829 }