[PATCH v3] send-email: add ability to send a copy of sent emails to an IMAP folder

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Some email providers like Apple iCloud Mail do not support sending a copy
of sent emails to the "Sent" folder if SMTP server is used. As a
workaround, various email clients like Thunderbird which rely on SMTP,
use IMAP to send a copy of sent emails to the "Sent" folder. Something
similar can be done if sending emails via `git send-email`, by using
the `git imap-send` command to send a copy of the sent email to an IMAP
folder specified by the user.

Add this functionality to `git send-email` by introducing a new
configuration variable `sendemail.imapfolder` and command line option
`--imap-folder` which specifies the IMAP folder to send a copy of the
sent emails to. If specified, a copy of the sent emails will be sent
by piping the emails to `git imap-send` command, after the all emails are
sent via SMTP and the SMTP server has been closed.

Signed-off-by: Aditya Garg <gargaditya08@xxxxxxxx>
---

v2 - Fix indentation in patch for imap-send.c
   - Minor edits to commit message

v3 - Rename imap folder to imap sent folder
   - Make an error message shorter by removing unecessary details

 Documentation/config/sendemail.adoc |  1 +
 Documentation/git-send-email.adoc   | 12 +++++++++++
 git-send-email.perl                 | 31 ++++++++++++++++++++++++++++-
 imap-send.c                         | 26 ++++++++++++++++--------
 4 files changed, 61 insertions(+), 9 deletions(-)

diff --git a/Documentation/config/sendemail.adoc b/Documentation/config/sendemail.adoc
index 4722334657..dd2dbc87a0 100644
--- a/Documentation/config/sendemail.adoc
+++ b/Documentation/config/sendemail.adoc
@@ -88,6 +88,7 @@ sendemail.smtpServer::
 sendemail.smtpServerPort::
 sendemail.smtpServerOption::
 sendemail.smtpUser::
+sendemail.imapSentFolder::
 sendemail.thread::
 sendemail.transferEncoding::
 sendemail.validate::
diff --git a/Documentation/git-send-email.adoc b/Documentation/git-send-email.adoc
index 5335502d68..82a65fd47f 100644
--- a/Documentation/git-send-email.adoc
+++ b/Documentation/git-send-email.adoc
@@ -299,6 +299,18 @@ must be used for each option.
 	commands and replies will be printed. Useful to debug TLS
 	connection and authentication problems.
 
+--imap-sent-folder=<folder>::
+	Some email providers (e.g. iCloud) do not send a copy of the emails sent
+	using SMTP to the `Sent` folder or similar in your mailbox. Use this option
+	to use `git imap-send` to send a copy of the emails to the folder specified
+	using this option. You can run `git imap-send --list` to get a list of
+	valid folder names, including the correct name of the `Sent` folder in
+	your mailbox. You can also use this option to send emails to a dedicated
+	IMAP folder of your choice.
++
+This feature requires setting up `git imap-send`. See linkgit:git-imap-send[1]
+to get instructions for the same.
+
 --batch-size=<num>::
 	Some email servers (e.g. 'smtp.163.com') limit the number of emails to be
 	sent per session (connection) and this will lead to a failure when
diff --git a/git-send-email.perl b/git-send-email.perl
index 437f8ac46a..5aafe8cdf3 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -73,6 +73,8 @@ sub usage {
     --no-smtp-auth                 * Disable SMTP authentication. Shorthand for
                                      `--smtp-auth=none`
     --smtp-debug            <0|1>  * Disable, enable Net::SMTP debug.
+    --imap-sent-folder      <str>  * IMAP folder where a copy of the emails should be sent.
+                                     Make sure `git imap-send` is setup to use this feature.
 
     --batch-size            <int>  * send max <int> message per connection.
     --relogin-delay         <int>  * delay <int> seconds between two successive login.
@@ -200,7 +202,7 @@ sub format_2822_time {
 
 # Variables we fill in automatically, or via prompting:
 my (@to,@cc,@xh,$envelope_sender,
-	$initial_in_reply_to,$reply_to,$initial_subject,@files,
+	$initial_in_reply_to,$reply_to,$initial_subject,@files,@imap_copy,
 	$author,$sender,$smtp_authpass,$annotate,$compose,$time);
 # Things we either get from config, *or* are overridden on the
 # command-line.
@@ -277,6 +279,7 @@ sub do_edit {
 my ($smtp_authuser, $smtp_encryption, $smtp_ssl_cert_path);
 my ($batch_size, $relogin_delay);
 my ($identity, $aliasfiletype, @alias_files, $smtp_domain, $smtp_auth);
+my ($imap_sent_folder);
 my ($confirm);
 my (@suppress_cc);
 my ($auto_8bit_encoding);
@@ -322,6 +325,7 @@ sub do_edit {
     "smtpauth" => \$smtp_auth,
     "smtpbatchsize" => \$batch_size,
     "smtprelogindelay" => \$relogin_delay,
+    "imapsentfolder" => \$imap_sent_folder,
     "to" => \@config_to,
     "tocmd" => \$to_cmd,
     "cc" => \@config_cc,
@@ -527,6 +531,7 @@ sub config_regexp {
 		    "smtp-domain:s" => \$smtp_domain,
 		    "smtp-auth=s" => \$smtp_auth,
 		    "no-smtp-auth" => sub {$smtp_auth = 'none'},
+		    "imap-sent-folder=s" => \$imap_sent_folder,
 		    "annotate!" => \$annotate,
 		    "compose" => \$compose,
 		    "quiet" => \$quiet,
@@ -1829,6 +1834,17 @@ sub send_message {
 		print "\n";
 	}
 
+	if ($imap_sent_folder) {
+		my $imap_header = $header;
+		if (@initial_bcc) {
+			# Bcc is not a part of $header, so we add it here.
+			# This is only for the IMAP copy, not for the actual email
+			# sent to the recipients.
+			$imap_header .= "Bcc: " . join(", ", @initial_bcc) . "\n";
+		}
+		push @imap_copy, "From git-send-email\n$imap_header\n$message";
+	}
+
 	return 1;
 }
 
@@ -2223,6 +2239,19 @@ sub cleanup_compose_files {
 
 $smtp->quit if $smtp;
 
+if ($imap_sent_folder && @imap_copy) {
+	my $imap_input = join("\n", @imap_copy);
+	eval {
+		print "\nStarting git imap-send...\n";
+		my ($fh, $ctx) = Git::command_input_pipe(['imap-send', '-f', $imap_sent_folder]);
+		print $fh $imap_input;
+		Git::command_close_pipe($fh, $ctx);
+		1;
+	} or do {
+		warn "Warning: failed to send messages to IMAP folder $imap_sent_folder: $@";
+	};
+}
+
 sub apply_transfer_encoding {
 	my $message = shift;
 	my $from = shift;
diff --git a/imap-send.c b/imap-send.c
index f5a656ac71..44de0c5a77 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -1441,14 +1441,24 @@ static int count_messages(struct strbuf *all_msgs)
 
 	while (1) {
 		if (starts_with(p, "From ")) {
-			p = strstr(p+5, "\nFrom: ");
-			if (!p) break;
-			p = strstr(p+7, "\nDate: ");
-			if (!p) break;
-			p = strstr(p+7, "\nSubject: ");
-			if (!p) break;
-			p += 10;
-			count++;
+			if (starts_with(p, "From git-send-email")) {
+				p = strstr(p+5, "\nFrom: ");
+				if (!p) break;
+				p += 7;
+				p = strstr(p, "\nTo: ");
+				if (!p) break;
+				p += 5;
+				count++;
+			} else {
+				p = strstr(p+5, "\nFrom: ");
+				if (!p) break;
+				p = strstr(p+7, "\nDate: ");
+				if (!p) break;
+				p = strstr(p+7, "\nSubject: ");
+				if (!p) break;
+				p += 10;
+				count++;
+			}
 		}
 		p = strstr(p+5, "\nFrom ");
 		if (!p)

Range-diff against v2:
1:  01084f57f9 ! 1:  da7cee769f send-email: add ability to send a copy of sent emails to an IMAP folder
    @@ Documentation/config/sendemail.adoc: sendemail.smtpServer::
      sendemail.smtpServerPort::
      sendemail.smtpServerOption::
      sendemail.smtpUser::
    -+sendemail.imapfolder::
    ++sendemail.imapSentFolder::
      sendemail.thread::
      sendemail.transferEncoding::
      sendemail.validate::
    @@ Documentation/git-send-email.adoc: must be used for each option.
      	commands and replies will be printed. Useful to debug TLS
      	connection and authentication problems.
      
    -+--imap-folder=<folder>::
    ++--imap-sent-folder=<folder>::
     +	Some email providers (e.g. iCloud) do not send a copy of the emails sent
     +	using SMTP to the `Sent` folder or similar in your mailbox. Use this option
     +	to use `git imap-send` to send a copy of the emails to the folder specified
    @@ git-send-email.perl: sub usage {
          --no-smtp-auth                 * Disable SMTP authentication. Shorthand for
                                           `--smtp-auth=none`
          --smtp-debug            <0|1>  * Disable, enable Net::SMTP debug.
    -+    --imap-folder           <str>  * IMAP folder where a copy of the emails should be sent.
    ++    --imap-sent-folder      <str>  * IMAP folder where a copy of the emails should be sent.
     +                                     Make sure `git imap-send` is setup to use this feature.
      
          --batch-size            <int>  * send max <int> message per connection.
    @@ git-send-email.perl: sub do_edit {
      my ($smtp_authuser, $smtp_encryption, $smtp_ssl_cert_path);
      my ($batch_size, $relogin_delay);
      my ($identity, $aliasfiletype, @alias_files, $smtp_domain, $smtp_auth);
    -+my ($imap_folder);
    ++my ($imap_sent_folder);
      my ($confirm);
      my (@suppress_cc);
      my ($auto_8bit_encoding);
    @@ git-send-email.perl: sub do_edit {
          "smtpauth" => \$smtp_auth,
          "smtpbatchsize" => \$batch_size,
          "smtprelogindelay" => \$relogin_delay,
    -+    "imapfolder" => \$imap_folder,
    ++    "imapsentfolder" => \$imap_sent_folder,
          "to" => \@config_to,
          "tocmd" => \$to_cmd,
          "cc" => \@config_cc,
    @@ git-send-email.perl: sub config_regexp {
      		    "smtp-domain:s" => \$smtp_domain,
      		    "smtp-auth=s" => \$smtp_auth,
      		    "no-smtp-auth" => sub {$smtp_auth = 'none'},
    -+		    "imap-folder=s" => \$imap_folder,
    ++		    "imap-sent-folder=s" => \$imap_sent_folder,
      		    "annotate!" => \$annotate,
      		    "compose" => \$compose,
      		    "quiet" => \$quiet,
    @@ git-send-email.perl: sub send_message {
      		print "\n";
      	}
      
    -+	if ($imap_folder) {
    ++	if ($imap_sent_folder) {
     +		my $imap_header = $header;
     +		if (@initial_bcc) {
     +			# Bcc is not a part of $header, so we add it here.
    @@ git-send-email.perl: sub cleanup_compose_files {
      
      $smtp->quit if $smtp;
      
    -+if ($imap_folder && @imap_copy) {
    ++if ($imap_sent_folder && @imap_copy) {
     +	my $imap_input = join("\n", @imap_copy);
     +	eval {
     +		print "\nStarting git imap-send...\n";
    -+		my ($fh, $ctx) = Git::command_input_pipe(['imap-send', '-f', $imap_folder]);
    ++		my ($fh, $ctx) = Git::command_input_pipe(['imap-send', '-f', $imap_sent_folder]);
     +		print $fh $imap_input;
     +		Git::command_close_pipe($fh, $ctx);
     +		1;
     +	} or do {
    -+		warn "Warning: failed to send messages to IMAP folder $imap_folder via imap-send pipe: $@";
    ++		warn "Warning: failed to send messages to IMAP folder $imap_sent_folder: $@";
     +	};
     +}
     +
-- 
2.50.1.319.gda7cee769f






[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux