char *user; /* the name of the invoking user */
char *home; /* invoking user's home directory */
char *fmhome; /* fetchmail's home directory */
-char *program_name; /* the name to prefix error messages with */
+const 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 */
+const char *fetchmailhost; /* either `localhost' or the host's FQDN */
static int quitonly; /* if we should quit after killing the running daemon */
static void printcopyright(FILE *fp) {
fprintf(fp, GT_("Copyright (C) 2002, 2003 Eric S. Raymond\n"
- "Copyright (C) 2004 Matthias Andree, Eric S. Raymond, Rob F. Funk, Graham Wilson\n"
- "Copyright (C) 2005-2006 Matthias Andree, Sunil Shetye\n"
+ "Copyright (C) 2004 Matthias Andree, Eric S. Raymond,\n"
+ " Robert M. Funk, Graham Wilson\n"
+ "Copyright (C) 2005 - 2006, 2010 - 2012 Sunil Shetye\n"
+ "Copyright (C) 2005 - 2012 Matthias Andree\n"
));
fprintf(fp, GT_("Fetchmail comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n"
"are welcome to redistribute it under certain conditions. For details,\n"
"please see the file COPYING in the source or documentation directory.\n"));
+#ifdef SSL_ENABLE
+ /* Do not translate this */
+ fprintf(fp, "This product includes software developed by the OpenSSL Project\nfor use in the OpenSSL Toolkit. (http://www.openssl.org/)\n");
+#endif
}
const char *iana_charset;
#ifdef ENABLE_NLS
"+NLS"
#endif /* ENABLE_NLS */
+#ifdef KERBEROS_V4
+ "+KRB4"
+#endif /* KERBEROS_V4 */
+#ifdef KERBEROS_V5
+ "+KRB5"
+#endif /* KERBEROS_V5 */
+#ifndef HAVE_RES_SEARCH
+ "-DNS"
+#endif
".\n";
printf(GT_("This is fetchmail release %s"), VERSION);
fputs(features, stdout);
fflush(stdout);
/* this is an attempt to help remote debugging */
- system("uname -a");
+ if (system("uname -a")) { /* NOOP to quench GCC complaint */ }
}
/* avoid parsing the config file if all we're doing is killing a daemon */
if (!quitonly)
implicitmode = load_params(argc, argv, optind);
+ /* precedence: logfile (if effective) overrides syslog. */
+ if (run.logfile && run.poll_interval && !nodetach) {
+ run.use_syslog = 0;
+ }
+
#if defined(HAVE_SYSLOG)
/* logging should be set up early in case we were restarted from exec */
if (run.use_syslog)
}
else if (kill(pid, SIGTERM) < 0)
{
- fprintf(stderr,GT_("fetchmail: error killing %s fetchmail at %d; bailing out.\n"),
- bkgd ? GT_("background") : GT_("foreground"), pid);
+ fprintf(stderr,GT_("fetchmail: error killing %s fetchmail at %ld; bailing out.\n"),
+ bkgd ? GT_("background") : GT_("foreground"), (long)pid);
exit(PS_EXCLUDE);
}
else
int maxwait;
if (outlevel > O_SILENT)
- fprintf(stderr,GT_("fetchmail: %s fetchmail at %d killed.\n"),
- bkgd ? GT_("background") : GT_("foreground"), pid);
+ fprintf(stderr,GT_("fetchmail: %s fetchmail at %ld killed.\n"),
+ bkgd ? GT_("background") : GT_("foreground"), (long)pid);
/* We used to nuke the other process's lock here, with
* fm_lock_release(), which is broken. The other process
* needs to clear its lock by itself. */
else if (!implicitmode)
{
fprintf(stderr,
- GT_("fetchmail: can't poll specified hosts with another fetchmail running at %d.\n"),
- pid);
+ GT_("fetchmail: can't poll specified hosts with another fetchmail running at %ld.\n"),
+ (long)pid);
return(PS_EXCLUDE);
}
else if (!bkgd)
{
fprintf(stderr,
- GT_("fetchmail: another foreground fetchmail is running at %d.\n"),
- pid);
+ GT_("fetchmail: another foreground fetchmail is running at %ld.\n"),
+ (long)pid);
return(PS_EXCLUDE);
}
else if (getpid() == pid)
else if (kill(pid, SIGUSR1) == 0)
{
fprintf(stderr,
- GT_("fetchmail: background fetchmail at %d awakened.\n"),
- pid);
+ GT_("fetchmail: background fetchmail at %ld awakened.\n"),
+ (long)pid);
return(0);
}
else
* SIGUSR1/SIGHUP transmission.
*/
fprintf(stderr,
- GT_("fetchmail: elder sibling at %d died mysteriously.\n"),
- pid);
+ GT_("fetchmail: elder sibling at %ld died mysteriously.\n"),
+ (long)pid);
return(PS_UNDEFINED);
}
}
const char* password_prompt = GT_("Enter password for %s@%s: ");
size_t pplen = strlen(password_prompt) + strlen(ctl->remotename) + strlen(ctl->server.pollname) + 1;
- tmpbuf = xmalloc(pplen);
+ tmpbuf = (char *)xmalloc(pplen);
snprintf(tmpbuf, pplen, password_prompt,
ctl->remotename, ctl->server.pollname);
ctl->password = xstrdup((char *)fm_getpassword(tmpbuf));
/* avoid zombies from plugins */
deal_with_sigchld();
+ /* Fix up log destination - if the if() is true, the precedence rule
+ * above hasn't killed off the syslog option, because the logfile
+ * option is ineffective (because we're not detached or not in
+ * deamon mode), so kill it for the benefit of other parts of the
+ * code. */
if (run.logfile && run.use_syslog)
- fprintf(stderr, GT_("fetchmail: Warning: syslog and logfile are set. Check both for logs!\n"));
+ run.logfile = 0;
/*
* Maybe time to go to demon mode...
exit(rc);
}
}
- report(stdout, GT_("starting fetchmail %s daemon \n"), VERSION);
+ report(stdout, GT_("starting fetchmail %s daemon\n"), VERSION);
/*
* We'll set up a handler for these when we're sleeping,
if (run.logfile && !nodetach && access(run.logfile, F_OK) == 0)
{
if (!freopen(run.logfile, "a", stdout))
- report(stderr, GT_("could not open %s to append logs to \n"), run.logfile);
+ 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);
+ report(stdout, GT_("could not open %s to append logs to\n"), run.logfile);
if (run.use_syslog)
report(stdout, GT_("fetchmail: Warning: syslog and logfile are set. Check both for logs!\n"));
}
/* here's the exclusion lock */
fm_lock_or_die();
+ if (check_only && outlevel >= O_VERBOSE) {
+ report(stdout, GT_("--check mode enabled, not fetching mail\n"));
+ }
+
/*
* Query all hosts. If there's only one, the error return will
* reflect the status of that transaction.
report(stderr, GT_("attempt to re-exec fetchmail failed\n"));
}
-#if defined(HAVE_RES_SEARCH) && defined(USE_TCPIP_FOR_DNS)
- /*
- * This was an efficiency hack that backfired. The theory
- * was that using TCP/IP for DNS queries would get us better
- * reliability and shave off some per-UDP-packet costs.
- * Unfortunately it interacted badly with diald, which effectively
- * filters out DNS queries over TCP/IP for reasons having to do
- * with some obscure Linux kernel problem involving bootstrapping of
- * dynamically-addressed links. I don't understand this mess
- * and don't want to, so it's "See ya!" to this hack.
- */
- sethostent(TRUE); /* use TCP/IP for mailserver queries */
-#endif /* HAVE_RES_SEARCH */
-
#ifdef HAVE_RES_SEARCH
/* Boldly assume that we also have res_init() if we have
* res_search(), and call res_init() to re-read the resolv.conf
}
}
-#if defined(HAVE_RES_SEARCH) && defined(USE_TCPIP_FOR_DNS)
- endhostent(); /* release TCP/IP connection to nameserver */
-#endif /* HAVE_RES_SEARCH */
-
/* close connections cleanly */
terminate_poll(0);
exit(PS_AUTHFAIL);
}
- if (outlevel > O_SILENT)
+ if ((outlevel > O_SILENT && !run.use_syslog && isatty(1))
+ || outlevel > O_NORMAL)
report(stdout,
GT_("sleeping at %s for %d seconds\n"), timestamp(), run.poll_interval);
ctl->wedged = FALSE;
}
- if (outlevel > O_SILENT)
+ if ((outlevel > O_SILENT && !run.use_syslog && isatty(1))
+ || outlevel > O_NORMAL)
report(stdout, GT_("awakened at %s\n"), timestamp());
}
- } while
- (run.poll_interval);
+ } while (run.poll_interval);
if (outlevel >= O_VERBOSE)
report(stdout, GT_("normal termination, status %d\n"),
FLAG_MERGE(server.plugin);
FLAG_MERGE(server.plugout);
FLAG_MERGE(server.tracepolls);
+ FLAG_MERGE(server.badheader);
FLAG_MERGE(wildcard);
FLAG_MERGE(remotename);
FLAG_MERGE(sslcert);
FLAG_MERGE(sslproto);
FLAG_MERGE(sslcertck);
+ FLAG_MERGE(sslcertfile);
FLAG_MERGE(sslcertpath);
+ FLAG_MERGE(sslcommonname);
FLAG_MERGE(sslfingerprint);
#endif
FLAG_MERGE(expunge);
char *p;
run.bouncemail = TRUE;
+ run.softbounce = TRUE; /* treat permanent errors as temporary */
run.spambounce = FALSE; /* don't bounce back to innocent bystanders */
memset(&def_opts, '\0', sizeof(struct query));
def_opts.server.protocol = P_AUTO;
def_opts.server.timeout = CLIENT_TIMEOUT;
def_opts.server.esmtp_name = user;
+ def_opts.server.badheader = BHREJECT;
def_opts.warnings = WARNING_INTERVAL;
def_opts.remotename = user;
def_opts.listener = SMTP_MODE;
}
/* note the parse time, so we can pick up on modifications */
- parsetime = 0; /* foil compiler warnings */
- if (strcmp(rcfile, "-") == 0 || stat(rcfile, &rcstat) != -1)
- parsetime = rcstat.st_mtime;
- else if (errno != ENOENT)
- report(stderr, GT_("couldn't time-check the run-control file\n"));
+ if (strcmp(rcfile, "-") == 0)
+ parsetime = time(NULL);
+ else {
+ if (stat(rcfile, &rcstat) != -1)
+ parsetime = rcstat.st_mtime;
+ else if (errno != ENOENT)
+ report(stderr, GT_("couldn't time-check the run-control file\n"));
+ }
/* this builds the host list */
if ((st = prc_parse_file(rcfile, !versioninfo)) != 0)
/*
* If there's a defaults record, merge it and lose it.
+ * FIXME: we don't currently free all entries that might be in struct query.
*/
if (querylist && strcmp(querylist->server.pollname, "defaults") == 0)
{
+ struct query *tmpq;
+
for (ctl = querylist->next; ctl; ctl = ctl->next)
optmerge(ctl, querylist, FALSE);
+ tmpq = querylist;
querylist = querylist->next;
+ free(tmpq->server.pollname);
+ free(tmpq);
}
/* don't allow a defaults record after the first */
if (cmd_run.poll_interval >= 0)
run.poll_interval = cmd_run.poll_interval;
if (cmd_run.invisible)
- run.invisible = cmd_run.invisible;
+ run.invisible = (cmd_run.invisible == FLAG_TRUE);
if (cmd_run.showdots)
- run.showdots = cmd_run.showdots;
+ run.showdots = (cmd_run.showdots == FLAG_TRUE);
if (cmd_run.use_syslog)
run.use_syslog = (cmd_run.use_syslog == FLAG_TRUE);
if (cmd_run.postmaster)
run.postmaster = cmd_run.postmaster;
if (cmd_run.bouncemail)
- run.bouncemail = cmd_run.bouncemail;
+ run.bouncemail = (cmd_run.bouncemail == FLAG_TRUE);
+ if (cmd_run.softbounce)
+ run.softbounce = (cmd_run.softbounce == FLAG_TRUE);
/* check and daemon options are not compatible */
if (check_only && run.poll_interval)
flag = FALSE;\
else\
flag = (dflt)
- /* one global gets treated specially */
- DEFAULT(run.showdots, run.poll_interval==0 || nodetach);
/* merge in wired defaults, do sanity checks and prepare internal fields */
for (ctl = querylist; ctl; ctl = ctl->next)
}
#endif /* SSL_ENABLE */
#undef DEFAULT
+#ifndef KERBEROS_V4
+ if (ctl->server.authenticate == A_KERBEROS_V4) {
+ report(stderr, GT_("KERBEROS v4 support is configured, but not compiled in.\n"));
+ exit(PS_SYNTAX);
+ }
+#endif
+#ifndef KERBEROS_V5
+ if (ctl->server.authenticate == A_KERBEROS_V5) {
+ report(stderr, GT_("KERBEROS v5 support is configured, but not compiled in.\n"));
+ exit(PS_SYNTAX);
+ }
+#endif
+#ifndef GSSAPI
+ if (ctl->server.authenticate == A_GSSAPI) {
+ report(stderr, GT_("GSSAPI support is configured, but not compiled in.\n"));
+ exit(PS_SYNTAX);
+ }
+#endif
/*
* Make sure we have a nonempty host list to forward to.
else if (outlevel >= O_VERBOSE)
printf(GT_("Fetchmail will direct error mail to the sender.\n"));
+ if (!runp->softbounce)
+ printf(GT_("Fetchmail will treat permanent errors as permanent (drop messages).\n"));
+ else if (outlevel >= O_VERBOSE)
+ printf(GT_("Fetchmail will treat permanent errors as temporary (keep messages).\n"));
+
for (ctl = querylist; ctl; ctl = ctl->next)
{
if (!ctl->active || (implicit && ctl->server.skip))
printf(GT_(" OTP authentication will be forced.\n"));
break;
case A_CRAM_MD5:
- printf(GT_(" CRAM-Md5 authentication will be forced.\n"));
+ printf(GT_(" CRAM-MD5 authentication will be forced.\n"));
break;
case A_GSSAPI:
printf(GT_(" GSSAPI authentication will be forced.\n"));
printf(GT_(" SSL protocol: %s.\n"), ctl->sslproto);
if (ctl->sslcertck) {
printf(GT_(" SSL server certificate checking enabled.\n"));
- if (ctl->sslcertpath != NULL)
- printf(GT_(" SSL trusted certificate directory: %s\n"), ctl->sslcertpath);
}
+ if (ctl->sslcertfile != NULL)
+ printf(GT_(" SSL trusted certificate file: %s\n"), ctl->sslcertfile);
+ if (ctl->sslcertpath != NULL)
+ printf(GT_(" SSL trusted certificate directory: %s\n"), ctl->sslcertpath);
+ if (ctl->sslcommonname != NULL)
+ printf(GT_(" SSL server CommonName: %s\n"), ctl->sslcommonname);
if (ctl->sslfingerprint != NULL)
printf(GT_(" SSL key fingerprint (checked against the server key): %s\n"), ctl->sslfingerprint);
#endif
if (ctl->server.akalist)
{
- struct idlist *idp;
-
printf(GT_(" Predeclared mailserver aliases:"));
for (idp = ctl->server.akalist; idp; idp = idp->next)
printf(" %s", idp->id);
putchar('\n');
}
+
if (ctl->server.localdomains)
{
- struct idlist *idp;
-
printf(GT_(" Local domains:"));
for (idp = ctl->server.localdomains; idp; idp = idp->next)
printf(" %s", idp->id);
if (ctl->server.tracepolls)
printf(GT_(" Poll trace information will be added to the Received header.\n"));
else if (outlevel >= O_VERBOSE)
- printf(GT_(" No poll trace information will be added to the Received header.\n.\n"));
+ printf(GT_(" No poll trace information will be added to the Received header.\n"));
+
+ switch (ctl->server.badheader) {
+ case BHREJECT:
+ if (outlevel >= O_VERBOSE)
+ printf(GT_(" Messages with bad headers will be rejected.\n"));
+ break;
+ case BHACCEPT:
+ printf(GT_(" Messages with bad headers will be passed on.\n"));
+ break;
+ }
if (ctl->properties)
printf(GT_(" Pass-through properties \"%s\".\n"),