/* * fetchmail.c -- main driver module for fetchmail * * For license terms, see the file COPYING in this directory. */ #include "config.h" #include #if defined(STDC_HEADERS) #include #endif #if defined(HAVE_UNISTD_H) #include #endif #include #include #include #if defined(HAVE_SYSLOG) #include #endif #include #ifdef __FreeBSD__ #include #endif #include #include #include #include /* needed for Sun 4.1.2 */ #ifdef HAVE_SETRLIMIT #include #endif /* HAVE_SETRLIMIT */ #include #ifdef HAVE_NET_SOCKET_H #include #endif #ifdef HAVE_GETHOSTBYNAME #include #endif /* HAVE_GETHOSTBYNAME */ #ifdef HESIOD #include #endif #include "getopt.h" #include "fetchmail.h" #include "socket.h" #include "tunable.h" #include "smtp.h" #include "netrc.h" #include "i18n.h" #ifndef ENETUNREACH #define ENETUNREACH 128 /* Interactive doesn't know this */ #endif /* ENETUNREACH */ /* prototypes for internal functions */ static int load_params(int, char **, int); static void dump_params (struct runctl *runp, struct query *, flag implicit); static int query_host(struct query *); /* controls the detail level of status/progress messages written to stderr */ int outlevel; /* see the O_.* constants above */ /* miscellaneous global controls */ struct runctl run; /* global controls for this run */ flag nodetach; /* if TRUE, don't detach daemon process */ flag quitmode; /* if --quit was set */ flag check_only; /* if --probe was set */ flag versioninfo; /* emit only version info */ 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 */ flag configdump; /* dump control blocks for configurator */ const char *fetchmailhost; /* either `localhost' or the host's FQDN */ #if NET_SECURITY void *request = NULL; int requestlen = 0; #endif /* NET_SECURITY */ static char *lockfile; /* name of lockfile */ static int lock_acquired; /* have we acquired a lock */ static int querystatus; /* status of query */ static int successes; /* count number of successful polls */ 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); #ifdef HAVE_ON_EXIT static void unlockit(int n, void *p) #else static void unlockit(void) #endif /* must-do actions for exit (but we can't count on being able to do malloc) */ { if (lockfile && lock_acquired) unlink(lockfile); } #ifdef __FreeBSD__ /* drop SGID kmem privileage until we need it */ static void dropprivs(void) { struct group *gr; gid_t egid; gid_t rgid; egid = getegid(); rgid = getgid(); gr = getgrgid(egid); if (gr && !strcmp(gr->gr_name, "kmem")) { extern void interface_set_gids(gid_t egid, gid_t rgid); interface_set_gids(egid, rgid); setegid(rgid); } } #endif int main(int argc, char **argv) { int st, bkgd = FALSE; int parsestatus, implicitmode = FALSE; FILE *lockfp; struct query *ctl; netrc_entry *netrc_list; char *netrc_file, *tmpbuf; pid_t pid; int lastsig = 0; #ifdef __FreeBSD__ dropprivs(); #endif envquery(argc, argv); #ifdef ENABLE_NLS bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); #endif /* * Note: because we can't initialize reporting before we know whether * syslog is supposed to be on, this message will go to stdout and * be lost when running in background. */ if (outlevel >= O_VERBOSE) { int i; report(stdout, "fetchmail: invoked with"); for (i = 0; i < argc; i++) report(stdout, " %s", argv[i]); report(stdout, "\n"); } #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); outlevel = O_NORMAL; /* * We used to arrange for the lockfile to be removed on exit close * to where the lock was asserted. Now we need to do it here, because * we might have re-executed in background with an existing lockfile * as the result of a changed rcfile (see the code near the execvp(3) * call near the beginning of the polling loop for details). We want * to be sure the lockfile gets nuked on any error exit, basically. */ #ifdef HAVE_ATEXIT atexit(unlockit); #endif #ifdef HAVE_ON_EXIT on_exit(unlockit, (char *)NULL); #endif if ((parsestatus = parsecmdline(argc,argv, &cmd_run, &cmd_opts)) < 0) exit(PS_SYNTAX); if (versioninfo) { printf(_("This is fetchmail release %s"), VERSION); #ifdef POP2_ENABLE printf("+POP2"); #endif /* POP2_ENABLE */ #ifndef POP3_ENABLE printf("-POP3"); #endif /* POP3_ENABLE */ #ifndef IMAP_ENABLE printf("-IMAP"); #endif /* IMAP_ENABLE */ #ifdef GSSAPI printf("+IMAP-GSS"); #endif /* GSSAPI */ #ifdef RPA_ENABLE printf("+RPA"); #endif /* RPA_ENABLE */ #ifdef NTLM_ENABLE printf("+NTLM"); #endif /* NTLM_ENABLE */ #ifdef SDPS_ENABLE printf("+SDPS"); #endif /* SDPS_ENABLE */ #ifndef ETRN_ENABLE printf("-ETRN"); #endif /* ETRN_ENABLE */ #ifdef SSL_ENABLE printf("+SSL"); #endif #if OPIE_ENABLE printf("+OPIE"); #endif /* OPIE_ENABLE */ #if INET6_ENABLE printf("+INET6"); #endif /* INET6_ENABLE */ #if NET_SECURITY printf("+NETSEC"); #endif /* NET_SECURITY */ #ifdef HAVE_SOCKS printf("+SOCKS"); #endif /* HAVE_SOCKS */ #if ENABLE_NLS printf("+NLS"); #endif /* ENABLE_NLS */ putchar('\n'); fflush(stdout); /* this is an attempt to help remote debugging */ system("uname -a"); } /* avoid parsing the config file if all we're doing is killing a daemon */ if (!(quitmode && argc == 2)) implicitmode = load_params(argc, argv, optind); #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); } else #endif report_init((run.poll_interval == 0 || nodetach) && !run.logfile); /* set up to do lock protocol */ #define FETCHMAIL_PIDFILE "fetchmail.pid" if (!getuid()) { xalloca(tmpbuf, char *, sizeof(PID_DIR) + sizeof(FETCHMAIL_PIDFILE)); sprintf(tmpbuf, "%s/%s", PID_DIR, FETCHMAIL_PIDFILE); } else { xalloca(tmpbuf, char *, strlen(fmhome) + sizeof(FETCHMAIL_PIDFILE) + 2); strcpy(tmpbuf, fmhome); strcat(tmpbuf, "/"); if (fmhome == home) strcat(tmpbuf, "."); strcat(tmpbuf, FETCHMAIL_PIDFILE); } #undef FETCHMAIL_PIDFILE #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 * cracker. */ if (outlevel < O_VERBOSE || run.poll_interval > 0) { struct rlimit corelimit; corelimit.rlim_cur = 0; 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. */ xalloca(netrc_file, char *, strlen(home) + sizeof(NETRC_FILE) + 2); strcpy (netrc_file, home); strcat (netrc_file, "/"); strcat (netrc_file, NETRC_FILE); netrc_list = parse_netrc(netrc_file); #undef NETRC_FILE /* pick up passwords where we can */ for (ctl = querylist; ctl; ctl = ctl->next) { if (ctl->active && !(implicitmode && ctl->server.skip)&&!ctl->password) { if (ctl->server.preauthenticate == A_KERBEROS_V4 || ctl->server.preauthenticate == A_KERBEROS_V5 || ctl->server.preauthenticate == A_SSH || #ifdef GSSAPI ctl->server.protocol == P_IMAP_GSS || #endif /* GSSAPI */ ctl->server.protocol == P_IMAP_K4) /* Server won't care what the password is, but there must be some non-null string here. */ ctl->password = ctl->remotename; else { netrc_entry *p; /* look up the pollname and account in the .netrc file. */ p = search_netrc(netrc_list, ctl->server.pollname, ctl->remotename); /* if we find a matching entry with a password, use it */ if (p && p->password) ctl->password = xstrdup(p->password); /* otherwise try with "via" name if there is one */ else if (ctl->server.via) { p = search_netrc(netrc_list, ctl->server.via, ctl->remotename); if (p && p->password)
#!/usr/bin/env perl
#
# Make a fetchmail release.
# Dumps a release notice and diffs as a MIME multipart message 
# in RELEASE_NOTES
#
use POSIX qw(strftime);
$timezone = strftime('%z', localtime) || "-0500";
$tmp = $ENV{TMPDIR} || $ENV{TMP} || $ENV{TEMP} || "/tmp";

$project = "fetchmail";
$svnrepos = "https://decoy.wox.org/svn/$project";
$website = "http://developer.berlios.de/projects/$project";
$mailfrom = "<$project-devel-owner\@lists.berlios.de> (Fetchmail Development Team)";

# parse options
$diffs = 0;
$verbose = 0;
$null = ">/dev/null";
$errnull = "2>/dev/null";
while ($i = shift @ARGV)
{
	if ($i =~ /^(--diffs|-d)$/i)
	{
		$diffs = 1;
		next;
	}

	if ($i =~ /^(--verbose|-v)$/i)
	{
		$verbose = 1;
		$null = "";
		next;
	}

	die "Error: Unknown option: $i\n";
}

# extract version from source
$version=`grep 'AC_INIT' configure.ac`;
$version =~ /AC_INIT\([^,]*,\[?([0-9.rc-]+)\]?\)/;
$version = $1;
die "cannot determine version" unless defined $1;
$tag = "RELEASE_$version";
$tag =~ tr/./-/;

# extract existing tags
open(ID, "-|", "svn", "ls", $svnrepos . "/tags") || die "cannot run svn ls: $!\naborting";
while (<ID>) {
    if (m{^(RELEASE_.*)/}) {
	unshift(@versions, $1);
    }
}
close ID || die "svn ls  failed, aborting";

if ($versions[0] eq $tag) {
    $tag = $versions[0];
    $oldtag = $versions[1];
} else {
    $tag = '<workfile>';
    $oldtag = $versions[0];
}

$ENV{PATH} .= ":./dist-tools:./dist-tools/shipper:.";

print "Building $version release, tag $tag, previous tag $oldtag\n";

if (-d autom4te.cache) {
    system("rm -rf autom4te.cache")
	and die "Failure in removing autom4te.cache";
}

if (system("autoreconf -isv")) {
	die("Failure in regenerating autoconf files\n");
}

if (system("./configure && make clean && make -C po update-po && make clean")) {
	die("Failure in translation-file rebuild\n");
}

print "### Test-building the software...\n";
if (system("./configure && make clean && make distcheck")) {
	die("Compilation failure\n");
}

print "### Building the distribution...\n";
if (system("make dist $null")) {
	die("Distribution-build failure\n");
}

print "### Building the RPMs...\n";
if (system("buildrpms $project-${version}.tar.gz $null")) {
	die("RPM-build failure\n");
}

open(REPORT, ">$tmp/$project.PREAMBLE.$$");

print REPORT <<EOF;
From: $mailfrom
Subject: The $version release of $project is available

The $version release of $project is now available at the usual locations,
including <URL:$website>.

The source archive is available at:
<URL:$website/$project-${version}.tar.gz>

Here are the release notes:

EOF

# Extract the current notes
open(NEWS, "NEWS");
while (<NEWS>) {
    if (/^$project/) {
	print REPORT $_;
	last;
    }
}
while (<NEWS>) {
    if (/^$project/) {
	last;
    }
    print REPORT $_;
}

$oldver = $oldtag;
$oldver =~ tr/-/./;
$oldver =~ s/^RELEASE_//;

if ($diffs) {
	print REPORT "Diffs from the previous ($oldver) release follow as a MIME attachment."
} else {
        print REPORT "By popular demand, diffs from the previous release have been omitted."
}

close(NEWS);

close(REPORT);

if ($tag eq '<workfile>') {
    system("svn diff -r$oldtag        $errnull >$tmp/$project.DIFFS.$$");
} else {
    system("svn diff -r$oldtag -r$tag $errnull >$tmp/$project.DIFFS.$$");
}
print "Diff size:";
system("wc <$tmp/$project.DIFFS.$$");

if ($diffs) {
	system "metasend -b"
	    ." -D '$project-$tag announcement' -m 'text/plain' -e 7bit -f $tmp/$project.PREAMBLE.$$"
	    ." -n -D 'diff between $oldver and $version' -m 'text/plain' -e 7bit -f $tmp/$project.DIFFS.$$"
	    ." -o ANNOUNCE.EMAIL";
} else {
	rename("$tmp/$project.PREAMBLE.$$", "ANNOUNCE.EMAIL");
}
#system("chown esr ANNOUNCE.EMAIL");
#chmod(0700, "ANNOUNCE.EMAIL");

#unlink("$tmp/$project.PREAMBLE.$$");
unlink("$tmp/$project.DIFFS.$$");

print "Building index page...\n";
system("rm -f index.html; indexgen.sh");

if (-r "testsites") {
	print "Building test server list...\n";
	system("rm -f testservers.html; testservers-gen.sh >testservers.html");
}

print "Making activity graph...";
system "growthplot";

print "Done\n";

# makerelease ends here
(!versioninfo && (st = prc_filecheck(run.idfile, !versioninfo)) != 0) exit(st); else initialize_saved_lists(querylist, run.idfile); #endif /* POP3_ENABLE */ /* * If the user didn't set a last-resort user to get misaddressed * multidrop mail, set an appropriate default here. */ if (!run.postmaster) { if (getuid()) /* ordinary user */ run.postmaster = user; else /* root */ run.postmaster = "postmaster"; } return(implicitmode); } static void terminate_poll(int sig) /* to be executed at the end of a poll cycle */ { /* * Close all SMTP delivery sockets. For optimum performance * we'd like to hold them open til end of run, but (1) this * loses if our poll interval is longer than the MTA's inactivity * timeout, and (2) some MTAs (like smail) don't deliver after * each message, but rather queue up mail and wait to actually * deliver it until the input socket is closed. * * Sending SMTP QUIT on signal is theoretically nice, but led to a * subtle bug. If fetchmail was terminated by signal while it was * shipping message text, it would hang forever waiting for a * command acknowledge. In theory we could enable the QUIT * only outside of the message send. In practice, we don't * care. All mailservers hang up on a dropped TCP/IP connection * anyway. */ if (sig != 0) report(stdout, _("terminated with signal %d\n"), sig); else { struct query *ctl; /* terminate all SMTP connections cleanly */ for (ctl = querylist; ctl; ctl = ctl->next) if (ctl->smtp_socket != -1) { SMTP_quit(ctl->smtp_socket); SockClose(ctl->smtp_socket); ctl->smtp_socket = -1; } } #ifdef POP3_ENABLE /* * Update UID information at end of each poll, rather than at end * of run, because that way we don't lose all UIDL information since * the beginning of time if fetchmail crashes. */ if (!check_only) write_saved_lists(querylist, run.idfile); #endif /* POP3_ENABLE */ } static void terminate_run(int sig) /* to be executed on normal or signal-induced termination */ { struct query *ctl; terminate_poll(sig); /* * Craig Metz, the RFC1938 one-time-password guy, points out: * "Remember that most kernels don't zero pages before handing them to the * next process and many kernels share pages between user and kernel space. * You'd be very surprised what you can find from a short program to do a * malloc() and then dump the contents of the pages you got. By zeroing * the secrets at end of run (earlier if you can), you make sure the next * guy can't get the password/pass phrase." * * Right you are, Craig! */ for (ctl = querylist; ctl; ctl = ctl->next) if (ctl->password) memset(ctl->password, '\0', strlen(ctl->password)); #if !defined(HAVE_ATEXIT) && !defined(HAVE_ON_EXIT) unlockit(); #endif if (activecount == 0) exit(PS_NOMAIL); else exit(successes ? PS_SUCCESS : querystatus); } /* * Sequence of protocols to try when autoprobing, most capable to least. */ static const int autoprobe[] = { #ifdef IMAP_ENABLE P_IMAP, #endif /* IMAP_ENABLE */ #ifdef POP3_ENABLE P_POP3, #endif /* POP3_ENABLE */ #ifdef POP2_ENABLE P_POP2 #endif /* POP2_ENABLE */ }; static int query_host(struct query *ctl) /* perform fetch transaction with single host */ { int i, st; /* * 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)) { report(stdout, _("%s querying %s (protocol %s) at %s\n"), VERSION, ctl->server.pollname, showproto(ctl->server.protocol), rfc822timestamp()); } switch (ctl->server.protocol) { case P_AUTO: for (i = 0; i < sizeof(autoprobe)/sizeof(autoprobe[0]); i++) { ctl->server.protocol = autoprobe[i]; if ((st = query_host(ctl)) == PS_SUCCESS || st == PS_NOMAIL || st == PS_AUTHFAIL || st == PS_LOCKBUSY || st == PS_SMTP) break; } ctl->server.protocol = P_AUTO; return(st); case P_POP2: #ifdef POP2_ENABLE return(doPOP2(ctl)); #else report(stderr, _("POP2 support is not configured.\n")); return(PS_PROTOCOL); #endif /* POP2_ENABLE */ break; case P_POP3: case P_APOP: case P_RPOP: #ifdef POP3_ENABLE return(doPOP3(ctl)); #else report(stderr, _("POP3 support is not configured.\n")); return(PS_PROTOCOL); #endif /* POP3_ENABLE */ break; case P_IMAP: case P_IMAP_K4: case P_IMAP_CRAM_MD5: case P_IMAP_LOGIN: #ifdef GSSAPI case P_IMAP_GSS: #endif /* GSSAPI */ #ifdef IMAP_ENABLE return(doIMAP(ctl)); #else report(stderr, _("IMAP support is not configured.\n")); return(PS_PROTOCOL); #endif /* IMAP_ENABLE */ case P_ETRN: #ifndef ETRN_ENABLE report(stderr, _("ETRN support is not configured.\n")); return(PS_PROTOCOL); #else #ifdef HAVE_GETHOSTBYNAME return(doETRN(ctl)); #else report(stderr, _("Cannot support ETRN without gethostbyname(2).\n")); return(PS_PROTOCOL); #endif /* HAVE_GETHOSTBYNAME */ #endif /* ETRN_ENABLE */ default: report(stderr, _("unsupported protocol selected.\n")); return(PS_PROTOCOL); } } static void dump_params (struct runctl *runp, struct query *querylist, flag implicit) /* display query parameters in English */ { struct query *ctl; if (runp->poll_interval) printf(_("Poll interval is %d seconds\n"), runp->poll_interval); if (runp->logfile) printf(_("Logfile is %s\n"), runp->logfile); if (strcmp(runp->idfile, IDFILE_NAME)) printf(_("Idfile is %s\n"), runp->idfile); #if defined(HAVE_SYSLOG) if (runp->use_syslog) printf(_("Progress messages will be logged via syslog\n")); #endif if (runp->invisible) printf(_("Fetchmail will masquerade and will not generate Received\n")); if (runp->postmaster) printf(_("Fetchmail will forward misaddressed multidrop messages to %s.\n"), runp->postmaster); if (!runp->bouncemail) printf(_("Fetchmail will direct error mail to the postmaster.\n")); else if (outlevel >= O_VERBOSE) printf(_("Fetchmail will direct error mail to the sender.\n")); for (ctl = querylist; ctl; ctl = ctl->next) { if (!ctl->active || (implicit && ctl->server.skip)) continue; printf(_("Options for retrieving from %s@%s:\n"), ctl->remotename, visbuf(ctl->server.pollname)); if (ctl->server.via && (ctl->server.protocol != P_ETRN)) printf(_(" Mail will be retrieved via %s\n"), ctl->server.via); if (ctl->server.interval) printf(_(" Poll of this server will occur every %d intervals.\n"), ctl->server.interval); if (ctl->server.truename) printf(_(" True name of server is %s.\n"), ctl->server.truename); if (ctl->server.skip || outlevel >= O_VERBOSE) printf(_(" This host %s be queried when no host is specified.\n"), ctl->server.skip ? _("will not") : _("will")); /* * Don't poll for password when there is one or when using the ETRN * or IMAP-GSS protocol */ /* ETRN, IMAP_GSS, and IMAP_K4 do not need a password, so skip this */ if ( (ctl->server.protocol != P_ETRN) #ifdef GSSAPI && (ctl->server.protocol != P_IMAP_GSS) #endif /* GSSAPI */ && (ctl->server.protocol != P_IMAP_K4) ) { if (!ctl->password) printf(_(" Password will be prompted for.\n")); else if (outlevel >= O_VERBOSE) { if (ctl->server.protocol == P_APOP) printf(_(" APOP secret = \"%s\".\n"), visbuf(ctl->password)); else if (ctl->server.protocol == P_RPOP) printf(_(" RPOP id = \"%s\".\n"), visbuf(ctl->password)); else printf(_(" Password = \"%s\".\n"), visbuf(ctl->password)); } } if (ctl->server.protocol == P_POP3 #if INET6_ENABLE && ctl->server.service && !strcmp(ctl->server.service, KPOP_PORT) #else /* INET6_ENABLE */ && ctl->server.port == KPOP_PORT #endif /* INET6_ENABLE */ && (ctl->server.preauthenticate == A_KERBEROS_V4 || ctl->server.preauthenticate == A_KERBEROS_V5)) printf(_(" Protocol is KPOP with Kerberos %s authentication"), ctl->server.preauthenticate == A_KERBEROS_V5 ? "V" : "IV"); else printf(_(" Protocol is %s"), showproto(ctl->server.protocol)); #if INET6_ENABLE if (ctl->server.service) printf(_(" (using service %s)"), ctl->server.service); if (ctl->server.netsec) printf(_(" (using network security options %s)"), ctl->server.netsec); #else /* INET6_ENABLE */ if (ctl->server.port) printf(_(" (using port %d)"), ctl->server.port); #endif /* INET6_ENABLE */ else if (outlevel >= O_VERBOSE) printf(_(" (using default port)")); if (ctl->server.uidl && (ctl->server.protocol != P_ETRN)) printf(_(" (forcing UIDL use)")); putchar('.'); putchar('\n'); if (ctl->server.preauthenticate == A_KERBEROS_V4) printf(_(" Kerberos V4 preauthentication enabled.\n")); else if (ctl->server.preauthenticate == A_KERBEROS_V5) printf(_(" Kerberos V5 preauthentication enabled.\n")); else if (ctl->server.preauthenticate == A_SSH) printf(_(" End-to-end encryption assumed.\n")); #ifdef SSL_ENABLE if (ctl->use_ssl) printf(" SSL encrypted sessions enabled.\n"); #endif if (ctl->server.timeout > 0) printf(_(" Server nonresponse timeout is %d seconds"), ctl->server.timeout); if (ctl->server.timeout == CLIENT_TIMEOUT) printf(_(" (default).\n")); else printf(".\n"); if (ctl->server.protocol != P_ETRN) { if (!ctl->mailboxes->id) printf(_(" Default mailbox selected.\n")); else { struct idlist *idp; printf(_(" Selected mailboxes are:")); for (idp = ctl->mailboxes; idp; idp = idp->next) printf(" %s", idp->id); printf("\n"); } printf(_(" %s messages will be retrieved (--all %s).\n"), ctl->fetchall ? _("All") : _("Only new"), ctl->fetchall ? "on" : "off"); printf(_(" Fetched messages %s be kept on the server (--keep %s).\n"), ctl->keep ? _("will") : _("will not"), ctl->keep ? "on" : "off"); printf(_(" Old messages %s be flushed before message retrieval (--flush %s).\n"), ctl->flush ? _("will") : _("will not"), ctl->flush ? "on" : "off"); printf(_(" Rewrite of server-local addresses is %s (--norewrite %s).\n"), ctl->rewrite ? _("enabled") : _("disabled"), ctl->rewrite ? "off" : "on"); printf(_(" Carriage-return stripping is %s (stripcr %s).\n"), ctl->stripcr ? _("enabled") : _("disabled"), ctl->stripcr ? "on" : "off"); printf(_(" Carriage-return forcing is %s (forcecr %s).\n"), ctl->forcecr ? _("enabled") : _("disabled"), ctl->forcecr ? "on" : "off"); printf(_(" Interpretation of Content-Transfer-Encoding is %s (pass8bits %s).\n"), ctl->pass8bits ? _("disabled") : _("enabled"), ctl->pass8bits ? "on" : "off"); printf(_(" MIME decoding is %s (mimedecode %s).\n"), ctl->mimedecode ? _("enabled") : _("disabled"), ctl->mimedecode ? "on" : "off"); printf(_(" Idle after poll is %s (idle %s).\n"), ctl->idle ? _("enabled") : _("disabled"), ctl->idle ? "on" : "off"); printf(_(" Nonempty Status lines will be %s (dropstatus %s)\n"), ctl->dropstatus ? _("discarded") : _("kept"), ctl->dropstatus ? "on" : "off"); printf(_(" Delivered-To lines will be %s (dropdelivered %s)\n"), ctl->dropdelivered ? _("discarded") : _("kept"), ctl->dropdelivered ? "on" : "off"); if (NUM_NONZERO(ctl->limit)) { if (NUM_NONZERO(ctl->limit)) printf(_(" Message size limit is %d octets (--limit %d).\n"), ctl->limit, ctl->limit); else if (outlevel >= O_VERBOSE) printf(_(" No message size limit (--limit 0).\n")); if (run.poll_interval > 0) printf(_(" Message size warning interval is %d seconds (--warnings %d).\n"), ctl->warnings, ctl->warnings); else if (outlevel >= O_VERBOSE) printf(_(" Size warnings on every poll (--warnings 0).\n")); } if (NUM_NONZERO(ctl->fetchlimit)) printf(_(" Received-message limit is %d (--fetchlimit %d).\n"), ctl->fetchlimit, ctl->fetchlimit); else if (outlevel >= O_VERBOSE) printf(_(" No received-message limit (--fetchlimit 0).\n")); if (NUM_NONZERO(ctl->batchlimit)) printf(_(" SMTP message batch limit is %d.\n"), ctl->batchlimit); else if (outlevel >= O_VERBOSE) printf(_(" No SMTP message batch limit (--batchlimit 0).\n")); if (ctl->server.protocol != P_ETRN) { if (NUM_NONZERO(ctl->expunge)) printf(_(" Deletion interval between expunges forced to %d (--expunge %d).\n"), ctl->expunge, ctl->expunge); else if (outlevel >= O_VERBOSE) printf(_(" No forced expunges (--expunge 0).\n")); } } if (ctl->bsmtp) printf(_(" Messages will be appended to %s as BSMTP\n"), visbuf(ctl->bsmtp)); else if (ctl->mda && (ctl->server.protocol != P_ETRN)) printf(_(" Messages will be delivered with \"%s\".\n"), visbuf(ctl->mda)); else { struct idlist *idp; printf(_(" Messages will be %cMTP-forwarded to:"), ctl->listener); for (idp = ctl->smtphunt; idp; idp = idp->next) { printf(" %s", idp->id); if (!idp->val.status.mark) printf(_(" (default)")); } printf("\n"); if (ctl->smtpaddress) printf(_(" Host part of MAIL FROM line will be %s\n"), ctl->smtpaddress); } if (ctl->server.protocol != P_ETRN) { if (ctl->antispam != (struct idlist *)NULL) { struct idlist *idp; printf(_(" Recognized listener spam block responses are:")); for (idp = ctl->antispam; idp; idp = idp->next) printf(" %d", idp->val.status.num); printf("\n"); } else if (outlevel >= O_VERBOSE) printf(_(" Spam-blocking disabled\n")); } if (ctl->preconnect) printf(_(" Server connection will be brought up with \"%s\".\n"), visbuf(ctl->preconnect)); else if (outlevel >= O_VERBOSE) printf(_(" No pre-connection command.\n")); if (ctl->postconnect) printf(_(" Server connection will be taken down with \"%s\".\n"), visbuf(ctl->postconnect)); else if (outlevel >= O_VERBOSE) printf(_(" No post-connection command.\n")); if (ctl->server.protocol != P_ETRN) { if (!ctl->localnames) printf(_(" No localnames declared for this host.\n")); else { struct idlist *idp; int count = 0; for (idp = ctl->localnames; idp; idp = idp->next) ++count; if (count > 1 || ctl->wildcard) printf(_(" Multi-drop mode: ")); else printf(_(" Single-drop mode: ")); printf(_("%d local name(s) recognized.\n"), count); if (outlevel >= O_VERBOSE) { for (idp = ctl->localnames; idp; idp = idp->next) if (idp->val.id2) printf("\t%s -> %s\n", idp->id, idp->val.id2); else printf("\t%s\n", idp->id); if (ctl->wildcard) fputs("\t*\n", stdout); } if (count > 1 || ctl->wildcard) { printf(_(" DNS lookup for multidrop addresses is %s.\n"), ctl->server.dns ? _("enabled") : _("disabled")); if (ctl->server.dns) { printf(_(" Server aliases will be compared with multidrop addresses by ")); if (ctl->server.checkalias) printf(_("IP address.\n")); else printf(_("name.\n")); } if (ctl->server.envelope == STRING_DISABLED) printf(_(" Envelope-address routing is disabled\n")); else { printf(_(" Envelope header is assumed to be: %s\n"), ctl->server.envelope ? ctl->server.envelope:_("Received")); if (ctl->server.envskip > 1 || outlevel >= O_VERBOSE) printf(_(" Number of envelope header to be parsed: %d\n"), ctl->server.envskip); if (ctl->server.qvirtual) printf(_(" Prefix %s will be removed from user id\n"), ctl->server.qvirtual); else if (outlevel >= O_VERBOSE) printf(_(" No prefix stripping\n")); } if (ctl->server.akalist) { struct idlist *idp; printf(_(" 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(_(" Local domains:")); for (idp = ctl->server.localdomains; idp; idp = idp->next) printf(" %s", idp->id); putchar('\n'); } } } } #if defined(linux) || defined(__FreeBSD__) if (ctl->server.interface) printf(_(" Connection must be through interface %s.\n"), ctl->server.interface); else if (outlevel >= O_VERBOSE) printf(_(" No interface requirement specified.\n")); if (ctl->server.monitor) printf(_(" Polling loop will monitor %s.\n"), ctl->server.monitor); else if (outlevel >= O_VERBOSE) printf(_(" No monitor interface specified.\n")); #endif if (ctl->server.plugin) printf(_(" Server connections will be made via plugin %s (--plugin %s).\n"), ctl->server.plugin, ctl->server.plugin); else if (outlevel >= O_VERBOSE) printf(_(" No plugin command specified.\n")); if (ctl->server.plugout) printf(_(" Listener connections will be made via plugout %s (--plugout %s).\n"), ctl->server.plugout, ctl->server.plugout); else if (outlevel >= O_VERBOSE) printf(_(" No plugout command specified.\n")); if (ctl->server.protocol > P_POP2 && (ctl->server.protocol != P_ETRN)) { if (!ctl->oldsaved) printf(_(" No UIDs saved from this host.\n")); else { struct idlist *idp; int count = 0; for (idp = ctl->oldsaved; idp; idp = idp->next) ++count; printf(_(" %d UIDs saved.\n"), count); if (outlevel >= O_VERBOSE) for (idp = ctl->oldsaved; idp; idp = idp->next) printf("\t%s\n", idp->id); } } if (ctl->properties) printf(_(" Pass-through properties \"%s\".\n"), visbuf(ctl->properties)); } } /* fetchmail.c ends here */