aboutsummaryrefslogtreecommitdiffstats
path: root/sink.c
diff options
context:
space:
mode:
authorMatthias Andree <matthias.andree@gmx.de>2010-01-28 00:16:07 +0000
committerMatthias Andree <matthias.andree@gmx.de>2010-01-28 00:16:07 +0000
commit6827f405d1239ba41e62181c88ab6cff51ca44f8 (patch)
treef9214cbdfeb7919d6588e1d378c079c172e0d6b6 /sink.c
parentca66045dfe48faa985f39c0208aded9f93d3da96 (diff)
downloadfetchmail-6827f405d1239ba41e62181c88ab6cff51ca44f8.tar.gz
fetchmail-6827f405d1239ba41e62181c88ab6cff51ca44f8.tar.bz2
fetchmail-6827f405d1239ba41e62181c88ab6cff51ca44f8.zip
Recover from SMTP protocol errors on RSET. (Sunil Shetye)
Apply patch from Sunil Shetye to fix a problem reported by James Moe. Before this fix, fetchmail's SMTP client would not recover from errors such as lost connections that were encountered when fetchmail had sent RSET, for instance, after an anti-spam filter dropped the connection after detecting spam. Fetchmail then tried to send subsequent mail through this broken connection and deferred retrieval until the next poll. Now, if RSET fails, fetchmail closes the connection and reopens it for the next message to be delivered. svn path=/branches/BRANCH_6-3/; revision=5463
Diffstat (limited to 'sink.c')
-rw-r--r--sink.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/sink.c b/sink.c
index 3db9def4..703bea58 100644
--- a/sink.c
+++ b/sink.c
@@ -65,6 +65,17 @@ void smtp_close(struct query *ctl, int sayquit)
batchcount = 0;
}
+void smtp_rset(struct query *ctl)
+/* reset the mail transaction */
+{
+ if (SMTP_rset(ctl->smtp_socket, ctl->smtphostmode) == SM_UNRECOVERABLE)
+ {
+ /* close the bad connection. fetchmail will reconnect for the
+ * next mail */
+ smtp_close(ctl, 0);
+ }
+}
+
int smtp_open(struct query *ctl)
/* try to open a socket to the appropriate SMTP server for this query */
{
@@ -441,7 +452,7 @@ static int handle_smtp_report(struct query *ctl, struct msgblk *msg)
* RSET discards the message body and it doesn't get sent to the
* valid recipients.
*/
- SMTP_rset(ctl->smtp_socket); /* stay on the safe side */
+ smtp_rset(ctl); /* stay on the safe side */
if (outlevel >= O_DEBUG)
report(stdout, GT_("Saved error is still %d\n"), smtperr);
#endif /* __UNUSED */
@@ -938,7 +949,7 @@ static int open_smtp_sink(struct query *ctl, struct msgblk *msg,
{
int err = handle_smtp_report(ctl, msg); /* map to PS_TRANSIENT or PS_REFUSED */
- SMTP_rset(ctl->smtp_socket, ctl->smtphostmode); /* stay on the safe side */
+ smtp_rset(ctl); /* stay on the safe side */
return(err);
}
@@ -1006,7 +1017,7 @@ transient:
* crap. If one of the recipients returned PS_TRANSIENT,
* we return exactly that.
*/
- SMTP_rset(ctl->smtp_socket, ctl->smtphostmode); /* required by RFC1870 */
+ smtp_rset(ctl); /* required by RFC1870 */
goto transient;
}
#ifdef EXPLICIT_BOUNCE_ON_BAD_ADDRESS
@@ -1041,7 +1052,7 @@ transient:
{
if (outlevel >= O_VERBOSE)
report(stderr, GT_("no address matches; no postmaster set.\n"));
- SMTP_rset(ctl->smtp_socket, ctl->smtphostmode); /* required by RFC1870 */
+ smtp_rset(ctl); /* required by RFC1870 */
return(PS_REFUSED);
}
if ((smtp_err = SMTP_rcpt(ctl->smtp_socket, ctl->smtphostmode,
@@ -1053,7 +1064,7 @@ transient:
if (smtp_err != SM_OK)
{
report(stderr, GT_("can't even send to %s!\n"), run.postmaster);
- SMTP_rset(ctl->smtp_socket, ctl->smtphostmode); /* required by RFC1870 */
+ smtp_rset(ctl); /* required by RFC1870 */
return(PS_REFUSED);
}
@@ -1074,7 +1085,7 @@ transient:
if (smtp_err != SM_OK)
{
int err = handle_smtp_report(ctl, msg);
- SMTP_rset(ctl->smtp_socket, ctl->smtphostmode); /* stay on the safe side */
+ smtp_rset(ctl); /* stay on the safe side */
return(err);
}
@@ -1409,13 +1420,13 @@ int close_sink(struct query *ctl, struct msgblk *msg, flag forward)
{
if (handle_smtp_report(ctl, msg) != PS_REFUSED)
{
- SMTP_rset(ctl->smtp_socket, ctl->smtphostmode); /* stay on the safe side */
+ smtp_rset(ctl); /* stay on the safe side */
return(FALSE);
}
else
{
report(stderr, GT_("SMTP listener refused delivery\n"));
- SMTP_rset(ctl->smtp_socket, ctl->smtphostmode); /* stay on the safe side */
+ smtp_rset(ctl); /* stay on the safe side */
return(TRUE);
}
}