]> Pileus Git - ~andy/fetchmail/blobdiff - driver.c
Note Earl's regression fix for SSL_CTX_clear_options() on older OpenSSL.
[~andy/fetchmail] / driver.c
index 4a98442ded1d0f33ac5c8c03686b5a359d1bd138..c2917268cedfce70fa9d70f085bad27b7f4f201b 100644 (file)
--- a/driver.c
+++ b/driver.c
 #endif
 #include <netdb.h>
 #ifdef HAVE_PKG_hesiod
+#ifdef __cplusplus
+extern "C" {
+#endif
 #include <hesiod.h>
+#ifdef __cplusplus
+}
+#endif
 #endif
 
 #include <langinfo.h>
@@ -53,6 +59,8 @@
 #include "getaddrinfo.h"
 #include "tunable.h"
 
+#include "sdump.h"
+
 /* throw types for runtime errors */
 #define THROW_TIMEOUT  1               /* server timed out */
 
@@ -246,15 +254,17 @@ const char *canonical;  /* server name */
     if (retval) {
 #ifdef HEIMDAL
       if (err_ret && err_ret->e_text) {
-          report(stderr, GT_("krb5_sendauth: %s [server says '%*s'] \n"),
-                 error_message(retval),
-                 err_ret->e_text);
+         char *t = err_ret->e_text;
+         char *tt = sdump(t, strlen(t));
+          report(stderr, GT_("krb5_sendauth: %s [server says '%s']\n"),
+                 error_message(retval), tt);
+         free(tt);
 #else
       if (err_ret && err_ret->text.length) {
-          report(stderr, GT_("krb5_sendauth: %s [server says '%*s'] \n"),
-                error_message(retval),
-                err_ret->text.length,
-                err_ret->text.data);
+         char *tt = sdump(err_ret->text.data, err_ret->text.length);
+          report(stderr, GT_("krb5_sendauth: %s [server says '%s']\n"),
+                error_message(retval), tt);
+         free(tt);
 #endif
          krb5_free_error(context, err_ret);
       } else
@@ -428,7 +438,8 @@ static int eat_trailer(int sock, struct query *ctl)
 
 static int fetch_messages(int mailserver_socket, struct query *ctl, 
                          int count, int **msgsizes, int maxfetch,
-                         int *fetches, int *dispatches, int *deletions)
+                         int *fetches, int *dispatches, int *deletions,
+                         int *transient_errors)
 /* fetch messages in lockstep mode */
 {
     flag force_retrieval;
@@ -492,20 +503,20 @@ static int fetch_messages(int mailserver_socket, struct query *ctl,
 
        /* check if the message is old
         * Note: the size of the message may not be known here */
-       if (ctl->fetchall || force_retrieval)
-           ;
-       else if (ctl->server.base_protocol->is_old && (ctl->server.base_protocol->is_old)(mailserver_socket,ctl,num))
-           msgcode = MSGLEN_OLD;
+       if (ctl->fetchall || force_retrieval) {
+           /* empty */
+       } else { 
+           if (ctl->server.base_protocol->is_old && (ctl->server.base_protocol->is_old)(mailserver_socket,ctl,num)) {
+                   msgcode = MSGLEN_OLD;
+           }
+        }
        if (msgcode == MSGLEN_OLD)
        {
-               /* To avoid flooding the syslog when using --keep,
-                * report "Skipped message" only when:
-                *  1) --verbose is on, or
-                *  2) fetchmail does not use syslog
-                */
-           if (   (outlevel >= O_VERBOSE) ||
-                  (outlevel > O_SILENT && !run.use_syslog)
-              )
+           /*
+            * To avoid flooding the logs when using --keep, report
+            * skipping for old messages only when --flush is on.
+            */
+           if (outlevel > O_SILENT && ctl->flush)
            {
                report_build(stdout, 
                             GT_("skipping message %s@%s:%d"),
@@ -602,6 +613,7 @@ static int fetch_messages(int mailserver_socket, struct query *ctl,
                             GT_("couldn't fetch headers, message %s@%s:%d (%d octets)\n"),
                             ctl->remotename, ctl->server.truename, num,
                             msgsize);
+               (*transient_errors)++;
                continue;
            }
            else if (err != 0)
@@ -643,7 +655,10 @@ static int fetch_messages(int mailserver_socket, struct query *ctl,
            if (err == PS_RETAINED)
                suppress_forward = suppress_delete = retained = TRUE;
            else if (err == PS_TRANSIENT)
+           {
                suppress_delete = suppress_forward = TRUE;
+               (*transient_errors)++;
+           }
            else if (err == PS_REFUSED)
                suppress_forward = TRUE;
            else if (err)
@@ -704,7 +719,10 @@ static int fetch_messages(int mailserver_socket, struct query *ctl,
                              len);
 
                if (err == PS_TRANSIENT)
+               {
                    suppress_delete = suppress_forward = TRUE;
+                   (*transient_errors)++;
+               }
                else if (err)
                    return(err);
 
@@ -797,16 +815,11 @@ flagthemail:
        }
        else
        {
-           if (   (outlevel >= O_VERBOSE) ||
-                       /* To avoid flooding the syslog when using --keep,
-                        * report "Skipped message" only when:
-                        *  1) --verbose is on, or
-                        *  2) fetchmail does not use syslog, or
-                        *  3) the message was skipped for some other
-                        *     reason than just being old.
-                        */
-                  (outlevel > O_SILENT && (!run.use_syslog || msgcode != MSGLEN_OLD))
-              )
+           /*
+            * To avoid flooding the logs when using --keep, report
+            * skipping of new messages only.
+            */
+           if (outlevel > O_SILENT && msgcode != MSGLEN_OLD)
            report_complete(stdout, GT_(" not flushed\n"));
 
            /* maybe we mark this message as seen now? */
@@ -935,7 +948,7 @@ static int do_session(
        /* sigsetjmp returned zero -> normal operation */
        char buf[MSGBUFSIZE+1], *realhost;
        int count, newm, bytes;
-       int fetches, dispatches, oldphase;
+       int fetches, dispatches, transient_errors, oldphase;
        struct idlist *idp;
 
        /* execute pre-initialization command, if any */
@@ -1070,25 +1083,6 @@ static int do_session(
                    strlcpy(errbuf, strerror(err_no), sizeof(errbuf));
                report_complete(stderr, ": %s\n", errbuf);
 
-#ifdef __UNUSED__
-               /* 
-                * Don't use this.  It was an attempt to address Debian bug
-                * #47143 (Notify user by mail when pop server nonexistent).
-                * Trouble is, that doesn't work; you trip over the case 
-                * where your SLIP or PPP link is down...
-                */
-               /* warn the system administrator */
-               if (open_warning_by_mail(ctl) == 0)
-               {
-                   stuff_warning(iana_charset, ctl,
-                        GT_("Subject: Fetchmail unreachable-server warning."));
-                   stuff_warning(NULL, ctl, "");
-                   stuff_warning(NULL, ctl, GT_("Fetchmail could not reach the mail server %s:"),
-                                 ctl->server.pollname);
-                   stuff_warning(NULL, ctl, errbuf, ctl->server.pollname);
-                   close_warning_by_mail(ctl, (struct msgblk *)NULL);
-               }
-#endif
            }
            err = PS_SOCKET;
            set_timeout(0);
@@ -1106,11 +1100,13 @@ static int do_session(
        /* perform initial SSL handshake on open connection */
        if (ctl->use_ssl &&
                SSLOpen(mailserver_socket, ctl->sslcert, ctl->sslkey,
-                   ctl->sslproto, ctl->sslcertck, ctl->sslcertpath,
+                   ctl->sslproto, ctl->sslcertck,
+                   ctl->sslcertfile, ctl->sslcertpath,
                    ctl->sslfingerprint, ctl->sslcommonname ?
                    ctl->sslcommonname : realhost, ctl->server.pollname,
                    &ctl->remotename) == -1)
        {
+           set_timeout(0);
            report(stderr, GT_("SSL connection failed.\n"));
            err = PS_SOCKET;
            goto cleanUp;
@@ -1159,7 +1155,9 @@ static int do_session(
        stage = STAGE_GETAUTH;
        if (ctl->server.base_protocol->getauth)
        {
+           set_timeout(mytimeout);
            err = (ctl->server.base_protocol->getauth)(mailserver_socket, ctl, buf);
+           set_timeout(0);
 
            if (err != 0)
            {
@@ -1178,6 +1176,9 @@ static int do_session(
                           ctl->server.truename,
                           (ctl->wehaveauthed ? GT_(" (previously authorized)") : "")
                        );
+                   if (ctl->server.authenticate == A_ANY && !ctl->wehaveauthed) {
+                       report(stderr, GT_("For help, see http://www.fetchmail.info/fetchmail-FAQ.html#R15\n"));
+                   }
 
                    /*
                     * If we're running in background, try to mail the
@@ -1304,6 +1305,7 @@ is restored."));
            pass = 0;
            do {
                dispatches = 0;
+               transient_errors = 0;
                ++pass;
 
                /* reset timeout, in case we did an IDLE */
@@ -1433,10 +1435,20 @@ is restored."));
                    err = fetch_messages(mailserver_socket, ctl, 
                                         count, &msgsizes,
                                         maxfetch,
-                                        &fetches, &dispatches, &deletions);
+                                        &fetches, &dispatches, &deletions,
+                                        &transient_errors);
                    if (err != PS_SUCCESS && err != PS_MAXFETCH)
                        goto cleanUp;
 
+                   if (transient_errors > MAX_TRANSIENT_ERRORS)
+                   {
+                       if (outlevel > O_SILENT)
+                       {
+                           report(stderr, GT_("Too many mails skipped (%d > %d) due to transient errors for %s\n"),
+                                   transient_errors, MAX_TRANSIENT_ERRORS, buf);
+                       }
+                   }
+
                    if (!check_only && ctl->skipped
                        && run.poll_interval > 0 && !nodetach)
                    {
@@ -1518,7 +1530,6 @@ is restored."));
        smtp_close(ctl, 0);
        if (mailserver_socket != -1) {
            cleanupSockClose(mailserver_socket);
-           mailserver_socket = -1;
        }
        /* If there was a connect timeout, the socket should be closed.
         * mailserver_socket_temp contains the socket to close.