Git fork

Merge branch 'ag/send-email-imap-sent'

"git send-email" learned to drive "git imap-send" to store already
sent e-mails in an IMAP folder.

* ag/send-email-imap-sent:
send-email: enable copying emails to an IMAP folder without actually sending them
send-email: add ability to send a copy of sent emails to an IMAP folder

+84 -10
+2
Documentation/config/sendemail.adoc
··· 88 88 sendemail.smtpServerPort:: 89 89 sendemail.smtpServerOption:: 90 90 sendemail.smtpUser:: 91 + sendemail.imapSentFolder:: 92 + sendemail.useImapOnly:: 91 93 sendemail.thread:: 92 94 sendemail.transferEncoding:: 93 95 sendemail.validate::
+26
Documentation/git-send-email.adoc
··· 300 300 commands and replies will be printed. Useful to debug TLS 301 301 connection and authentication problems. 302 302 303 + --imap-sent-folder=<folder>:: 304 + Some email providers (e.g. iCloud) do not send a copy of the emails sent 305 + using SMTP to the `Sent` folder or similar in your mailbox. Use this option 306 + to use `git imap-send` to send a copy of the emails to the folder specified 307 + using this option. You can run `git imap-send --list` to get a list of 308 + valid folder names, including the correct name of the `Sent` folder in 309 + your mailbox. You can also use this option to send emails to a dedicated 310 + IMAP folder of your choice. 311 + + 312 + This feature requires setting up `git imap-send`. See linkgit:git-imap-send[1] 313 + for instructions. 314 + 315 + --use-imap-only:: 316 + --no-use-imap-only:: 317 + If this is set, all emails will only be copied to the IMAP folder specified 318 + with `--imap-sent-folder` or `sendemail.imapSentFolder` and will not be sent 319 + to the recipients. Useful if you just want to create a draft of the emails 320 + and use another email client to send them. 321 + If disabled with `--no-use-imap-only`, the emails will be sent like usual. 322 + Disabled by default, but the `sendemail.useImapOnly` configuration 323 + variable can be used to enable it. 324 + 325 + + 326 + This feature requires setting up `git imap-send`. See linkgit:git-imap-send[1] 327 + for instructions. 328 + 303 329 --batch-size=<num>:: 304 330 Some email servers (e.g. 'smtp.163.com') limit the number of emails to be 305 331 sent per session (connection) and this will lead to a failure when
+38 -2
git-send-email.perl
··· 62 62 --smtp-user <str> * Username for SMTP-AUTH. 63 63 --smtp-pass <str> * Password for SMTP-AUTH; not necessary. 64 64 --smtp-encryption <str> * tls or ssl; anything else disables. 65 - --smtp-ssl * Deprecated. Use '--smtp-encryption ssl'. 65 + --smtp-ssl * Deprecated. Use `--smtp-encryption ssl`. 66 66 --smtp-ssl-cert-path <str> * Path to ca-certificates (either directory or file). 67 67 Pass an empty string to disable certificate 68 68 verification. ··· 73 73 --no-smtp-auth * Disable SMTP authentication. Shorthand for 74 74 `--smtp-auth=none` 75 75 --smtp-debug <0|1> * Disable, enable Net::SMTP debug. 76 + --imap-sent-folder <str> * IMAP folder where a copy of the emails should be sent. 77 + Make sure `git imap-send` is set up to use this feature. 78 + --[no-]use-imap-only * Only copy emails to the IMAP folder specified by 79 + `--imap-sent-folder` instead of actually sending them. 76 80 77 81 --batch-size <int> * send max <int> message per connection. 78 82 --relogin-delay <int> * delay <int> seconds between two successive login. ··· 200 204 201 205 # Variables we fill in automatically, or via prompting: 202 206 my (@to,@cc,@xh,$envelope_sender, 203 - $initial_in_reply_to,$reply_to,$initial_subject,@files, 207 + $initial_in_reply_to,$reply_to,$initial_subject,@files,@imap_copy, 204 208 $author,$sender,$smtp_authpass,$annotate,$compose,$time); 205 209 # Things we either get from config, *or* are overridden on the 206 210 # command-line. ··· 277 281 my ($smtp_authuser, $smtp_encryption, $smtp_ssl_cert_path); 278 282 my ($batch_size, $relogin_delay); 279 283 my ($identity, $aliasfiletype, @alias_files, $smtp_domain, $smtp_auth); 284 + my ($imap_sent_folder); 280 285 my ($confirm); 281 286 my (@suppress_cc); 282 287 my ($auto_8bit_encoding); ··· 293 298 my $target_xfer_encoding = 'auto'; 294 299 my $forbid_sendmail_variables = 1; 295 300 my $outlook_id_fix = 'auto'; 301 + my $use_imap_only = 0; 296 302 297 303 my %config_bool_settings = ( 298 304 "thread" => \$thread, ··· 309 315 "forbidsendmailvariables" => \$forbid_sendmail_variables, 310 316 "mailmap" => \$mailmap, 311 317 "outlookidfix" => \$outlook_id_fix, 318 + "useimaponly" => \$use_imap_only, 312 319 ); 313 320 314 321 my %config_settings = ( ··· 322 329 "smtpauth" => \$smtp_auth, 323 330 "smtpbatchsize" => \$batch_size, 324 331 "smtprelogindelay" => \$relogin_delay, 332 + "imapsentfolder" => \$imap_sent_folder, 325 333 "to" => \@config_to, 326 334 "tocmd" => \$to_cmd, 327 335 "cc" => \@config_cc, ··· 527 535 "smtp-domain:s" => \$smtp_domain, 528 536 "smtp-auth=s" => \$smtp_auth, 529 537 "no-smtp-auth" => sub {$smtp_auth = 'none'}, 538 + "imap-sent-folder=s" => \$imap_sent_folder, 539 + "use-imap-only!" => \$use_imap_only, 530 540 "annotate!" => \$annotate, 531 541 "compose" => \$compose, 532 542 "quiet" => \$quiet, ··· 1678 1688 1679 1689 if ($dry_run) { 1680 1690 # We don't want to send the email. 1691 + } elsif ($use_imap_only) { 1692 + die __("The destination IMAP folder is not properly defined.") if !defined $imap_sent_folder; 1681 1693 } elsif (defined $sendmail_cmd || file_name_is_absolute($smtp_server)) { 1682 1694 my $pid = open my $sm, '|-'; 1683 1695 defined $pid or die $!; ··· 1827 1839 print __("Result: OK"); 1828 1840 } 1829 1841 print "\n"; 1842 + } 1843 + 1844 + if ($imap_sent_folder && !$dry_run) { 1845 + my $imap_header = $header; 1846 + if (@initial_bcc) { 1847 + # Bcc is not a part of $header, so we add it here. 1848 + # This is only for the IMAP copy, not for the actual email 1849 + # sent to the recipients. 1850 + $imap_header .= "Bcc: " . join(", ", @initial_bcc) . "\n"; 1851 + } 1852 + push @imap_copy, "From git-send-email\n$imap_header\n$message"; 1830 1853 } 1831 1854 1832 1855 return 1; ··· 2222 2245 } 2223 2246 2224 2247 $smtp->quit if $smtp; 2248 + 2249 + if ($imap_sent_folder && @imap_copy && !$dry_run) { 2250 + my $imap_input = join("\n", @imap_copy); 2251 + eval { 2252 + print "\nStarting git imap-send...\n"; 2253 + my ($fh, $ctx) = Git::command_input_pipe(['imap-send', '-f', $imap_sent_folder]); 2254 + print $fh $imap_input; 2255 + Git::command_close_pipe($fh, $ctx); 2256 + 1; 2257 + } or do { 2258 + warn "Warning: failed to send messages to IMAP folder $imap_sent_folder: $@"; 2259 + }; 2260 + } 2225 2261 2226 2262 sub apply_transfer_encoding { 2227 2263 my $message = shift;
+18 -8
imap-send.c
··· 1442 1442 1443 1443 while (1) { 1444 1444 if (starts_with(p, "From ")) { 1445 - p = strstr(p+5, "\nFrom: "); 1446 - if (!p) break; 1447 - p = strstr(p+7, "\nDate: "); 1448 - if (!p) break; 1449 - p = strstr(p+7, "\nSubject: "); 1450 - if (!p) break; 1451 - p += 10; 1452 - count++; 1445 + if (starts_with(p, "From git-send-email")) { 1446 + p = strstr(p+5, "\nFrom: "); 1447 + if (!p) break; 1448 + p += 7; 1449 + p = strstr(p, "\nTo: "); 1450 + if (!p) break; 1451 + p += 5; 1452 + count++; 1453 + } else { 1454 + p = strstr(p+5, "\nFrom: "); 1455 + if (!p) break; 1456 + p = strstr(p+7, "\nDate: "); 1457 + if (!p) break; 1458 + p = strstr(p+7, "\nSubject: "); 1459 + if (!p) break; 1460 + p += 10; 1461 + count++; 1462 + } 1453 1463 } 1454 1464 p = strstr(p+5, "\nFrom "); 1455 1465 if (!p)