#include "config.h"
#include <stdio.h>
-#if defined(STDC_HEADERS)
#include <stdlib.h>
-#endif
-#if defined(HAVE_UNISTD_H)
#include <unistd.h>
-#endif
#include <fcntl.h>
#include <string.h>
#include <signal.h>
-#if defined(HAVE_SYSLOG)
#include <syslog.h>
-#endif
#include <pwd.h>
#ifdef __FreeBSD__
#include <grp.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
-#ifdef HAVE_SETRLIMIT
#include <sys/resource.h>
-#endif /* HAVE_SETRLIMIT */
#ifdef HAVE_SOCKS
#include <socks.h> /* SOCKSinit() */
#endif /* HAVE_SOCKS */
-#ifdef HAVE_LANGINFO_H
#include <langinfo.h>
-#endif
#include "fetchmail.h"
#include "socket.h"
#include "tunable.h"
#include "smtp.h"
#include "netrc.h"
-#include "i18n.h"
+#include "gettext.h"
#include "lock.h"
/* need these (and sys/types.h) for res_init() */
static struct runctl cmd_run; /* global options set from command line */
static time_t parsetime; /* time of last parse */
-static RETSIGTYPE terminate_run(int);
-static RETSIGTYPE terminate_poll(int);
+static void terminate_run(int);
+static void terminate_poll(int);
#ifdef HAVE_LIBPWMD
static pwm_t *pwm; /* the handle */
}
#endif
-#if defined(HAVE_SETLOCALE) && defined(ENABLE_NLS) && defined(HAVE_STRFTIME)
#include <locale.h>
+#if defined(ENABLE_NLS)
/** returns timestamp in current locale,
* and resets LC_TIME locale to POSIX. */
static char *timestamp (void)
#define timestamp rfc822timestamp
#endif
-static RETSIGTYPE donothing(int sig)
+static void donothing(int sig)
{
set_signal_handler(sig, donothing);
lastsig = sig;
fprintf(fp, GT_("Copyright (C) 2002, 2003 Eric S. Raymond\n"
"Copyright (C) 2004 Matthias Andree, Eric S. Raymond,\n"
" Robert M. Funk, Graham Wilson\n"
- "Copyright (C) 2005 - 2006, 2010 Sunil Shetye\n"
- "Copyright (C) 2005 - 2010 Matthias Andree\n"
+ "Copyright (C) 2005 - 2012 Matthias Andree, Sunil Shetye\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;
{
int bkgd = FALSE;
int implicitmode = FALSE;
+ flag safewithbg = FALSE; /** if parsed options are compatible with a
+ fetchmail copy running in the background */
struct query *ctl;
netrc_entry *netrc_list;
char *netrc_file, *tmpbuf;
#define IDFILE_NAME ".fetchids"
run.idfile = prependdir (IDFILE_NAME, fmhome);
-
+
outlevel = O_NORMAL;
/*
{
int i;
- i = parsecmdline(argc, argv, &cmd_run, &cmd_opts);
+ i = parsecmdline(argc, argv, &cmd_run, &cmd_opts, &safewithbg);
if (i < 0)
exit(PS_SYNTAX);
if (versioninfo)
{
const char *features =
-#ifdef POP2_ENABLE
- "+POP2"
-#endif /* POP2_ENABLE */
#ifndef POP3_ENABLE
"-POP3"
#endif /* POP3_ENABLE */
#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
#ifdef HAVE_LIBPWMD
"+PWMD"
#endif /* HAVE_LIBPWMD */
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 (run.logfile) {
+ /* nodetach -> turn off logfile option */
+ if (nodetach) {
+ if (outlevel >= O_DEBUG) { fprintf(stderr, GT_("The nodetach option is in effect, ignoring logfile option.\n")); }
+ xfree(run.logfile);
+ }
+
+ /* not in daemon mode -> turn off logfile option */
+ if (0 == run.poll_interval) {
+ if (outlevel >= O_DEBUG) { fprintf(stderr, GT_("Not running in daemon mode, ignoring logfile option.\n")); }
+ xfree(run.logfile);
+ }
+
+ /* log file not writable -> turn off logfile option */
+ if (run.logfile && 0 != access(run.logfile, F_OK)) {
+ if (outlevel >= O_DEBUG) { fprintf(stderr, GT_("Logfile \"%s\" does not exist, ignoring logfile option.\n"), run.logfile); }
+ xfree(run.logfile);
+ }
+
+ /* log file not writable -> turn off logfile option */
+ if (run.logfile && 0 != access(run.logfile, W_OK)) {
+ if (outlevel >= O_DEBUG) { fprintf(stderr, GT_("Logfile \"%s\" is not writable, aborting.\n"), run.logfile); }
+ xfree(run.logfile);
+ exit(PS_UNDEFINED);
+ }
}
-#if defined(HAVE_SYSLOG)
/* logging should be set up early in case we were restarted from exec */
if (run.use_syslog)
{
-#if defined(LOG_MAIL)
openlog(program_name, LOG_PID, LOG_MAIL);
-#else
- /* Assume BSD4.2 openlog with two arguments */
- openlog(program_name, LOG_PID);
-#endif
- report_init(-1);
+ /* precedence: logfile (if effective) overrides syslog. */
+ if (run.logfile) {
+ syslog(LOG_ERR, GT_("syslog and logfile options are both set, ignoring syslog, and logging to %s"), run.logfile);
+ run.use_syslog = 0;
+ report_init((run.poll_interval == 0 || nodetach) && !run.logfile); /* when changing this, change copy below, too */
+ } else {
+ report_init(-1);
+ }
}
else
-#endif
- report_init((run.poll_interval == 0 || nodetach) && !run.logfile);
+ report_init((run.poll_interval == 0 || nodetach) && !run.logfile); /* when changing this, change copy above, too */
#ifdef POP3_ENABLE
/* initialize UID handling */
/* construct the lockfile */
fm_lock_setup(&run);
-#ifdef HAVE_SETRLIMIT
/*
* Before getting passwords, disable core dumps unless -v -d0 mode is on.
* Core dumps could otherwise contain passwords to be scavenged by a
corelimit.rlim_max = 0;
setrlimit(RLIMIT_CORE, &corelimit);
}
-#endif /* HAVE_SETRLIMIT */
#define NETRC_FILE ".netrc"
/* parse the ~/.netrc file (if present) for future password lookups. */
else if (getpid() == pid)
/* this test enables re-execing on a changed rcfile */
fm_lock_assert();
- else if (argc > 1)
+ else if (argc > 1 && !safewithbg)
{
fprintf(stderr,
GT_("fetchmail: can't accept options while a background fetchmail is running.\n"));
+ {
+ int i;
+ fprintf(stderr, "argc = %d, arg list:\n", argc);
+ for (i = 1; i < argc; i++) fprintf(stderr, "arg %d = \"%s\"\n", i, argv[i]);
+ }
return(PS_EXCLUDE);
}
else if (kill(pid, SIGUSR1) == 0)
{
- fprintf(stderr,
- GT_("fetchmail: background fetchmail at %ld awakened.\n"),
- (long)pid);
+ if (outlevel > O_SILENT)
+ fprintf(stderr,
+ GT_("fetchmail: background fetchmail at %ld awakened.\n"),
+ (long)pid);
return(0);
}
else
else
{
/* not in daemon mode */
- if (run.logfile && !nodetach && access(run.logfile, F_OK) == 0)
- {
+ if (run.logfile)
+ {
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);
- if (run.use_syslog)
- report(stdout, GT_("fetchmail: Warning: syslog and logfile are set. Check both for logs!\n"));
}
}
FLAG_MERGE(server.skip);
FLAG_MERGE(server.dns);
FLAG_MERGE(server.checkalias);
- FLAG_MERGE(server.uidl);
FLAG_MERGE(server.principal);
#ifdef CAN_MONITOR
FLAG_MERGE(server.plugout);
FLAG_MERGE(server.tracepolls);
FLAG_MERGE(server.badheader);
+ FLAG_MERGE(server.retrieveerror);
FLAG_MERGE(wildcard);
FLAG_MERGE(remotename);
ctl->server.via =
ctl->server.pollname = xstrdup(argv[optind]);
#else
- ctl->server.via =
- ctl->server.pollname = xstrdup(argv[optind]);
+ ctl->server.via =
+ ctl->server.pollname = xstrdup(argv[optind]);
#endif
ctl->active = TRUE;
ctl->server.lead_server = (struct hostdata *)NULL;
for (ctl = querylist; ctl; ctl = ctl->next)
if (ctl->active &&
(ctl->server.protocol==P_ETRN || ctl->server.protocol==P_ODMR
- || ctl->server.authenticate == A_KERBEROS_V4
|| ctl->server.authenticate == A_KERBEROS_V5))
{
fetchmailhost = host_fqdn(1);
DEFAULT(ctl->mimedecode, FALSE);
DEFAULT(ctl->idle, FALSE);
DEFAULT(ctl->server.dns, TRUE);
- DEFAULT(ctl->server.uidl, FALSE);
DEFAULT(ctl->use_ssl, FALSE);
DEFAULT(ctl->sslcertck, FALSE);
DEFAULT(ctl->server.checkalias, FALSE);
}
#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"));
if (!ctl->localnames) /* for local delivery via SMTP */
save_str_pair(&ctl->localnames, user, NULL);
-#ifndef HAVE_RES_SEARCH
- /* can't handle multidrop mailboxes unless we can do DNS lookups */
- if (MULTIDROP(ctl) && ctl->server.dns)
- {
- ctl->server.dns = FALSE;
- report(stderr, GT_("fetchmail: warning: no DNS available to check multidrop fetches from %s\n"), ctl->server.pollname);
- }
-#endif /* !HAVE_RES_SEARCH */
-
/*
* can't handle multidrop mailboxes without "envelope"
* option, this causes truckloads full of support complaints
ctl->server.pollname);
exit(PS_SYNTAX);
}
- if (ctl->server.protocol == P_RPOP && port >= 1024)
- {
- (void) fprintf(stderr,
- GT_("fetchmail: %s configuration invalid, RPOP requires a privileged port\n"),
- ctl->server.pollname);
- exit(PS_SYNTAX);
- }
}
if (ctl->listener == LMTP_MODE)
{
return(implicitmode);
}
-static RETSIGTYPE terminate_poll(int sig)
+static void terminate_poll(int sig)
/* to be executed at the end of a poll cycle */
{
#endif /* POP3_ENABLE */
}
-static RETSIGTYPE terminate_run(int sig)
+static void terminate_run(int sig)
/* to be executed on normal or signal-induced termination */
{
struct query *ctl;
if (ctl->password)
memset(ctl->password, '\0', strlen(ctl->password));
-#if !defined(HAVE_ATEXIT)
- fm_lock_release();
-#endif
-
if (activecount == 0)
exit(PS_NOMAIL);
else
#ifdef POP3_ENABLE
P_POP3,
#endif /* POP3_ENABLE */
-#ifdef POP2_ENABLE
- P_POP2
-#endif /* POP2_ENABLE */
};
static int query_host(struct query *ctl)
}
ctl->server.protocol = P_AUTO;
break;
- case P_POP2:
-#ifdef POP2_ENABLE
- st = doPOP2(ctl);
-#else
- report(stderr, GT_("POP2 support is not configured.\n"));
- st = PS_PROTOCOL;
-#endif /* POP2_ENABLE */
- break;
case P_POP3:
- case P_APOP:
- case P_RPOP:
#ifdef POP3_ENABLE
do {
st = doPOP3(ctl);
return(st);
}
+static int print_id_of(struct uid_db_record *rec, void *unused)
+{
+ (void)unused;
+
+ printf("\t%s\n", rec->id);
+ return 0;
+}
+
static void dump_params (struct runctl *runp,
struct query *querylist, flag implicit)
/* display query parameters in English */
printf(GT_("Logfile is %s\n"), runp->logfile);
if (strcmp(runp->idfile, IDFILE_NAME))
printf(GT_("Idfile is %s\n"), runp->idfile);
-#if defined(HAVE_SYSLOG)
if (runp->use_syslog)
printf(GT_("Progress messages will be logged via syslog\n"));
-#endif
if (runp->invisible)
printf(GT_("Fetchmail will masquerade and will not generate Received\n"));
if (runp->showdots)
printf(GT_(" Password will be prompted for.\n"));
else if (outlevel >= O_VERBOSE)
{
- if (ctl->server.protocol == P_APOP)
- printf(GT_(" APOP secret = \"%s\".\n"),
- visbuf(ctl->password));
- else if (ctl->server.protocol == P_RPOP)
- printf(GT_(" RPOP id = \"%s\".\n"),
- visbuf(ctl->password));
- else
- printf(GT_(" Password = \"%s\".\n"),
- visbuf(ctl->password));
+ printf(GT_(" Password = \"%s\".\n"),
+ visbuf(ctl->password));
}
}
if (ctl->server.protocol == P_POP3
&& ctl->server.service && !strcmp(ctl->server.service, KPOP_PORT)
- && (ctl->server.authenticate == A_KERBEROS_V4 ||
- ctl->server.authenticate == A_KERBEROS_V5))
+ && (ctl->server.authenticate == A_KERBEROS_V5))
printf(GT_(" Protocol is KPOP with Kerberos %s authentication"),
ctl->server.authenticate == A_KERBEROS_V5 ? "V" : "IV");
else
printf(GT_(" (using service %s)"), ctl->server.service);
else if (outlevel >= O_VERBOSE)
printf(GT_(" (using default port)"));
- if (ctl->server.uidl && MAILBOX_PROTOCOL(ctl))
- printf(GT_(" (forcing UIDL use)"));
putchar('.');
putchar('\n');
switch (ctl->server.authenticate)
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"));
break;
- case A_KERBEROS_V4:
- printf(GT_(" Kerberos V4 authentication will be forced.\n"));
- break;
case A_KERBEROS_V5:
printf(GT_(" Kerberos V5 authentication will be forced.\n"));
break;
case A_SSH:
printf(GT_(" End-to-end encryption assumed.\n"));
break;
+ case A_APOP:
+ printf(GT_(" APOP authentication will be forced.\n"));
+ break;
+ default:
+ abort();
}
if (ctl->server.principal != (char *) NULL)
printf(GT_(" Mail service principal is: %s\n"), ctl->server.principal);
else if (outlevel >= O_VERBOSE)
printf(GT_(" No plugout command specified.\n"));
- if (ctl->server.protocol > P_POP2 && MAILBOX_PROTOCOL(ctl))
+ if (MAILBOX_PROTOCOL(ctl))
{
- if (!ctl->oldsaved)
+ int count;
+
+ if (!(count = uid_db_n_records(&ctl->oldsaved)))
printf(GT_(" No UIDs saved from this host.\n"));
else
{
- struct idlist *idp;
- int count = 0;
-
- for (idp = ctl->oldsaved; idp; idp = idp->next)
- ++count;
-
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);
+ traverse_uid_db(&ctl->oldsaved, print_id_of, NULL);
}
}
break;
}
+ switch (ctl->server.retrieveerror) {
+ case RE_ABORT:
+ if (outlevel >= O_VERBOSE)
+ printf(GT_(" Messages with fetch body errors will cause the session to abort.\n"));
+ break;
+ case RE_CONTINUE:
+ printf(GT_(" Messages with fetch body errors will be skipped, the session will continue.\n"));
+ break;
+ case RE_MARKSEEN:
+ printf(GT_(" Messages with fetch body errors will be marked seen, the session will continue.\n"));
+ break;
+ }
+
if (ctl->properties)
printf(GT_(" Pass-through properties \"%s\".\n"),
visbuf(ctl->properties));