Documentation: help: describe 'man.viewer' config variable
[gitweb.git] / git-send-email.perl
index e5d67f1b6c3237ff67673037be5ca8997cdb191d..be4a20d7cd562e9b00d93fe71313aed70afe50af 100755 (executable)
@@ -24,8 +24,6 @@
 use Term::ANSIColor;
 use Git;
 
-$SIG{INT} = sub { print color("reset"), "\n"; exit };
-
 package FakeTerm;
 sub new {
        my ($class, $reason) = @_;
@@ -88,6 +86,12 @@ sub usage {
 
    --smtp-ssl     If set, connects to the SMTP server using SSL.
 
+   --suppress-cc  Suppress the specified category of auto-CC.  The category
+                 can be one of 'author' for the patch author, 'self' to
+                 avoid copying yourself, 'sob' for Signed-off-by lines,
+                 'cccmd' for the output of the cccmd, or 'all' to suppress
+                 all of these.
+
    --suppress-from Suppress sending emails to yourself. Defaults to off.
 
    --thread       Specify that the "In-Reply-To:" header should be set on all
@@ -157,7 +161,7 @@ sub format_2822_time {
 
 # Variables we fill in automatically, or via prompting:
 my (@to,@cc,@initial_cc,@bcclist,@xh,
-       $initial_reply_to,$initial_subject,@files,$author,$sender,$compose,$time);
+       $initial_reply_to,$initial_subject,@files,$author,$sender,$smtp_authpass,$compose,$time);
 
 my $envelope_sender;
 
@@ -179,15 +183,16 @@ sub format_2822_time {
 
 # Variables with corresponding config settings
 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 ($smtp_server, $smtp_server_port, $smtp_authuser, $smtp_ssl);
 my ($identity, $aliasfiletype, @alias_files, @smtp_host_parts);
 my ($no_validate);
+my (@suppress_cc);
 
 my %config_bool_settings = (
     "thread" => [\$thread, 1],
     "chainreplyto" => [\$chain_reply_to, 1],
-    "suppressfrom" => [\$suppress_from, 0],
-    "signedoffcc" => [\$signed_off_cc, 1],
+    "suppressfrom" => [\$suppress_from, undef],
+    "signedoffcc" => [\$signed_off_cc, undef],
     "smtpssl" => [\$smtp_ssl, 0],
 );
 
@@ -201,8 +206,32 @@ sub format_2822_time {
     "aliasfiletype" => \$aliasfiletype,
     "bcc" => \@bcclist,
     "aliasesfile" => \@alias_files,
+    "suppresscc" => \@suppress_cc,
 );
 
+# Handle Uncouth Termination
+sub signal_handler {
+
+       # Make text normal
+       print color("reset"), "\n";
+
+       # SMTP password masked
+       system "stty echo";
+
+       # tmp files from --compose
+       if (-e $compose_filename) {
+               print "'$compose_filename' contains an intermediate version of the email you were composing.\n";
+       }
+       if (-e ($compose_filename . ".final")) {
+               print "'$compose_filename.final' contains the composed email.\n"
+       }
+
+       exit;
+};
+
+$SIG{TERM} = \&signal_handler;
+$SIG{INT}  = \&signal_handler;
+
 # Begin by accumulating all the variables (defined above), that we will end up
 # needing, first, from the command line:
 
@@ -216,13 +245,14 @@ sub format_2822_time {
                    "smtp-server=s" => \$smtp_server,
                    "smtp-server-port=s" => \$smtp_server_port,
                    "smtp-user=s" => \$smtp_authuser,
-                   "smtp-pass=s" => \$smtp_authpass,
+                   "smtp-pass:s" => \$smtp_authpass,
                    "smtp-ssl!" => \$smtp_ssl,
                    "identity=s" => \$identity,
                    "compose" => \$compose,
                    "quiet" => \$quiet,
                    "cc-cmd=s" => \$cc_cmd,
                    "suppress-from!" => \$suppress_from,
+                   "suppress-cc=s" => \@suppress_cc,
                    "signed-off-cc|signed-off-by-cc!" => \$signed_off_cc,
                    "dry-run" => \$dry_run,
                    "envelope-sender=s" => \$envelope_sender,
@@ -268,6 +298,35 @@ sub read_config {
        ${$setting->[0]} = $setting->[1] unless (defined (${$setting->[0]}));
 }
 
+# Set CC suppressions
+my(%suppress_cc);
+if (@suppress_cc) {
+       foreach my $entry (@suppress_cc) {
+               die "Unknown --suppress-cc field: '$entry'\n"
+                       unless $entry =~ /^(all|cccmd|cc|author|self|sob)$/;
+               $suppress_cc{$entry} = 1;
+       }
+}
+
+if ($suppress_cc{'all'}) {
+       foreach my $entry (qw (ccmd cc author self sob)) {
+               $suppress_cc{$entry} = 1;
+       }
+       delete $suppress_cc{'all'};
+}
+
+# If explicit old-style ones are specified, they trump --suppress-cc.
+$suppress_cc{'self'} = $suppress_from if defined $suppress_from;
+$suppress_cc{'sob'} = !$signed_off_cc if defined $signed_off_cc;
+
+# Debugging, print out the suppressions.
+if (0) {
+       print "suppressions:\n";
+       foreach my $entry (keys %suppress_cc) {
+               printf "  %-5s -> $suppress_cc{$entry}\n", $entry;
+       }
+}
+
 my ($repoauthor) = $repo->ident_person('author');
 my ($repocommitter) = $repo->ident_person('committer');
 
@@ -357,9 +416,12 @@ sub read_config {
 my $prompting = 0;
 if (!defined $sender) {
        $sender = $repoauthor || $repocommitter;
-       do {
+
+       while (1) {
                $_ = $term->readline("Who should the emails appear to be from? [$sender] ");
-       } while (!defined $_);
+               last if defined $_;
+               print "\n";
+       }
 
        $sender = $_ if ($_);
        print "Emails will be sent from: ", $sender, "\n";
@@ -367,10 +429,14 @@ sub read_config {
 }
 
 if (!@to) {
-       do {
-               $_ = $term->readline("Who should the emails be sent to? ",
-                               "");
-       } while (!defined $_);
+
+
+       while (1) {
+               $_ = $term->readline("Who should the emails be sent to? ", "");
+               last if defined $_;
+               print "\n";
+       }
+
        my $to = $_;
        push @to, split /,/, $to;
        $prompting++;
@@ -392,19 +458,22 @@ sub expand_aliases {
 @bcclist = expand_aliases(@bcclist);
 
 if (!defined $initial_subject && $compose) {
-       do {
-               $_ = $term->readline("What subject should the initial email start with? ",
-                       $initial_subject);
-       } while (!defined $_);
+       while (1) {
+               $_ = $term->readline("What subject should the initial email start with? ", $initial_subject);
+               last if defined $_;
+               print "\n";
+       }
+
        $initial_subject = $_;
        $prompting++;
 }
 
 if ($thread && !defined $initial_reply_to && $prompting) {
-       do {
-               $_= $term->readline("Message-ID to be used as In-Reply-To for the first email? ",
-                       $initial_reply_to);
-       } while (!defined $_);
+       while (1) {
+               $_= $term->readline("Message-ID to be used as In-Reply-To for the first email? ", $initial_reply_to);
+               last if defined $_;
+               print "\n";
+       }
 
        $initial_reply_to = $_;
 }
@@ -456,9 +525,11 @@ sub expand_aliases {
        close(C);
        close(C2);
 
-       do {
+       while (1) {
                $_ = $term->readline("Send this email? (y|n) ");
-       } while (!defined $_);
+               last if defined $_;
+               print "\n";
+       }
 
        if (uc substr($_,0,1) ne 'Y') {
                cleanup_compose_files();
@@ -650,9 +721,26 @@ sub send_message
                        die "Unable to initialize SMTP properly.  Is there something wrong with your config?";
                }
 
-               if ((defined $smtp_authuser) && (defined $smtp_authpass)) {
+               if (defined $smtp_authuser) {
+
+                       if (!defined $smtp_authpass) {
+
+                               system "stty -echo";
+
+                               do {
+                                       print "Password: ";
+                                       $_ = <STDIN>;
+                                       print "\n";
+                               } while (!defined $_);
+
+                               chomp($smtp_authpass = $_);
+
+                               system "stty echo";
+                       }
+
                        $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;
                $smtp->data or die $smtp->message;
@@ -714,11 +802,14 @@ sub send_message
 
                                } elsif (/^(Cc|From):\s+(.*)$/) {
                                        if (unquote_rfc2047($2) eq $sender) {
-                                               next if ($suppress_from);
+                                               next if ($suppress_cc{'self'});
                                        }
                                        elsif ($1 eq 'From') {
                                                ($author, $author_encoding)
                                                  = unquote_rfc2047($2);
+                                               next if ($suppress_cc{'author'});
+                                       } else {
+                                               next if ($suppress_cc{'cc'});
                                        }
                                        printf("(mbox) Adding cc: %s from line '%s'\n",
                                                $2, $_) unless $quiet;
@@ -745,7 +836,7 @@ sub send_message
                                # line 2 = subject
                                # So let's support that, too.
                                $input_format = 'lots';
-                               if (@cc == 0) {
+                               if (@cc == 0 && !$suppress_cc{'cc'}) {
                                        printf("(non-mbox) Adding cc: %s from line '%s'\n",
                                                $_, $_) unless $quiet;
 
@@ -762,10 +853,12 @@ sub send_message
                        }
                } else {
                        $message .=  $_;
-                       if (/^(Signed-off-by|Cc): (.*)$/i && $signed_off_cc) {
+                       if (/^(Signed-off-by|Cc): (.*)$/i) {
+                               next if ($suppress_cc{'sob'});
+                               chomp;
                                my $c = $2;
                                chomp $c;
-                               next if ($c eq $sender and $suppress_from);
+                               next if ($c eq $sender and $suppress_cc{'self'});
                                push @cc, $c;
                                printf("(sob) Adding cc: %s from line '%s'\n",
                                        $c, $_) unless $quiet;
@@ -774,7 +867,7 @@ sub send_message
        }
        close F;
 
-       if (defined $cc_cmd) {
+       if (defined $cc_cmd && !$suppress_cc{'cccmd'}) {
                open(F, "$cc_cmd $t |")
                        or die "(cc-cmd) Could not execute '$cc_cmd'";
                while(<F>) {