* RFC: git send-email and error handling @ 2011-04-14 20:10 Paul Gortmaker 2011-04-14 21:09 ` Jeff King 0 siblings, 1 reply; 9+ messages in thread From: Paul Gortmaker @ 2011-04-14 20:10 UTC (permalink / raw) To: git I came across a situation today where the behaviour of git send-email kind of surprised me -- in that it seemed definitely less than ideal for the use case I had. For stable linux kernel releases, it is very common to send hundreds of patches at once, to people you've never contacted before, simply because the are called out in CC: or SOB: lines of a patch that has been cherry picked. So it is highly likely that you may hit full inboxes, expired accounts and so on. The command line (git 1.7.4.4) is typically something like: git send-email --to stable@kernel.org --to linux-kernel@vger.kernel.org \ --cc stable-review@kernel.org some_patch_dir So, let me get to what happened today: After sending 113 out of 209 patches, it came to the 114th patch, and gave me this: (mbox) Adding cc: Dmitry Torokhov <dmitry.torokhov@gmail.com> from line 'From: Dmitry Torokhov <dmitry.torokhov@gmail.com>' (body) Adding cc: Dmitry Torokhov <dtor@mail.ru> from line 'Signed-off-by: Dmitry Torokhov <dtor@mail.ru>' (body) Adding cc: Paul Gortmaker <paul.gortmaker@windriver.com> from line 'Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>' 5.2.1 <dtor@mail.ru>... Mailbox disabled for this recipient Then, taking that as a hard error, it simply exited, leaving me scrambling to figure out how to quickly fix the offending patch and continue with the unsent queue. From my point of view, the right thing to do here would have been to ignore the error on the harvested mail address, and continue on through the rest of the queue. Or even interactively ask me what to do when it saw the 5.2.1 failure. But maybe that wouldn't be right for everyone. I didn't see anything in the GSE man page that would let me configure this behaviour either. Anyway, I thought I'd mention it and see where the discussion went. Thanks, Paul. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: RFC: git send-email and error handling 2011-04-14 20:10 RFC: git send-email and error handling Paul Gortmaker @ 2011-04-14 21:09 ` Jeff King 2011-04-15 0:30 ` Paul Gortmaker 0 siblings, 1 reply; 9+ messages in thread From: Jeff King @ 2011-04-14 21:09 UTC (permalink / raw) To: Paul Gortmaker; +Cc: git On Thu, Apr 14, 2011 at 04:10:12PM -0400, Paul Gortmaker wrote: > The command line (git 1.7.4.4) is typically something like: > > git send-email --to stable@kernel.org --to linux-kernel@vger.kernel.org \ > --cc stable-review@kernel.org some_patch_dir > > So, let me get to what happened today: After sending 113 out of 209 > patches, it came to the 114th patch, and gave me this: > > (mbox) Adding cc: Dmitry Torokhov <dmitry.torokhov@gmail.com> from line 'From: Dmitry Torokhov <dmitry.torokhov@gmail.com>' > (body) Adding cc: Dmitry Torokhov <dtor@mail.ru> from line 'Signed-off-by: Dmitry Torokhov <dtor@mail.ru>' > (body) Adding cc: Paul Gortmaker <paul.gortmaker@windriver.com> from line 'Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>' > 5.2.1 <dtor@mail.ru>... Mailbox disabled for this recipient > > Then, taking that as a hard error, it simply exited, > leaving me scrambling to figure out how to quickly fix the > offending patch and continue with the unsent queue. I suspect part of the issue is that your mail setup is unlike that of most people. Usually, we would deliver to some local MTA (either by SMTP directly, by sendmail that speaks SMTP to a smarthost, or by sendmail that queues directly); that MTA would queue the message in a spool for you, and attempt delivery asynchronously. So the errors generally come all or nothing. You can queue mail, or you can't, and trying again and again after each error is just wasteful and annoying. Eventual errors are reported back to you as bounces. Your setup seems different; it looks like your sendmail (or the SMTP server you connect to) actually routes the mail without queueing at all, and you synchronously get the final word on whether it can be delivered. Or maybe it just connects to the recipient site and checks that "RCPT TO" works before actually queueing. It's hard to say from the snippet above. What's your MTA? I can see in your case how it would be preferable to keep going through the list and then assemble a set of errors at the end. But that should be configurable, because most setups won't want that behavior. > From my point of view, the right thing to do here would have > been to ignore the error on the harvested mail address, and continue > on through the rest of the queue. It's a little tricky, because send-email may not know the details of what happened, especially if this behavior comes from a sendmail wrapper rather than SMTP. We dump the message and a list of recipients to an external program, and then get back a "yes it was sent" or "no it was not" code. So we can't do anything clever, like say "Well, it was sent, but not to one particular address, but that's OK because that address was auto-harvested from a signed-off-by line". Whether we can do better depends on your MTA. _If_ you are sending via SMTP, and _if_ it will reject particular recipients at the time of "rcpt to", then we could do something that clever. Given that the 5.2.1 message appeared on your terminal, and that it should not have been generated by git-send-email, that implies to me you are using the local sendmail binary. > Or even interactively ask me what to do when it saw the 5.2.1 failure. > But maybe that wouldn't be right for everyone. I didn't see anything > in the GSE man page that would let me configure this behaviour either. The problem there is that the message probably was not actually sent (or at least, sendmail presumably returned an error code to git, which is why git stopped). And you, as a human, saw that the error was something survivable. But you can't just tell git "it's OK to continue". You need to actually fix the problem and re-send, which means telling git that the one particular address is not interesting. And that is a lot more interface than just yes/no. I would think what you really want is a system that tries to send everything, keeps track of which recipients are to receive which message, and then marks success or failure for each. At the end, you would find that dtor@mail.ru didn't receive anything, and realize you don't care. And you don't have to worry about restarting a failed send-email and sending duplicates. You know who got what. If that sounds good, then you should consider switching MTAs, because that is exactly what the job of an MTA is. :) -Peff ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: RFC: git send-email and error handling 2011-04-14 21:09 ` Jeff King @ 2011-04-15 0:30 ` Paul Gortmaker 2011-04-15 3:42 ` Jeff King 2011-05-04 16:12 ` [RFC/PATCH] git-send-email: Remember sources of Cc addresses Jakub Narebski 0 siblings, 2 replies; 9+ messages in thread From: Paul Gortmaker @ 2011-04-15 0:30 UTC (permalink / raw) To: Jeff King; +Cc: git On 11-04-14 05:09 PM, Jeff King wrote: > On Thu, Apr 14, 2011 at 04:10:12PM -0400, Paul Gortmaker wrote: > >> The command line (git 1.7.4.4) is typically something like: >> >> git send-email --to stable@kernel.org --to linux-kernel@vger.kernel.org \ >> --cc stable-review@kernel.org some_patch_dir >> >> So, let me get to what happened today: After sending 113 out of 209 >> patches, it came to the 114th patch, and gave me this: >> >> (mbox) Adding cc: Dmitry Torokhov <dmitry.torokhov@gmail.com> from line 'From: Dmitry Torokhov <dmitry.torokhov@gmail.com>' >> (body) Adding cc: Dmitry Torokhov <dtor@mail.ru> from line 'Signed-off-by: Dmitry Torokhov <dtor@mail.ru>' >> (body) Adding cc: Paul Gortmaker <paul.gortmaker@windriver.com> from line 'Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>' >> 5.2.1 <dtor@mail.ru>... Mailbox disabled for this recipient >> >> Then, taking that as a hard error, it simply exited, >> leaving me scrambling to figure out how to quickly fix the >> offending patch and continue with the unsent queue. > > I suspect part of the issue is that your mail setup is unlike that of > most people. Usually, we would deliver to some local MTA (either by SMTP > directly, by sendmail that speaks SMTP to a smarthost, or by sendmail > that queues directly); that MTA would queue the message in a spool for > you, and attempt delivery asynchronously. So the errors generally come > all or nothing. You can queue mail, or you can't, and trying again and > again after each error is just wasteful and annoying. Eventual errors > are reported back to you as bounces. > > Your setup seems different; it looks like your sendmail (or the SMTP > server you connect to) actually routes the mail without queueing at all, > and you synchronously get the final word on whether it can be delivered. > Or maybe it just connects to the recipient site and checks that "RCPT > TO" works before actually queueing. It's hard to say from the snippet > above. What's your MTA? Yes, the above is true -- I'm not queuing anything locally or involving a local MTA. I've set sendemail.smtpserver in my ~/.gitconfig to the hostname of an infrastructural server running sendmail (telnet 25 doesnt show me what version, but I'm told it is sendmail). This configuration gives me the most portability to run on any random machine within our org without having to wonder if it has a locally installed and correctly configured MTA -- it works so well, I've even abused git send-email to dispatch random (non-patch) mails from ad-hoc scripts on occasions, simply because I know everyone has git installed somewhere in $PATH. > > I can see in your case how it would be preferable to keep going through > the list and then assemble a set of errors at the end. But that should > be configurable, because most setups won't want that behavior. > >> From my point of view, the right thing to do here would have >> been to ignore the error on the harvested mail address, and continue >> on through the rest of the queue. > > It's a little tricky, because send-email may not know the details of > what happened, especially if this behavior comes from a sendmail > wrapper rather than SMTP. We dump the message and a list of recipients > to an external program, and then get back a "yes it was sent" or "no it > was not" code. So we can't do anything clever, like say "Well, it was > sent, but not to one particular address, but that's OK because that > address was auto-harvested from a signed-off-by line". True. I wonder if there is some flexibility in what we do, depending on whether the setting is a local binary like /usr/bin/sendmail, vs. a hostname of a server, like it was in my case... > > Whether we can do better depends on your MTA. _If_ you are sending via > SMTP, and _if_ it will reject particular recipients at the time of "rcpt > to", then we could do something that clever. Given that the 5.2.1 > message appeared on your terminal, and that it should not have been > generated by git-send-email, that implies to me you are using the local > sendmail binary. > >> Or even interactively ask me what to do when it saw the 5.2.1 failure. >> But maybe that wouldn't be right for everyone. I didn't see anything >> in the GSE man page that would let me configure this behaviour either. > > The problem there is that the message probably was not actually sent (or > at least, sendmail presumably returned an error code to git, which is > why git stopped). And you, as a human, saw that the error was something > survivable. But you can't just tell git "it's OK to continue". You need > to actually fix the problem and re-send, which means telling git that > the one particular address is not interesting. And that is a lot more > interface than just yes/no. > > I would think what you really want is a system that tries to send > everything, keeps track of which recipients are to receive which > message, and then marks success or failure for each. At the end, you > would find that dtor@mail.ru didn't receive anything, and realize you > don't care. And you don't have to worry about restarting a failed > send-email and sending duplicates. You know who got what. > > If that sounds good, then you should consider switching MTAs, because > that is exactly what the job of an MTA is. :) I could set up a local queue, and for the big batches of patches I may do that, but the portability of having sendemail.smtpserver pointing at a host instead of a program is too nice for me to be willing to give that up globally. P. > > -Peff ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: RFC: git send-email and error handling 2011-04-15 0:30 ` Paul Gortmaker @ 2011-04-15 3:42 ` Jeff King 2011-05-04 16:12 ` [RFC/PATCH] git-send-email: Remember sources of Cc addresses Jakub Narebski 1 sibling, 0 replies; 9+ messages in thread From: Jeff King @ 2011-04-15 3:42 UTC (permalink / raw) To: Paul Gortmaker; +Cc: git On Thu, Apr 14, 2011 at 08:30:26PM -0400, Paul Gortmaker wrote: > > Your setup seems different; it looks like your sendmail (or the SMTP > > server you connect to) actually routes the mail without queueing at all, > > and you synchronously get the final word on whether it can be delivered. > > Or maybe it just connects to the recipient site and checks that "RCPT > > TO" works before actually queueing. It's hard to say from the snippet > > above. What's your MTA? > > Yes, the above is true -- I'm not queuing anything locally or involving > a local MTA. I've set sendemail.smtpserver in my ~/.gitconfig to the > hostname of an infrastructural server running sendmail (telnet 25 doesnt > show me what version, but I'm told it is sendmail). Ah. I'm not up on my sendmail config, but googling around, there are apparently milters that will do this kind of "call-ahead" rcpt checking. > This configuration gives me the most portability to run on any random > machine within our org without having to wonder if it has a locally > installed and correctly configured MTA -- it works so well, I've even > abused git send-email to dispatch random (non-patch) mails from ad-hoc > scripts on occasions, simply because I know everyone has git installed > somewhere in $PATH. Yeah, I think submitting to a central server is a very sane config if you don't have reliably local delivery. > > It's a little tricky, because send-email may not know the details of > > what happened, especially if this behavior comes from a sendmail > > wrapper rather than SMTP. We dump the message and a list of recipients > > to an external program, and then get back a "yes it was sent" or "no it > > was not" code. So we can't do anything clever, like say "Well, it was > > sent, but not to one particular address, but that's OK because that > > address was auto-harvested from a signed-off-by line". > > True. I wonder if there is some flexibility in what we do, depending > on whether the setting is a local binary like /usr/bin/sendmail, vs. > a hostname of a server, like it was in my case... Sure. Since you are actually doing SMTP, you have much more flexibility in knowing what errors happen. Look in git-send-email.perl's send_message, around line 1118. We use the Mail::SMTP module, but we just feed it the whole recipient list and barf if any of them is rejected. You could probably remember which recipients are "important" (i.e., given on the command line) and which were pulled automatically from the commit information, and then feed each recipient individually. If important ones fail, abort the message. If an unimportant one fails, send the message anyway, but remember the bad address and report the error at the end. That wouldn't help people using a sendmail binary, but there's nothing we can do. That transport simply doesn't supply as much information, so it can't take advantage of the new feature. But it will be no worse off for you adding the feature for SMTP users. -Peff ^ permalink raw reply [flat|nested] 9+ messages in thread
* [RFC/PATCH] git-send-email: Remember sources of Cc addresses 2011-04-15 0:30 ` Paul Gortmaker 2011-04-15 3:42 ` Jeff King @ 2011-05-04 16:12 ` Jakub Narebski 2011-05-04 21:35 ` Jeff King 1 sibling, 1 reply; 9+ messages in thread From: Jakub Narebski @ 2011-05-04 16:12 UTC (permalink / raw) To: git; +Cc: Jeff King, Paul Gortmaker, Jakub Narebski Instead of using @initial_cc to remember --cc=<address> command line options, and @cc to remember Cc addresses derived from message body and --cc-cmd=<command> and ultimately gather all Cc addresses, use %cc hash to remember from where Cc addresses came from: * command line --cc=<address> ('initial'), * "From:" email header in patch ('from'), * "Cc:" email header in patch ('cc'), * signoff lines and Cc lines in message body ('body'), * result of running <command> from --cc-cmd=<command> ('cc-cmd'). This is pure refactoring: we don't use this information, but gather together all of those in @cc variable local to send_message() subroutine. No changes in behavior. While at it make assignment to $to variable in send_message() up, to make it more clear that @recipients is just @to then. Signed-off-by: Jakub Narebski <jnareb@gmail.com> --- On Fri, 15 Apr 2011, Jeff King wrote: > On Thu, Apr 14, 2011 at 08:30:26PM -0400, Paul Gortmaker wrote: >> True. I wonder if there is some flexibility in what we do, depending >> on whether the setting is a local binary like /usr/bin/sendmail, vs. >> a hostname of a server, like it was in my case... > > Sure. Since you are actually doing SMTP, you have much more flexibility > in knowing what errors happen. Look in git-send-email.perl's > send_message, around line 1118. We use the Mail::SMTP module, but we > just feed it the whole recipient list and barf if any of them is > rejected. You could probably remember which recipients are "important" > (i.e., given on the command line) and which were pulled automatically > from the commit information, and then feed each recipient individually. > If important ones fail, abort the message. If an unimportant one fails, > send the message anyway, but remember the bad address and report the > error at the end. > > That wouldn't help people using a sendmail binary, but there's nothing > we can do. That transport simply doesn't supply as much information, so > it can't take advantage of the new feature. But it will be no worse off > for you adding the feature for SMTP users. This is an RFC patch preparing the way, so to speak, by remembering where each Cc address came from. We could in the future treat $cc{'body'} / all_cc('body') differently from the rest of all_cc(). Is the approach taken here sane? git-send-email.perl | 52 ++++++++++++++++++++++++++++++-------------------- 1 files changed, 31 insertions(+), 21 deletions(-) diff --git a/git-send-email.perl b/git-send-email.perl index 1c6b1a8..7d75a1e 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -140,10 +140,18 @@ my $smtp; my $auth; # Variables we fill in automatically, or via prompting: -my (@to,$no_to,@initial_to,@cc,$no_cc,@initial_cc,@bcclist,$no_bcc,@xh, +my (@to,$no_to,@initial_to,%cc,$no_cc,@bcclist,$no_bcc,@xh, $initial_reply_to,$initial_subject,@files, $author,$sender,$smtp_authpass,$annotate,$compose,$time); +sub all_cc { + my @keys = @_; + @keys = qw(initial from cc body cc-cmd) unless @keys; + return map { ref($_) ? @$_ : () } @cc{@keys}; + + #return map { ref($_) ? @$_ : () } values %cc; +} + my $envelope_sender; # Example reply to: @@ -221,7 +229,7 @@ my %config_settings = ( "smtpdomain" => \$smtp_domain, "to" => \@initial_to, "tocmd" => \$to_cmd, - "cc" => \@initial_cc, + "cc" => \@{$cc{'initial'}}, "cccmd" => \$cc_cmd, "aliasfiletype" => \$aliasfiletype, "bcc" => \@bcclist, @@ -281,7 +289,7 @@ my $rc = GetOptions("sender|from=s" => \$sender, "to=s" => \@initial_to, "to-cmd=s" => \$to_cmd, "no-to" => \$no_to, - "cc=s" => \@initial_cc, + "cc=s" => \@{$cc{'initial'}}, "no-cc" => \$no_cc, "bcc=s" => \@bcclist, "no-bcc" => \$no_bcc, @@ -423,7 +431,7 @@ foreach my $entry (@initial_to) { die "Comma in --to entry: $entry'\n" unless $entry !~ m/,/; } -foreach my $entry (@initial_cc) { +foreach my $entry (@{$cc{'initial'}}) { die "Comma in --cc entry: $entry'\n" unless $entry !~ m/,/; } @@ -753,7 +761,7 @@ sub expand_one_alias { @initial_to = expand_aliases(@initial_to); @initial_to = (map { sanitize_address($_) } @initial_to); -@initial_cc = expand_aliases(@initial_cc); +@{$cc{'initial'}} = expand_aliases(@{$cc{'initial'}}); @bcclist = expand_aliases(@bcclist); if ($thread && !defined $initial_reply_to && $prompting) { @@ -959,12 +967,14 @@ sub maildomain { sub send_message { my @recipients = unique_email_list(@to); - @cc = (grep { my $cc = extract_valid_address($_); - not grep { $cc eq $_ || $_ =~ /<\Q${cc}\E>$/ } @recipients - } - map { sanitize_address($_) } - @cc); - my $to = join (",\n\t", @recipients); + my $to = join(",\n\t", @recipients); + my @cc = + grep { + my $cc = extract_valid_address($_); + not grep { $cc eq $_ || $_ =~ /<\Q${cc}\E>$/ } @recipients + } + map { sanitize_address($_) } + all_cc(); @recipients = unique_email_list(@recipients,@cc,@bcclist); @recipients = (map { extract_valid_address($_) } @recipients); my $date = format_2822_time($time++); @@ -1159,7 +1169,7 @@ foreach my $t (@files) { my $has_content_type; my $body_encoding; @to = (); - @cc = (); + $cc{$_} = [] foreach (qw(from cc body)); @xh = (); my $input_format = undef; my @header = (); @@ -1197,7 +1207,7 @@ foreach my $t (@files) { next if $suppress_cc{'self'} and $author eq $sender; printf("(mbox) Adding cc: %s from line '%s'\n", $1, $_) unless $quiet; - push @cc, $1; + push @{$cc{'from'}}, $1; } elsif (/^To:\s+(.*)$/) { foreach my $addr (parse_address_line($1)) { @@ -1215,7 +1225,7 @@ foreach my $t (@files) { } printf("(mbox) Adding cc: %s from line '%s'\n", $addr, $_) unless $quiet; - push @cc, $addr; + push @{$cc{'cc'}}, $addr; } } elsif (/^Content-type:/i) { @@ -1239,10 +1249,10 @@ foreach my $t (@files) { # line 2 = subject # So let's support that, too. $input_format = 'lots'; - if (@cc == 0 && !$suppress_cc{'cc'}) { + if (all_cc() == 0 && !$suppress_cc{'cc'}) { printf("(non-mbox) Adding cc: %s from line '%s'\n", $_, $_) unless $quiet; - push @cc, $_; + push @{$cc{'cc'}}, $_; } elsif (!defined $subject) { $subject = $_; } @@ -1261,7 +1271,7 @@ foreach my $t (@files) { next if $suppress_cc{'sob'} and $what =~ /Signed-off-by/i; next if $suppress_cc{'bodycc'} and $what =~ /Cc/i; } - push @cc, $c; + push @{$cc{'body'}}, $c; printf("(body) Adding cc: %s from line '%s'\n", $c, $_) unless $quiet; } @@ -1270,7 +1280,7 @@ foreach my $t (@files) { push @to, recipients_cmd("to-cmd", "to", $to_cmd, $t) if defined $to_cmd; - push @cc, recipients_cmd("cc-cmd", "cc", $cc_cmd, $t) + push @{$cc{'cc-cmd'}}, recipients_cmd("cc-cmd", "cc", $cc_cmd, $t) if defined $cc_cmd && !$suppress_cc{'cccmd'}; if ($broken_encoding{$t} && !$has_content_type) { @@ -1308,14 +1318,14 @@ foreach my $t (@files) { } } + my $has_cc = all_cc(); $needs_confirm = ( $confirm eq "always" or - ($confirm =~ /^(?:auto|cc)$/ && @cc) or + ($confirm =~ /^(?:auto|cc)$/ && $has_cc) or ($confirm =~ /^(?:auto|compose)$/ && $compose && $message_num == 1)); - $needs_confirm = "inform" if ($needs_confirm && $confirm_unconfigured && @cc); + $needs_confirm = "inform" if ($needs_confirm && $confirm_unconfigured && $has_cc); @to = (@initial_to, @to); - @cc = (@initial_cc, @cc); my $message_was_sent = send_message(); -- 1.7.5 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [RFC/PATCH] git-send-email: Remember sources of Cc addresses 2011-05-04 16:12 ` [RFC/PATCH] git-send-email: Remember sources of Cc addresses Jakub Narebski @ 2011-05-04 21:35 ` Jeff King 2011-05-05 14:01 ` [RFC/PATCH 2/2] git-send-email: Do not require that addresses added from body be valid Jakub Narebski 0 siblings, 1 reply; 9+ messages in thread From: Jeff King @ 2011-05-04 21:35 UTC (permalink / raw) To: Jakub Narebski; +Cc: git, Paul Gortmaker On Wed, May 04, 2011 at 06:12:08PM +0200, Jakub Narebski wrote: > > Sure. Since you are actually doing SMTP, you have much more flexibility > > in knowing what errors happen. Look in git-send-email.perl's > > send_message, around line 1118. We use the Mail::SMTP module, but we > > just feed it the whole recipient list and barf if any of them is > > rejected. You could probably remember which recipients are "important" > > (i.e., given on the command line) and which were pulled automatically > > from the commit information, and then feed each recipient individually. > > If important ones fail, abort the message. If an unimportant one fails, > > send the message anyway, but remember the bad address and report the > > error at the end. > [...] > This is an RFC patch preparing the way, so to speak, by remembering > where each Cc address came from. We could in the future treat > $cc{'body'} / all_cc('body') differently from the rest of all_cc(). > > Is the approach taken here sane? Yeah, from my cursory read, it looks like a good step forward, and I didn't see any obvious bugs. You'll need still more refactoring in send_message to treat them differently at the SMTP level. We collapse all of the addresses down to a single list via unique_email_list (and we obviously want to keep this unique-ifying step), but that final list will have to remember where each address came from. > +sub all_cc { > + my @keys = @_; > + @keys = qw(initial from cc body cc-cmd) unless @keys; > + return map { ref($_) ? @$_ : () } @cc{@keys}; > + > + #return map { ref($_) ? @$_ : () } values %cc; > +} Nit: debugging cruft. :) -Peff ^ permalink raw reply [flat|nested] 9+ messages in thread
* [RFC/PATCH 2/2] git-send-email: Do not require that addresses added from body be valid 2011-05-04 21:35 ` Jeff King @ 2011-05-05 14:01 ` Jakub Narebski 2011-05-06 11:22 ` [RFC/PATCH 3/2 (squash!)] git-send-email: Warn about rejected automatically added recipients Jakub Narebski 2011-05-07 13:21 ` [RFC/PATCH 2/2] git-send-email: Do not require that addresses added from body be valid Jakub Narebski 0 siblings, 2 replies; 9+ messages in thread From: Jakub Narebski @ 2011-05-05 14:01 UTC (permalink / raw) To: Jeff King; +Cc: git, Paul Gortmaker On Wed, 4 May 2011, Jeff King wrote: > On Wed, May 04, 2011 at 06:12:08PM +0200, Jakub Narebski wrote: > > On Fri, 15 Apr 2011, Jeff King wrote: > > > > > > Sure. Since you are actually doing SMTP, you have much more flexibility > > > in knowing what errors happen. Look in git-send-email.perl's > > > send_message, around line 1118. We use the Mail::SMTP module, but we > > > just feed it the whole recipient list and barf if any of them is > > > rejected. You could probably remember which recipients are "important" > > > (i.e., given on the command line) and which were pulled automatically > > > from the commit information, and then feed each recipient individually. > > > If important ones fail, abort the message. If an unimportant one fails, > > > send the message anyway, but remember the bad address and report the > > > error at the end. > > [...] > > This is an RFC patch preparing the way, so to speak, by remembering > > where each Cc address came from. We could in the future treat > > $cc{'body'} / all_cc('body') differently from the rest of all_cc(). > > > > Is the approach taken here sane? > > Yeah, from my cursory read, it looks like a good step forward, and I > didn't see any obvious bugs. > > You'll need still more refactoring in send_message to treat them > differently at the SMTP level. We collapse all of the addresses down to > a single list via unique_email_list (and we obviously want to keep this > unique-ifying step), but that final list will have to remember where > each address came from. Below there is RFC patch that implements it by separating @cc and @cc_extra and later @recipients and @recipients_extra. How about it? It does not warn about bad addresses from body, and there are no tests yet! > > +sub all_cc { > > + my @keys = @_; > > + @keys = qw(initial from cc body cc-cmd) unless @keys; > > + return map { ref($_) ? @$_ : () } @cc{@keys}; > > + > > + #return map { ref($_) ? @$_ : () } values %cc; > > +} > > Nit: debugging cruft. :) Right, I'll fix it in final version. -- >8 ---------- >8 -- Subject: [PATCH] git-send-email: Do not require that addresses added from body be valid Do not barf if any of recipients that was pulled automatically from commit information is rejected. This covers [currently] addresses from 'Cc:' and 'Signed-off-by:' lines in message body. This is possible only if we are using Net::SMTP or Net::SMTP::SSL (it means that --smtp-server / sendemail.smtpserver is set to internet address of outgoing SMTP server to use), because only then we have control over which addresses are to be checked. Currently no warnings that "unimportant" addresses were rejected are shown; we should report errors at the end. No test for this new behavior: perhaps we could adapt some test from Net::SMTP module distribution... Cc: Jeff King <peff@peff.net> Cc: Paul Gortmaker <paul.gortmaker@windriver.com> Signed-off-by: Jakub Narebski <jnareb@gmail.com> --- git-send-email.perl | 40 +++++++++++++++++++++++++--------------- 1 files changed, 25 insertions(+), 15 deletions(-) diff --git a/git-send-email.perl b/git-send-email.perl index 7d75a1e..e758fd9 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -968,22 +968,32 @@ sub maildomain { sub send_message { my @recipients = unique_email_list(@to); my $to = join(",\n\t", @recipients); - my @cc = - grep { - my $cc = extract_valid_address($_); - not grep { $cc eq $_ || $_ =~ /<\Q${cc}\E>$/ } @recipients - } - map { sanitize_address($_) } - all_cc(); - @recipients = unique_email_list(@recipients,@cc,@bcclist); + my $sanitize_cc = sub { + return + grep { + my $cc = extract_valid_address($_); + not grep { $cc eq $_ || $_ =~ /<\Q${cc}\E>$/ } @recipients + } + map { sanitize_address($_) } + all_cc(@_); + }; + my @cc = $sanitize_cc->(qw(initial from cc cc-cmd)); + my @cc_extra = $sanitize_cc->(qw(body)); + + my (%seen, @recipients_extra); + @recipients = unique_email_list(\%seen,@recipients,@cc,@bcclist); @recipients = (map { extract_valid_address($_) } @recipients); + @recipients_extra = + map { extract_valid_address($_) } + unique_email_list(\%seen,@cc_extra); + my $date = format_2822_time($time++); my $gitversion = '@@GIT_VERSION@@'; if ($gitversion =~ m/..GIT_VERSION../) { $gitversion = Git::version(); } - my $cc = join(",\n\t", unique_email_list(@cc)); + my $cc = join(",\n\t", unique_email_list(@cc,@cc_extra)); my $ccline = ""; if ($cc ne '') { $ccline = "\nCc: $cc"; @@ -1007,7 +1017,7 @@ X-Mailer: git-send-email $gitversion $header .= join("\n", @xh) . "\n"; } - my @sendmail_parameters = ('-i', @recipients); + my @sendmail_parameters = ('-i', @recipients,@recipients_extra); my $raw_from = $sanitized_sender; if (defined $envelope_sender && $envelope_sender ne "auto") { $raw_from = $envelope_sender; @@ -1126,6 +1136,7 @@ X-Mailer: git-send-email $gitversion $smtp->mail( $raw_from ) or die $smtp->message; $smtp->to( @recipients ) or die $smtp->message; + $smtp->to( @recipients_extra, { Notify => ['NEVER'], SkipBad => 1 }); $smtp->data or die $smtp->message; $smtp->datasend("$header\n$message") or die $smtp->message; $smtp->dataend() or die $smtp->message; @@ -1138,8 +1149,8 @@ X-Mailer: git-send-email $gitversion if ($smtp_server !~ m#^/#) { print "Server: $smtp_server\n"; print "MAIL FROM:<$raw_from>\n"; - foreach my $entry (@recipients) { - print "RCPT TO:<$entry>\n"; + foreach my $entry (@recipients,@recipients_extra) { + print "RCPT TO:<$entry>\n"; } } else { print "Sendmail: $smtp_server ".join(' ',@sendmail_parameters)."\n"; @@ -1375,13 +1386,12 @@ sub cleanup_compose_files { $smtp->quit if $smtp; sub unique_email_list { - my %seen; + my $seen = ref $_[0] eq 'HASH' ? shift : {}; my @emails; foreach my $entry (@_) { if (my $clean = extract_valid_address($entry)) { - $seen{$clean} ||= 0; - next if $seen{$clean}++; + next if $seen->{$clean}++; push @emails, $entry; } else { print STDERR "W: unable to extract a valid address", -- 1.7.5 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [RFC/PATCH 3/2 (squash!)] git-send-email: Warn about rejected automatically added recipients 2011-05-05 14:01 ` [RFC/PATCH 2/2] git-send-email: Do not require that addresses added from body be valid Jakub Narebski @ 2011-05-06 11:22 ` Jakub Narebski 2011-05-07 13:21 ` [RFC/PATCH 2/2] git-send-email: Do not require that addresses added from body be valid Jakub Narebski 1 sibling, 0 replies; 9+ messages in thread From: Jakub Narebski @ 2011-05-06 11:22 UTC (permalink / raw) To: Jeff King; +Cc: git, Paul Gortmaker Signed-off-by: Jakub Narebski <jnareb@gmail.com> --- On Thu, 5 May 2011, Jakub Narebski wrote: > On Wed, 4 May 2011, Jeff King wrote: >> On Wed, May 04, 2011 at 06:12:08PM +0200, Jakub Narebski wrote: >>> On Fri, 15 Apr 2011, Jeff King wrote: >>>> [...] You could probably remember which recipients are "important" >>>> (i.e., given on the command line) and which were pulled automatically >>>> from the commit information, and then feed each recipient individually. >>>> If important ones fail, abort the message. If an unimportant one fails, >>>> send the message anyway, but remember the bad address and report the >>>> error at the end. > > It does not warn about bad addresses from body, and there are no tests yet! Now it does warn, though I don't know if we should warn after each message, or all together at the end, and if we should warn only about _new_ addresses. Still no tests, and no idea how to write one... Also if it is to be standalone commit, it needs better commit message. But if it is to squashed with previous, it doesn't ;-) git-send-email.perl | 11 ++++++++++- 1 files changed, 10 insertions(+), 1 deletions(-) diff --git a/git-send-email.perl b/git-send-email.perl index e758fd9..b8d4fb9 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -1136,11 +1136,20 @@ X-Mailer: git-send-email $gitversion $smtp->mail( $raw_from ) or die $smtp->message; $smtp->to( @recipients ) or die $smtp->message; - $smtp->to( @recipients_extra, { Notify => ['NEVER'], SkipBad => 1 }); + my @good_recips = + $smtp->to( @recipients_extra, { Notify => ['NEVER'], SkipBad => 1 }); $smtp->data or die $smtp->message; $smtp->datasend("$header\n$message") or die $smtp->message; $smtp->dataend() or die $smtp->message; $smtp->code =~ /250|200/ or die "Failed to send $subject\n".$smtp->message; + + %seen = (); + unique_email_list(\%seen, @good_recips); + # bad recipients are those not seen on list of good recipients + my @bad_recips = unique_email_list(\%seen, @recipients_extra); + @bad_recips and + warn "W: The following addresses added from body were rejected:\n\t". + join("\n\t", @bad_recips)."\n"; } if ($quiet) { printf (($dry_run ? "Dry-" : "")."Sent %s\n", $subject); -- 1.7.5 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [RFC/PATCH 2/2] git-send-email: Do not require that addresses added from body be valid 2011-05-05 14:01 ` [RFC/PATCH 2/2] git-send-email: Do not require that addresses added from body be valid Jakub Narebski 2011-05-06 11:22 ` [RFC/PATCH 3/2 (squash!)] git-send-email: Warn about rejected automatically added recipients Jakub Narebski @ 2011-05-07 13:21 ` Jakub Narebski 1 sibling, 0 replies; 9+ messages in thread From: Jakub Narebski @ 2011-05-07 13:21 UTC (permalink / raw) To: Jeff King; +Cc: git, Paul Gortmaker On Thu, 5 May 2011, Jakub Narebski wrote: > $smtp->to( @recipients ) or die $smtp->message; > + $smtp->to( @recipients_extra, { Notify => ['NEVER'], SkipBad => 1 }); ^^^^^^^^^^^^^^^^^^^^ Note: contrary to what I thought this doesn't mean to not send any notification request, but to send DSN (Delivery Status Notification) request of 'NEVER'. For example when using smtp.gmail.com gives: Net::SMTP::recipient: DSN option not supported by host at ./git-send-email line 1140 So the underlined part has to be removed. -- Jakub Narebski Poland ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2011-05-07 13:21 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2011-04-14 20:10 RFC: git send-email and error handling Paul Gortmaker 2011-04-14 21:09 ` Jeff King 2011-04-15 0:30 ` Paul Gortmaker 2011-04-15 3:42 ` Jeff King 2011-05-04 16:12 ` [RFC/PATCH] git-send-email: Remember sources of Cc addresses Jakub Narebski 2011-05-04 21:35 ` Jeff King 2011-05-05 14:01 ` [RFC/PATCH 2/2] git-send-email: Do not require that addresses added from body be valid Jakub Narebski 2011-05-06 11:22 ` [RFC/PATCH 3/2 (squash!)] git-send-email: Warn about rejected automatically added recipients Jakub Narebski 2011-05-07 13:21 ` [RFC/PATCH 2/2] git-send-email: Do not require that addresses added from body be valid Jakub Narebski
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.