diff options
author | Matthias Andree <matthias.andree@gmx.de> | 2010-01-28 00:16:07 +0000 |
---|---|---|
committer | Matthias Andree <matthias.andree@gmx.de> | 2010-01-28 00:16:07 +0000 |
commit | 6827f405d1239ba41e62181c88ab6cff51ca44f8 (patch) | |
tree | f9214cbdfeb7919d6588e1d378c079c172e0d6b6 /sink.c | |
parent | ca66045dfe48faa985f39c0208aded9f93d3da96 (diff) | |
download | fetchmail-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.c | 27 |
1 files changed, 19 insertions, 8 deletions
@@ -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); } } |