]> Pileus Git - ~andy/fetchmail/blobdiff - fetchmail.c
Fix HESIOD compile failure on FreeBSD 5-CURRENT,
[~andy/fetchmail] / fetchmail.c
index 2e8cd94f4a25a50f0111e96a09035349b242633a..de5215a9a2e8c6ef82050f26e4cfb7ea42bd8f2f 100644 (file)
 #include <errno.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <sys/time.h>  /* needed for Sun 4.1.2 */
 #ifdef HAVE_SETRLIMIT
 #include <sys/resource.h>
 #endif /* HAVE_SETRLIMIT */
 #include <sys/utsname.h>
 
-#include "getopt.h"
 #include "fetchmail.h"
 #include "socket.h"
 #include "tunable.h"
@@ -64,7 +62,7 @@ char *program_name;       /* the name to prefix error messages with */
 flag configdump;           /* dump control blocks for configurator */
 char *fetchmailhost;       /* either `localhost' or the host's FQDN */
 
-#if NET_SECURITY
+#ifdef NET_SECURITY
 void *request = NULL;
 int requestlen = 0;
 #endif /* NET_SECURITY */
@@ -75,8 +73,8 @@ static int activecount;               /* count number of active entries */
 static struct runctl cmd_run;  /* global options set from command line */
 static time_t parsetime;       /* time of last parse */
 
-static void terminate_run(int);
-static void terminate_poll(int);
+static RETSIGTYPE terminate_run(int);
+static RETSIGTYPE terminate_poll(int);
 
 #if defined(__FreeBSD__) && defined(__FreeBSD_USE_KVM)
 /* drop SGID kmem privileage until we need it */
@@ -100,7 +98,6 @@ static void dropprivs(void)
 #endif
 
 #if defined(HAVE_SETLOCALE) && defined(ENABLE_NLS) && defined(HAVE_STRFTIME)
-#include <time.h>
 #include <locale.h>
 static char *timestamp (void)
 {
@@ -117,6 +114,13 @@ static char *timestamp (void)
 #define timestamp rfc822timestamp
 #endif
 
+static RETSIGTYPE donothing(int sig) 
+{
+    extern volatile int lastsig;       /* declared in idle.c */
+    set_signal_handler(sig, donothing);
+    lastsig = sig;
+}
+
 int main(int argc, char **argv)
 {
     int bkgd = FALSE;
@@ -154,10 +158,7 @@ int main(int argc, char **argv)
     }
 
 #define IDFILE_NAME    ".fetchids"
-    run.idfile = (char *) xmalloc(strlen(fmhome)+sizeof(IDFILE_NAME)+2);
-    strcpy(run.idfile, fmhome);
-    strcat(run.idfile, "/");
-    strcat(run.idfile, IDFILE_NAME);
+    run.idfile = prependdir (IDFILE_NAME, fmhome);
   
     outlevel = O_NORMAL;
 
@@ -171,6 +172,14 @@ int main(int argc, char **argv)
      */
     lock_dispose();
 
+#ifdef HAVE_GETCWD
+    /* save the current directory */
+    if (getcwd (currentwd, sizeof (currentwd)) == NULL) {
+       report(stderr, GT_("could not get current working directory\n"));
+       currentwd[0] = 0;
+    }
+#endif
+
     if ((parsestatus = parsecmdline(argc,argv, &cmd_run, &cmd_opts)) < 0)
        exit(PS_SYNTAX);
 
@@ -207,21 +216,31 @@ int main(int argc, char **argv)
 #ifdef SSL_ENABLE
        printf("+SSL");
 #endif
-#if OPIE_ENABLE
+#ifdef OPIE_ENABLE
        printf("+OPIE");
 #endif /* OPIE_ENABLE */
-#if INET6_ENABLE
+#ifdef INET6_ENABLE
        printf("+INET6");
 #endif /* INET6_ENABLE */
-#if NET_SECURITY
+#ifdef HAVE_PKG_hesiod
+       printf("+HESIOD");
+#endif
+#ifdef NET_SECURITY
        printf("+NETSEC");
 #endif /* NET_SECURITY */
 #ifdef HAVE_SOCKS
        printf("+SOCKS");
 #endif /* HAVE_SOCKS */
-#if ENABLE_NLS
+#ifdef ENABLE_NLS
        printf("+NLS");
 #endif /* ENABLE_NLS */
+       putchar('\n');
+       fputs("Fallback MDA: ", stdout);
+#ifdef FALLBACK_MDA
+       fputs(FALLBACK_MDA, stdout);
+#else
+       fputs("(none)", stdout);
+#endif
        putchar('\n');
        fflush(stdout);
 
@@ -269,10 +288,7 @@ int main(int argc, char **argv)
 
 #define        NETRC_FILE      ".netrc"
     /* parse the ~/.netrc file (if present) for future password lookups. */
-    xalloca(netrc_file, char *, strlen(home) + sizeof(NETRC_FILE) + 2);
-    strcpy (netrc_file, home);
-    strcat (netrc_file, "/");
-    strcat (netrc_file, NETRC_FILE);
+    netrc_file = prependdir (NETRC_FILE, home);
     netrc_list = parse_netrc(netrc_file);
 #undef NETRC_FILE
 
@@ -353,6 +369,15 @@ int main(int argc, char **argv)
            if (argc == 2)
                exit(PS_EXCLUDE);
        }
+       else if (getpid() == pid)
+       {
+           /* this test enables re-execing on a changed rcfile */
+           if (argc == 2)
+           {
+               fprintf(stderr,GT_("fetchmail: no other fetchmail is running\n"));
+               exit(PS_EXCLUDE);
+           }
+       }
        else if (kill(pid, SIGTERM) < 0)
        {
            fprintf(stderr,GT_("fetchmail: error killing %s fetchmail at %d; bailing out.\n"),
@@ -394,17 +419,14 @@ int main(int argc, char **argv)
                 pid);
                return(PS_EXCLUDE);
        }
+       else if (getpid() == pid)
+           /* this test enables re-execing on a changed rcfile */
+           lock_assert();
        else if (argc > 1)
        {
-           /* this test enables re-execing on a changed rcfile */
-           if (getpid() == pid)
-               lock_assert();
-           else
-           {
-               fprintf(stderr,
-                       GT_("fetchmail: can't accept options while a background fetchmail is running.\n"));
-               return(PS_EXCLUDE);
-           }
+           fprintf(stderr,
+                   GT_("fetchmail: can't accept options while a background fetchmail is running.\n"));
+           return(PS_EXCLUDE);
        }
        else if (kill(pid, SIGUSR1) == 0)
        {
@@ -479,16 +501,18 @@ int main(int argc, char **argv)
         * We'll set up a handler for these when we're sleeping,
         * but ignore them otherwise so as not to interrupt a poll.
         */
-       signal(SIGUSR1, SIG_IGN);
-       if (run.poll_interval && !getuid())
-           signal(SIGHUP, SIG_IGN);
+       set_signal_handler(SIGUSR1, SIG_IGN);
+       if (run.poll_interval && getuid() == ROOT_UID)
+           set_signal_handler(SIGHUP, SIG_IGN);
     }
     else
     {
-       if (run.logfile && access(run.logfile, F_OK) == 0)
+       if (run.logfile && !nodetach && access(run.logfile, F_OK) == 0)
        {
-           freopen(run.logfile, "a", stdout);
-           freopen(run.logfile, "a", stderr);
+           if (!freopen(run.logfile, "a", stdout))
+                   report(stderr, GT_("could not open %s to append logs to \n"), run.logfile);
+           if (!freopen(run.logfile, "a", stderr))
+                   report(stdout, GT_("could not open %s to append logs to \n"), run.logfile);
        }
     }
 
@@ -498,12 +522,12 @@ int main(int argc, char **argv)
 
     /* beyond here we don't want more than one fetchmail running per user */
     umask(0077);
-    signal(SIGABRT, terminate_run);
-    signal(SIGINT, terminate_run);
-    signal(SIGTERM, terminate_run);
-    signal(SIGALRM, terminate_run);
-    signal(SIGPIPE, terminate_run);
-    signal(SIGQUIT, terminate_run);
+    set_signal_handler(SIGABRT, terminate_run);
+    set_signal_handler(SIGINT, terminate_run);
+    set_signal_handler(SIGTERM, terminate_run);
+    set_signal_handler(SIGALRM, terminate_run);
+    set_signal_handler(SIGPIPE, terminate_run);
+    set_signal_handler(SIGQUIT, terminate_run);
 
     /* here's the exclusion lock */
     lock_or_die();
@@ -532,6 +556,13 @@ int main(int argc, char **argv)
        else if (rcstat.st_mtime > parsetime)
        {
            report(stdout, GT_("restarting fetchmail (%s changed)\n"), rcfile);
+
+#ifdef HAVE_GETCWD
+           /* restore the startup directory */
+           if (!currentwd[0] || chdir (currentwd) == -1)
+               report(stderr, GT_("attempt to re-exec may fail as directory has not been restored\n"));
+#endif
+
            /*
             * Matthias Andree: Isn't this prone to introduction of
             * "false" programs by interfering with PATH? Those
@@ -602,7 +633,7 @@ int main(int argc, char **argv)
                        }
                    }
 
-#if (defined(linux) && !INET6_ENABLE) || defined(__FreeBSD__)
+#if (defined(linux) && !defined(INET6_ENABLE)) || defined(__FreeBSD__)
                    /*
                     * Don't do monitoring if we were woken by a signal.
                     * Note that interface_approve() does its own error logging.
@@ -611,13 +642,20 @@ int main(int argc, char **argv)
                        continue;
 #endif /* (defined(linux) && !INET6_ENABLE) || defined(__FreeBSD__) */
 
+                   dofastuidl = 0; /* this is reset in the driver if required */
+
                    querystatus = query_host(ctl);
 
+                   if (NUM_NONZERO(ctl->fastuidl))
+                       ctl->fastuidlcount = (ctl->fastuidlcount + 1) % ctl->fastuidl;
 #ifdef POP3_ENABLE
                    /* leave the UIDL state alone if there have been any errors */
                    if (!check_only &&
                                ((querystatus==PS_SUCCESS) || (querystatus==PS_NOMAIL) || (querystatus==PS_MAXFETCH)))
                        uid_swap_lists(ctl);
+                   else
+                       uid_discard_new_list(ctl);
+                   uid_reset_num(ctl);
 #endif  /* POP3_ENABLE */
 
                    if (querystatus == PS_SUCCESS)
@@ -659,7 +697,7 @@ int main(int argc, char **argv)
                            break;
                        }
 
-#if (defined(linux) && !INET6_ENABLE) || defined (__FreeBSD__)
+#if (defined(linux) && !defined(INET6_ENABLE)) || defined (__FreeBSD__)
                    if (ctl->server.monitor)
                    {
                        /*
@@ -706,9 +744,20 @@ int main(int argc, char **argv)
                exit(PS_AUTHFAIL);
            }
 
-           if (outlevel >= O_VERBOSE)
+           if (outlevel > O_SILENT)
                report(stdout, 
-                      GT_("fetchmail: sleeping at %s\n"), timestamp());
+                      GT_("sleeping at %s\n"), timestamp());
+
+           /*
+            * With this simple hack, we make it possible for a foreground 
+            * fetchmail to wake up one in daemon mode.  What we want is the
+            * side effect of interrupting any sleep that may be going on,
+            * forcing fetchmail to re-poll its hosts.  The second line is
+            * for people who think all system daemons wake up on SIGHUP.
+            */
+           set_signal_handler(SIGUSR1, donothing);
+           if (getuid() != ROOT_UID)
+               set_signal_handler(SIGHUP, donothing);
 
            /*
             * OK, now pause until it's time for the next poll cycle.
@@ -718,18 +767,19 @@ int main(int argc, char **argv)
             */
            if ((lastsig = interruptible_idle(run.poll_interval)))
            {
+               if (outlevel > O_SILENT)
 #ifdef SYS_SIGLIST_DECLARED
-               report(stdout, 
+                   report(stdout, 
                       GT_("awakened by %s\n"), sys_siglist[lastsig]);
 #else
-               report(stdout, 
+                   report(stdout, 
                       GT_("awakened by signal %d\n"), lastsig);
 #endif
                for (ctl = querylist; ctl; ctl = ctl->next)
                    ctl->wedged = FALSE;
            }
 
-           if (outlevel >= O_VERBOSE)
+           if (outlevel > O_SILENT)
                report(stdout, GT_("awakened at %s\n"), timestamp());
        }
     } while
@@ -778,7 +828,7 @@ static void optmerge(struct query *h2, struct query *h1, int force)
 #define FLAG_MERGE(fld) if (force ? !!h1->fld : !h2->fld) h2->fld = h1->fld
     FLAG_MERGE(server.via);
     FLAG_MERGE(server.protocol);
-#if INET6_ENABLE
+#ifdef INET6_ENABLE
     FLAG_MERGE(server.service);
     FLAG_MERGE(server.netsec);
 #else /* INET6_ENABLE */
@@ -830,6 +880,8 @@ static void optmerge(struct query *h2, struct query *h1, int force)
     FLAG_MERGE(limit);
     FLAG_MERGE(warnings);
     FLAG_MERGE(fetchlimit);
+    FLAG_MERGE(fetchsizelimit);
+    FLAG_MERGE(fastuidl);
     FLAG_MERGE(batchlimit);
 #ifdef SSL_ENABLE
     FLAG_MERGE(use_ssl);
@@ -853,6 +905,7 @@ static int load_params(int argc, char **argv, int optind)
     struct passwd *pw;
     struct query def_opts, *ctl;
     struct stat rcstat;
+    char *p;
 
     run.bouncemail = TRUE;
     run.spambounce = FALSE;    /* don't bounce back to innocent bystanders */
@@ -861,18 +914,25 @@ static int load_params(int argc, char **argv, int optind)
     def_opts.smtp_socket = -1;
     def_opts.smtpaddress = (char *)0;
     def_opts.smtpname = (char *)0;
-#define ANTISPAM(n)    save_str(&def_opts.antispam, STRING_DUMMY, 0)->val.status.num = (n)
-    ANTISPAM(571);     /* sendmail */
-    ANTISPAM(550);     /* old exim */
-    ANTISPAM(501);     /* new exim */
-    ANTISPAM(554);     /* Postfix */
-#undef ANTISPAM
-
     def_opts.server.protocol = P_AUTO;
     def_opts.server.timeout = CLIENT_TIMEOUT;
+    def_opts.server.esmtp_name = user;
     def_opts.warnings = WARNING_INTERVAL;
     def_opts.remotename = user;
     def_opts.listener = SMTP_MODE;
+    def_opts.fetchsizelimit = 100;
+    def_opts.fastuidl = 10;
+
+    /* get the location of rcfile */
+    rcfiledir[0] = 0;
+    p = strrchr (rcfile, '/');
+    if (p && (p - rcfile) < sizeof (rcfiledir)) {
+       *p = 0;                 /* replace '/' by '0' */
+       strcpy (rcfiledir, rcfile);
+       *p = '/';               /* restore '/' */
+       if (!rcfiledir[0])      /* "/.fetchmailrc" case */
+           strcpy (rcfiledir, "/");
+    }
 
     /* note the parse time, so we can pick up on modifications */
     parsetime = 0;     /* foil compiler warnings */
@@ -1002,14 +1062,30 @@ static int load_params(int argc, char **argv, int optind)
     {
        ctl->wedged = FALSE;
 
-       if (configdump || ctl->active )
-       {
-           /* merge in defaults */
-           optmerge(ctl, &def_opts, FALSE);
+       /* merge in defaults */
+       optmerge(ctl, &def_opts, FALSE);
 
-           /* force command-line options */
-           optmerge(ctl, &cmd_opts, TRUE);
+       /* force command-line options */
+       optmerge(ctl, &cmd_opts, TRUE);
 
+       /*
+        * queryname has to be set up for inactive servers too.  
+        * Otherwise the UIDL code core-dumps on startup.
+        */
+       if (ctl->server.via) 
+           ctl->server.queryname = xstrdup(ctl->server.via);
+       else
+           ctl->server.queryname = xstrdup(ctl->server.pollname);
+
+       /*
+        * We no longer do DNS lookups at startup.
+        * This is a kluge.  It enables users to edit their
+        * configurations when DNS isn't available.
+        */
+       ctl->server.truename = xstrdup(ctl->server.queryname);
+
+       if (configdump || ctl->active )
+       {
            /* this code enables flags to be turned off */
 #define DEFAULT(flag, dflt)    if (flag == FLAG_TRUE)\
                                        flag = TRUE;\
@@ -1035,11 +1111,15 @@ static int load_params(int argc, char **argv, int optind)
            DEFAULT(ctl->sslcertck, FALSE);
 #endif
            DEFAULT(ctl->server.checkalias, FALSE);
+#ifndef SSL_ENABLE
            if (ctl->use_ssl) 
            {
                report(stderr, GT_("SSL support is not compiled in.\n"));
                exit(PS_SYNTAX);
            }
+#endif /* SSL_ENABLE */
+           /* one global gets treated specially */
+           DEFAULT(run.showdots, run.poll_interval==0 || nodetach);
 #undef DEFAULT
 
            /*
@@ -1071,18 +1151,6 @@ static int load_params(int argc, char **argv, int optind)
            }
 #endif /* !HAVE_GETHOSTBYNAME || !HAVE_RES_SEARCH */
 
-           if (ctl->server.via) 
-               ctl->server.queryname = xstrdup(ctl->server.via);
-           else
-               ctl->server.queryname = xstrdup(ctl->server.pollname);
-
-           /*
-            * We no longer do DNS lookups at startup.
-            * This is a kluge.  It enables users to edit their
-            * configurations when DNS isn't available.
-            */
-           ctl->server.truename = xstrdup(ctl->server.queryname);
-
            /* if no folders were specified, set up the null one as default */
            if (!ctl->mailboxes)
                save_str(&ctl->mailboxes, (char *)NULL, 0);
@@ -1091,7 +1159,7 @@ static int load_params(int argc, char **argv, int optind)
            if (ctl->server.timeout == -1)      
                ctl->server.timeout = CLIENT_TIMEOUT;
 
-#if !INET6_ENABLE
+#ifndef INET6_ENABLE
            /* sanity checks */
            if (ctl->server.port < 0)
            {
@@ -1154,7 +1222,7 @@ static int load_params(int argc, char **argv, int optind)
      */
     if (!run.postmaster)
     {
-       if (getuid())                           /* ordinary user */
+       if (getuid() != ROOT_UID)               /* ordinary user */
            run.postmaster = user;
        else                                    /* root */
            run.postmaster = "postmaster";
@@ -1163,7 +1231,7 @@ static int load_params(int argc, char **argv, int optind)
     return(implicitmode);
 }
 
-static void terminate_poll(int sig)
+static RETSIGTYPE terminate_poll(int sig)
 /* to be executed at the end of a poll cycle */
 {
     /*
@@ -1195,10 +1263,7 @@ static void terminate_poll(int sig)
            {
                /* don't send QUIT for ODMR case because we're acting
                   as a proxy between the SMTP server and client. */
-               if (ctl->server.protocol != P_ODMR)
-                   SMTP_quit(ctl->smtp_socket);
-               SockClose(ctl->smtp_socket);
-               ctl->smtp_socket = -1;
+               smtp_close(ctl, ctl->server.protocol != P_ODMR);
            }
     }
 
@@ -1213,7 +1278,7 @@ static void terminate_poll(int sig)
 #endif /* POP3_ENABLE */
 }
 
-static void terminate_run(int sig)
+static RETSIGTYPE terminate_run(int sig)
 /* to be executed on normal or signal-induced termination */
 {
     struct query       *ctl;
@@ -1270,7 +1335,7 @@ static int query_host(struct query *ctl)
      * If we're syslogging the progress messages are automatically timestamped.
      * Force timestamping if we're going to a logfile.
      */
-    if (outlevel >= O_VERBOSE || (run.logfile && outlevel > O_SILENT))
+    if (outlevel >= O_VERBOSE)
     {
        report(stdout, GT_("%s querying %s (protocol %s) at %s: poll started\n"),
               VERSION,
@@ -1284,11 +1349,15 @@ static int query_host(struct query *ctl)
        for (i = 0; i < sizeof(autoprobe)/sizeof(autoprobe[0]); i++)
        {
            ctl->server.protocol = autoprobe[i];
-           st = query_host(ctl);
-           if (st == PS_SUCCESS || st == PS_NOMAIL || st == PS_AUTHFAIL || st == PS_LOCKBUSY || st == PS_SMTP || st == PS_MAXFETCH)
+           do {
+               st = query_host(ctl);
+           } while 
+               (st == PS_REPOLL);
+           if (st == PS_SUCCESS || st == PS_NOMAIL || st == PS_AUTHFAIL || st == PS_LOCKBUSY || st == PS_SMTP || st == PS_MAXFETCH || st == PS_DNS)
                break;
        }
        ctl->server.protocol = P_AUTO;
+       break;
     case P_POP2:
 #ifdef POP2_ENABLE
        st = doPOP2(ctl);
@@ -1301,7 +1370,9 @@ static int query_host(struct query *ctl)
     case P_APOP:
     case P_RPOP:
 #ifdef POP3_ENABLE
-       st = doPOP3(ctl);
+       do {
+           st = doPOP3(ctl);
+       } while (st == PS_REPOLL);
 #else
        report(stderr, GT_("POP3 support is not configured.\n"));
        st = PS_PROTOCOL;
@@ -1309,11 +1380,14 @@ static int query_host(struct query *ctl)
        break;
     case P_IMAP:
 #ifdef IMAP_ENABLE
-       st = doIMAP(ctl);
+       do {
+           st = doIMAP(ctl);
+       } while (st == PS_REPOLL);
 #else
        report(stderr, GT_("IMAP support is not configured.\n"));
        st = PS_PROTOCOL;
 #endif /* IMAP_ENABLE */
+       break;
     case P_ETRN:
 #ifndef ETRN_ENABLE
        report(stderr, GT_("ETRN support is not configured.\n"));
@@ -1325,6 +1399,7 @@ static int query_host(struct query *ctl)
        report(stderr, GT_("Cannot support ETRN without gethostbyname(2).\n"));
        st = PS_PROTOCOL;
 #endif /* HAVE_GETHOSTBYNAME */
+       break;
 #endif /* ETRN_ENABLE */
     case P_ODMR:
 #ifndef ODMR_ENABLE
@@ -1338,6 +1413,7 @@ static int query_host(struct query *ctl)
        st = PS_PROTOCOL;
 #endif /* HAVE_GETHOSTBYNAME */
 #endif /* ODMR_ENABLE */
+       break;
     default:
        report(stderr, GT_("unsupported protocol selected.\n"));
        st = PS_PROTOCOL;
@@ -1347,7 +1423,7 @@ static int query_host(struct query *ctl)
      * If we're syslogging the progress messages are automatically timestamped.
      * Force timestamping if we're going to a logfile.
      */
-    if (outlevel >= O_VERBOSE || (run.logfile && outlevel > O_SILENT))
+    if (outlevel >= O_VERBOSE)
     {
        report(stdout, GT_("%s querying %s (protocol %s) at %s: poll completed\n"),
               VERSION,
@@ -1426,7 +1502,7 @@ static void dump_params (struct runctl *runp,
        }
 
        if (ctl->server.protocol == P_POP3 
-#if INET6_ENABLE
+#ifdef INET6_ENABLE
            && ctl->server.service && !strcmp(ctl->server.service, KPOP_PORT)
 #else /* INET6_ENABLE */
            && ctl->server.port == KPOP_PORT
@@ -1437,7 +1513,7 @@ static void dump_params (struct runctl *runp,
                   ctl->server.authenticate == A_KERBEROS_V5 ? "V" : "IV");
        else
            printf(GT_("  Protocol is %s"), showproto(ctl->server.protocol));
-#if INET6_ENABLE
+#ifdef INET6_ENABLE
        if (ctl->server.service)
            printf(GT_(" (using service %s)"), ctl->server.service);
        if (ctl->server.netsec)
@@ -1487,6 +1563,8 @@ static void dump_params (struct runctl *runp,
 #ifdef SSL_ENABLE
        if (ctl->use_ssl)
            printf(GT_("  SSL encrypted sessions enabled.\n"));
+       if (ctl->sslproto)
+           printf(GT_("  SSL protocol: %s.\n"), ctl->sslproto);
        if (ctl->sslcertck) {
            printf(GT_("  SSL server certificate checking enabled.\n"));
            if (ctl->sslcertpath != NULL)
@@ -1512,7 +1590,7 @@ static void dump_params (struct runctl *runp,
 
                printf(GT_("  Selected mailboxes are:"));
                for (idp = ctl->mailboxes; idp; idp = idp->next)
-                   printf(" %s", idp->id);
+                   printf(" %s", (char *)idp->id);
                printf("\n");
            }
            printf(GT_("  %s messages will be retrieved (--all %s).\n"),
@@ -1566,6 +1644,20 @@ static void dump_params (struct runctl *runp,
                       ctl->fetchlimit, ctl->fetchlimit);
            else if (outlevel >= O_VERBOSE)
                printf(GT_("  No received-message limit (--fetchlimit 0).\n"));
+           if (NUM_NONZERO(ctl->fetchsizelimit))
+               printf(GT_("  Fetch message size limit is %d (--fetchsizelimit %d).\n"),
+                      ctl->fetchsizelimit, ctl->fetchsizelimit);
+           else if (outlevel >= O_VERBOSE)
+               printf(GT_("  No fetch message size limit (--fetchsizelimit 0).\n"));
+           if (NUM_NONZERO(ctl->fastuidl) && MAILBOX_PROTOCOL(ctl))
+           {
+               if (ctl->fastuidl == 1)
+                   printf(GT_("  Do binary search of UIDs during each poll (--fastuidl 1).\n"));
+               else
+                   printf(GT_("  Do binary search of UIDs during %d out of %d polls (--fastuidl %d).\n"), ctl->fastuidl - 1, ctl->fastuidl, ctl->fastuidl);
+           }
+           else if (outlevel >= O_VERBOSE)
+               printf(GT_("   Do linear search of UIDs during each poll (--fastuidl 0).\n"));
            if (NUM_NONZERO(ctl->batchlimit))
                printf(GT_("  SMTP message batch limit is %d.\n"), ctl->batchlimit);
            else if (outlevel >= O_VERBOSE)
@@ -1585,7 +1677,7 @@ static void dump_params (struct runctl *runp,
            printf(GT_("  Domains for which mail will be fetched are:"));
            for (idp = ctl->domainlist; idp; idp = idp->next)
            {
-               printf(" %s", idp->id);
+               printf(" %s", (char *)idp->id);
                if (!idp->val.status.mark)
                    printf(GT_(" (default)"));
            }
@@ -1605,7 +1697,7 @@ static void dump_params (struct runctl *runp,
                       ctl->listener);
                for (idp = ctl->smtphunt; idp; idp = idp->next)
                {
-                   printf(" %s", idp->id);
+                   printf(" %s", (char *)idp->id);
                    if (!idp->val.status.mark)
                        printf(GT_(" (default)"));
                }
@@ -1663,9 +1755,9 @@ static void dump_params (struct runctl *runp,
                    {
                        for (idp = ctl->localnames; idp; idp = idp->next)
                            if (idp->val.id2)
-                               printf("\t%s -> %s\n", idp->id, idp->val.id2);
+                               printf("\t%s -> %s\n", (char *)idp->id, (char *)idp->val.id2);
                            else
-                               printf("\t%s\n", idp->id);
+                               printf("\t%s\n", (char *)idp->id);
                        if (ctl->wildcard)
                            fputs("\t*\n", stdout);
                    }
@@ -1704,7 +1796,7 @@ static void dump_params (struct runctl *runp,
 
                            printf(GT_("  Predeclared mailserver aliases:"));
                            for (idp = ctl->server.akalist; idp; idp = idp->next)
-                               printf(" %s", idp->id);
+                               printf(" %s", (char *)idp->id);
                            putchar('\n');
                        }
                        if (ctl->server.localdomains)
@@ -1713,7 +1805,7 @@ static void dump_params (struct runctl *runp,
 
                            printf(GT_("  Local domains:"));
                            for (idp = ctl->server.localdomains; idp; idp = idp->next)
-                               printf(" %s", idp->id);
+                               printf(" %s", (char *)idp->id);
                            putchar('\n');
                        }
                    }
@@ -1754,7 +1846,7 @@ static void dump_params (struct runctl *runp,
                printf(GT_("  %d UIDs saved.\n"), count);
                if (outlevel >= O_VERBOSE)
                    for (idp = ctl->oldsaved; idp; idp = idp->next)
-                       printf("\t%s\n", idp->id);
+                       printf("\t%s\n", (char *)idp->id);
            }
        }