]> Pileus Git - ~andy/fetchmail/blobdiff - sink.c
Bugfix: recognize local as shorthand for localdomains.
[~andy/fetchmail] / sink.c
diff --git a/sink.c b/sink.c
index 78630a021bb652c0da084790acf89748ecc27d85..c51603644b392b5d7b664349dd66e0d73c4b4da9 100644 (file)
--- a/sink.c
+++ b/sink.c
@@ -65,7 +65,18 @@ void smtp_close(struct query *ctl, int sayquit)
     batchcount = 0;
 }
 
-int smtp_open(struct query *ctl)
+static 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_setup(struct query *ctl)
 /* try to open a socket to the appropriate SMTP server for this query */ 
 {
     /* maybe it's time to close the socket in order to force delivery */
@@ -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 */
@@ -539,6 +550,18 @@ static int handle_smtp_report(struct query *ctl, struct msgblk *msg)
        free(responses[0]);
        return(PS_REFUSED);
 
+    case 530: /* must issue STARTTLS error */
+       /*
+        * Some SMTP servers insist on encrypted communication
+        * Let's set PS_TRANSIENT, otherwise all messages to be sent
+        * over such server would be blackholed - see RFC 3207.
+        */
+       if (outlevel > O_SILENT)
+               report_complete(stdout,
+                               GT_("SMTP server requires STARTTLS, keeping message.\n"));
+       free(responses[0]);
+       return(PS_TRANSIENT);
+
     default:
        /* bounce non-transient errors back to the sender */
        if (smtperr >= 500 && smtperr <= 599)
@@ -926,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);
     }
 
@@ -994,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
@@ -1029,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,
@@ -1041,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);
        }
 
@@ -1062,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);
     }
 
@@ -1253,7 +1276,7 @@ int open_sink(struct query *ctl, struct msgblk *msg,
      * open a socket fails, fall through to attempt delivery via
      * local MDA.
      */
-    else if (!ctl->mda && smtp_open(ctl) != -1)
+    else if (!ctl->mda && smtp_setup(ctl) != -1)
        return(open_smtp_sink(ctl, msg, good_addresses, bad_addresses));
 
     /*
@@ -1397,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);
            }
        }