--[no-]bcc <str> * Email Bcc:
--subject <str> * Email "Subject:"
--in-reply-to <str> * Email "In-Reply-To:"
+ --[no-]xmailer * Add "X-Mailer:" header (default).
--[no-]annotate * Review each patch that will be sent in an editor.
--compose * Open an editor for introduction.
--compose-encoding <str> * Encoding to assume for introduction.
my $smtp;
my $auth;
+# Regexes for RFC 2047 productions.
+my $re_token = qr/[^][()<>@,;:\\"\/?.= \000-\037\177-\377]+/;
+my $re_encoded_text = qr/[^? \000-\037\177-\377]+/;
+my $re_encoded_word = qr/=\?($re_token)\?($re_token)\?($re_encoded_text)\?=/;
+
# Variables we fill in automatically, or via prompting:
my (@to,$no_to,@initial_to,@cc,$no_cc,@initial_cc,@bcclist,$no_bcc,@xh,
$initial_reply_to,$initial_subject,@files,
- $author,$sender,$smtp_authpass,$annotate,$compose,$time);
+ $author,$sender,$smtp_authpass,$annotate,$use_xmailer,$compose,$time);
my $envelope_sender;
"signedoffcc" => [\$signed_off_by_cc, undef], # Deprecated
"validate" => [\$validate, 1],
"multiedit" => [\$multiedit, undef],
- "annotate" => [\$annotate, undef]
+ "annotate" => [\$annotate, undef],
+ "xmailer" => [\$use_xmailer, 1]
);
my %config_settings = (
"bcc=s" => \@bcclist,
"no-bcc" => \$no_bcc,
"chain-reply-to!" => \$chain_reply_to,
+ "no-chain-reply-to" => sub {$chain_reply_to = 0},
"smtp-server=s" => \$smtp_server,
"smtp-server-option=s" => \@smtp_server_options,
"smtp-server-port=s" => \$smtp_server_port,
"smtp-domain:s" => \$smtp_domain,
"identity=s" => \$identity,
"annotate!" => \$annotate,
+ "no-annotate" => sub {$annotate = 0},
"compose" => \$compose,
"quiet" => \$quiet,
"cc-cmd=s" => \$cc_cmd,
"suppress-from!" => \$suppress_from,
+ "no-suppress-from" => sub {$suppress_from = 0},
"suppress-cc=s" => \@suppress_cc,
"signed-off-cc|signed-off-by-cc!" => \$signed_off_by_cc,
+ "no-signed-off-cc|no-signed-off-by-cc" => sub {$signed_off_by_cc = 0},
"cc-cover|cc-cover!" => \$cover_cc,
+ "no-cc-cover" => sub {$cover_cc = 0},
"to-cover|to-cover!" => \$cover_to,
+ "no-to-cover" => sub {$cover_to = 0},
"confirm=s" => \$confirm,
"dry-run" => \$dry_run,
"envelope-sender=s" => \$envelope_sender,
"thread!" => \$thread,
+ "no-thread" => sub {$thread = 0},
"validate!" => \$validate,
+ "no-validate" => sub {$validate = 0},
"transfer-encoding=s" => \$target_xfer_encoding,
"format-patch!" => \$format_patch,
+ "no-format-patch" => sub {$format_patch = 0},
"8bit-encoding=s" => \$auto_8bit_encoding,
"compose-encoding=s" => \$compose_encoding,
"force" => \$force,
+ "xmailer!" => \$use_xmailer,
+ "no-xmailer" => sub {$use_xmailer = 0},
);
usage() if $help;
print " $f\n";
}
$auto_8bit_encoding = ask("Which 8bit encoding should I declare [UTF-8]? ",
+ valid_re => qr/.{4}/, confirm_only => 1,
default => "UTF-8");
}
sub unquote_rfc2047 {
local ($_) = @_;
- my $encoding;
- s{=\?([^?]+)\?q\?(.*?)\?=}{
- $encoding = $1;
- my $e = $2;
- $e =~ s/_/ /g;
- $e =~ s/=([0-9A-F]{2})/chr(hex($1))/eg;
- $e;
+ my $charset;
+ my $sep = qr/[ \t]+/;
+ s{$re_encoded_word(?:$sep$re_encoded_word)*}{
+ my @words = split $sep, $&;
+ foreach (@words) {
+ m/$re_encoded_word/;
+ $charset = $1;
+ my $encoding = $2;
+ my $text = $3;
+ if ($encoding eq 'q' || $encoding eq 'Q') {
+ $_ = $text;
+ s/_/ /g;
+ s/=([0-9A-F]{2})/chr(hex($1))/egi;
+ } else {
+ # other encodings not supported yet
+ }
+ }
+ join '', @words;
}eg;
- return wantarray ? ($_, $encoding) : $_;
+ return wantarray ? ($_, $charset) : $_;
}
sub quote_rfc2047 {
sub is_rfc2047_quoted {
my $s = shift;
- my $token = qr/[^][()<>@,;:"\/?.= \000-\037\177-\377]+/;
- my $encoded_text = qr/[!->@-~]+/;
length($s) <= 75 &&
- $s =~ m/^(?:"[[:ascii:]]*"|=\?$token\?$token\?$encoded_text\?=)$/o;
+ $s =~ m/^(?:"[[:ascii:]]*"|$re_encoded_word)$/o;
}
sub subject_needs_rfc2047_quoting {
Subject: $subject
Date: $date
Message-Id: $message_id
-X-Mailer: git-send-email $gitversion
";
+ if ($use_xmailer) {
+ $header .= "X-Mailer: git-send-email $gitversion\n";
+ }
if ($reply_to) {
$header .= "In-Reply-To: $reply_to\n";