#if defined(HAVE_UNISTD_H)
#include <unistd.h>
#endif
+#if defined(HAVE_ALLOCA_H)
+#include <alloca.h>
+#endif
#include <string.h>
#include <signal.h>
+#if defined(HAVE_SYSLOG)
+#include <syslog.h>
+#endif
#include <pwd.h>
+#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <netdb.h>
#endif /* HAVE_GETHOSTBYNAME */
+#ifdef SUNOS
+#include <stdlib.h>
+#endif
+
#include "fetchmail.h"
+#include "tunable.h"
#include "smtp.h"
#include "getopt.h"
+#include "netrc.h"
#define DROPDEAD 6 /* maximum bad socket opens */
int poll_interval; /* poll interval in seconds */
int nodetach; /* if TRUE, don't detach daemon process */
char *logfile; /* log file for daemon mode */
+int use_syslog; /* if --syslog was set */
int quitmode; /* if --quit was set */
int check_only; /* if --probe was set */
-int cmd_batchlimit; /* if --batchlimit was set */
+char *cmd_logfile; /* if --logfile was set */
+int cmd_daemon; /* if --daemon was set */
/* miscellaneous global controls */
char *rcfile; /* path name of rc file */
char *idfile; /* UID list file */
int versioninfo; /* emit only version info */
char *user; /* the name of the invoking user */
+char *fetchmailhost; /* the name of the host running fetchmail */
+char *program_name; /* the name to prefix error messages with */
static char *lockfile; /* name of lockfile */
static int querystatus; /* status of query */
RETSIGTYPE donothing(sig) int sig; {signal(sig, donothing); lastsig = sig;}
+#ifdef HAVE_ATEXIT
static void unlockit(void)
+#else /* use on_exit(), e.g. on SunOS */
+static void unlockit(int n, void *p)
+#endif
/* must-do actions for exit (but we can't count on being able to do malloc) */
{
unlink(lockfile);
struct passwd *pw;
struct query *ctl;
FILE *lockfp;
+ netrc_entry *netrc_list;
+ char *netrc_file;
pid_t pid;
+ if ((program_name = strrchr(argv[0], '/')) != NULL)
+ ++program_name;
+ else
+ program_name = argv[0];
+
if ((user = getenv("USER")) == (char *)NULL)
user = getenv("LOGNAME");
}
}
+ /* we'll need this for the SMTP forwarding target and error messages */
+ if (gethostname(tmpbuf, sizeof(tmpbuf)))
+ {
+ fprintf(stderr, "fetchmail: can't determine fetchmail's host!");
+ exit(PS_IOERR);
+ }
+ fetchmailhost = xstrdup(tmpbuf);
+
/*
* Backward-compatibility hack. If we're called by the name of the
* ancestral popclient, look for .poprc. This will actually work
if ((parsestatus = parsecmdline(argc,argv,&cmd_opts)) < 0)
exit(PS_SYNTAX);
+ /* this hint to stdio should help messages come out in the right order */
+ setvbuf(stdout, NULL, _IOLBF, POPBUFSIZE);
+
if (versioninfo)
- printf("This is fetchmail release %s pl %s\n", RELEASE_ID, PATCHLEVEL);
+ printf("This is fetchmail release %s\n", RELEASE_ID);
/* avoid parsing the config file if all we're doing is killing a daemon */
if (!quitmode)
implicitmode = load_params(argc, argv, optind);
/* set up to do lock protocol */
- if ((tmpdir = getenv("TMPDIR")) == (char *)NULL)
- tmpdir = "/tmp";
- strcpy(tmpbuf, tmpdir);
- strcat(tmpbuf, "/fetchmail-");
- strcat(tmpbuf, user);
+ if (!getuid())
+ strcpy(tmpbuf, "/var/run/fetchmail.pid");
+ else {
+ strcpy(tmpbuf, home);
+ strcat(tmpbuf, "/.fetchmail");
+ }
/* perhaps we just want to check options? */
if (versioninfo) {
printf(" and %s\n", rcfile);
if (outlevel == O_VERBOSE)
printf("Lockfile at %s\n", tmpbuf);
- if (batchlimit)
- printf("SMTP message batch limit is %d.\n", batchlimit);
- else
- printf("No SMTP message batch limit.\n");
for (ctl = querylist; ctl; ctl = ctl->next) {
- if (ctl->active && !(implicitmode && ctl->skip))
+ if (ctl->active && !(implicitmode && ctl->server.skip))
dump_params(ctl);
}
if (querylist == NULL)
(void) fprintf(stderr,
- "No mailservers set up -- perhaps %s is missing?\n",
- rcfile);
+ "No mailservers set up -- perhaps %s is missing?\n", rcfile);
exit(0);
}
else if (!quitmode && querylist == NULL) {
fprintf(stderr,"fetchmail: removing stale lockfile\n");
pid = -1;
bkgd = FALSE;
- remove(lockfile);
+ unlink(lockfile);
}
fclose(lockfp);
}
{
fprintf(stderr,"fetchmail: %s fetchmail at %d killed.\n",
bkgd ? "background" : "foreground", pid);
- remove(lockfile);
+ unlink(lockfile);
exit(0);
}
}
if (pid != -1)
{
if (check_only)
+ {
+ fprintf(stderr,
+ "fetchmail: can't check mail while another fetchmail to same host is running.\n");
return(PS_EXCLUDE);
+ }
else if (!implicitmode)
{
fprintf(stderr,
pid);
return(PS_EXCLUDE);
}
- else if (kill(pid, SIGHUP) == 0)
+ else if (kill(pid, SIGUSR1) == 0)
{
fprintf(stderr,
"fetchmail: background fetchmail at %d awakened.\n",
{
/*
* Should never happen -- possible only if a background fetchmail
- * croaks after the first kill probe above but before the SIGHUP
+ * croaks after the first kill probe above but before the SIGUSR1/SIGHUP
* transmission.
*/
fprintf(stderr,
}
}
+ /* parse the ~/.netrc file, for future password lookups. */
+ netrc_file = (char *) xmalloc (strlen (home) + 8);
+ strcpy (netrc_file, home);
+ strcat (netrc_file, "/.netrc");
+
+ netrc_list = parse_netrc (netrc_file);
+
/* pick up interactively any passwords we need but don't have */
for (ctl = querylist; ctl; ctl = ctl->next)
- if (ctl->active && !(implicitmode && ctl->skip) && !ctl->password[0])
+ if (ctl->active && !(implicitmode && ctl->server.skip) && !ctl->password)
{
- if (ctl->authenticate == A_KERBEROS)
- /* Server won't care what the password is, but there
- must be some non-null string here. */
- (void) strncpy(ctl->password,
- ctl->remotename, PASSWORDLEN-1);
+ if (ctl->server.authenticate == A_KERBEROS_V4)
+ /* Server won't care what the password is, but there
+ must be some non-null string here. */
+ ctl->password = ctl->remotename;
else
- {
+ {
+ /* Look up the host and account in the .netrc file. */
+ netrc_entry *p = search_netrc(netrc_list,ctl->server.names->id);
+ while (p && strcmp (p->account, ctl->remotename))
+ p = search_netrc (p->next, ctl->remotename);
+
+ if (p)
+ {
+ /* We found the entry, so use the password. */
+ ctl->password = xstrdup(p->password);
+ }
+ }
+
+ if (ctl->server.protocol != P_ETRN && !ctl->password)
+ {
(void) sprintf(tmpbuf, "Enter password for %s@%s: ",
- ctl->remotename, ctl->servername);
- (void) strncpy(ctl->password,
- (char *)getpassword(tmpbuf),PASSWORDLEN-1);
- }
+ ctl->remotename, ctl->server.names->id);
+ ctl->password = xstrdup((char *)getpassword(tmpbuf));
+ }
}
/*
* Maybe time to go to demon mode...
*/
- if (poll_interval && !nodetach)
- daemonize(logfile, termhook);
+#if defined(HAVE_SYSLOG)
+ if (use_syslog)
+ openlog(program_name, LOG_PID, LOG_MAIL);
+#endif
+
+ if (poll_interval)
+ {
+ if (!nodetach)
+ daemonize(logfile, termhook);
+ error( 0, 0, "starting fetchmail %s daemon ", RELEASE_ID);
+ }
/* beyond here we don't want more than one fetchmail running per user */
umask(0077);
* side effect of interrupting any sleep that may be going on,
* forcing fetchmail to re-poll its hosts.
*/
- signal(SIGHUP, donothing);
+ signal(SIGUSR1, donothing);
+
+ /* pacify people who think all system daemons wake up on SIGHUP */
+ if (poll_interval && !getuid())
+ signal(SIGHUP, donothing);
/* here's the exclusion lock */
if ( (lockfp = fopen(lockfile,"w")) != NULL ) {
if (poll_interval)
fprintf(lockfp," %d", poll_interval);
fclose(lockfp);
+
+#ifdef HAVE_ATEXIT
atexit(unlockit);
+#else
+ on_exit(unlockit, (char *)NULL);
+#endif
}
/*
batchcount = 0;
for (ctl = querylist; ctl; ctl = ctl->next)
{
- if (ctl->active && !(implicitmode && ctl->skip))
+ if (ctl->active && !(implicitmode && ctl->server.skip))
{
+#ifdef linux
+ /* interface_approve() does its own error logging */
+ if (!interface_approve(&ctl->server))
+ continue;
+#endif /* linux */
+
#ifdef HAVE_GETHOSTBYNAME
/*
* This functions partly as an optimization and partly
* as a probe to make sure our nameserver is still up.
* The multidrop case (especially) needs it.
*/
- if (ctl->authenticate == A_KERBEROS || MULTIDROP(ctl))
+ if (ctl->server.authenticate==A_KERBEROS_V4 || MULTIDROP(ctl))
{
struct hostent *namerec;
/* compute the canonical name of the host */
- namerec = gethostbyname(ctl->servername);
+ errno = 0;
+ namerec = gethostbyname(ctl->server.names->id);
if (namerec == (struct hostent *)NULL)
{
- fprintf(stderr,
- "fetchmail: skipping %s poll, nameserver isn't responding\n",
- ctl->servername);
+ error(0, errno,
+ "skipping %s poll, ",
+ ctl->server.names->id);
+ if (errno)
+ {
+ if (errno == ENETUNREACH)
+ break; /* go to sleep */
+ }
+#ifdef HAVE_HERROR /* NEXTSTEP doesn't */
+ else
+ herror("DNS error");
+#endif /* HAVE_HERROR */
continue;
}
else
{
- free(ctl->canonical_name);
- ctl->canonical_name = xstrdup((char *)namerec->h_name);
+ free(ctl->server.canonical_name);
+ ctl->server.canonical_name = xstrdup((char *)namerec->h_name);
}
}
#endif /* HAVE_GETHOSTBYNAME */
querystatus = query_host(ctl);
if (!check_only)
- update_uid_lists(ctl);
+ update_str_lists(ctl);
+#ifdef linux
+ if (ctl->server.monitor)
+ {
+ /* Allow some time for the link to quiesce. One
+ * second is usually sufficient, three is safe.
+ * Note: this delay is important - don't remove!
+ */
+ sleep(3);
+ interface_note_activity(&ctl->server);
+ }
+#endif
}
}
ctl->smtp_sockfp = (FILE *)NULL;
}
+ /*
+ * OK, we've polled. Now sleep.
+ */
if (poll_interval)
{
if (outlevel == O_VERBOSE)
setitimer(ITIMER_REAL,&ntimeout,NULL);
signal(SIGALRM, donothing);
pause();
- if (lastsig == SIGHUP)
- (void) fputs("fetchmail: awakened by SIGHUP\n", stderr);
+ signal(SIGALRM, SIG_IGN);
+ if (lastsig == SIGUSR1
+ || ((poll_interval && !getuid()) && lastsig == SIGHUP))
+ {
+#ifdef SYS_SIGLIST_DECLARED
+ error(0, 0, "awakened by %s", sys_siglist[lastsig]);
+#else
+ error(0, 0, "awakened by signal %d", lastsig);
+#endif
+ }
}
if (outlevel == O_VERBOSE)
memset(&def_opts, '\0', sizeof(struct query));
- def_opts.protocol = P_AUTO;
- def_opts.timeout = CLIENT_TIMEOUT;
- strcpy(def_opts.remotename, user);
- strcpy(def_opts.smtphost, "localhost");
+ def_opts.server.protocol = P_AUTO;
+ def_opts.server.timeout = CLIENT_TIMEOUT;
+ def_opts.remotename = user;
+ save_str(&def_opts.smtphunt, -1, fetchmailhost);
/* this builds the host list */
if (prc_parse_file(rcfile) != 0)
* record from command line and defaults
*/
for (ctl = querylist; ctl; ctl = ctl->next)
- if (strcmp(ctl->servername, argv[optind]) == 0)
+ if (str_in_list(&ctl->server.names, argv[optind]))
goto foundit;
ctl = hostalloc(&cmd_opts);
- strcpy(ctl->servername, argv[optind]);
+ save_str(&ctl->server.names, -1, argv[optind]);
foundit:
ctl->active = TRUE;
}
/* if there's a defaults record, merge it and lose it */
- if (querylist && strcmp(querylist->servername, "defaults") == 0)
+ if (querylist && strcmp(querylist->server.names->id, "defaults") == 0)
{
- for (ctl = querylist; ctl; ctl = ctl->next)
+ for (ctl = querylist->next; ctl; ctl = ctl->next)
optmerge(ctl, querylist);
querylist = querylist->next;
}
/* don't allow a defaults record after the first */
for (ctl = querylist; ctl; ctl = ctl->next)
- if (strcmp(ctl->servername, "defaults") == 0)
+ if (ctl != querylist && strcmp(ctl->server.names->id, "defaults") == 0)
exit(PS_SYNTAX);
/* merge in wired defaults, do sanity checks and prepare internal fields */
for (ctl = querylist; ctl; ctl = ctl->next)
{
- if (ctl->active && !(implicitmode && ctl->skip))
+ if (ctl->active && !(implicitmode && ctl->server.skip))
{
/* merge in defaults */
optmerge(ctl, &def_opts);
{
ctl->uid = pw->pw_uid; /* for local delivery via MDA */
if (!ctl->localnames) /* for local delivery via SMTP */
- save_uid(&ctl->localnames, -1, user);
+ save_str_pair(&ctl->localnames, user, NULL);
}
#if !defined(HAVE_GETHOSTBYNAME) || !defined(HAVE_RES_SEARCH)
}
#endif /* !HAVE_GETHOSTBYNAME || !HAVE_RES_SEARCH */
- /*
- * Assign SMTP leaders. We want to allow all query blocks
- * sharing the same SMTP host to use the same SMTP connection.
- * To accomplish this, we initialize each query block's leader
- * field to point to the first block in the list with a matching
- * SMTP host.
- *
- * In the typical case, there will be only one SMTP host (the
- * client machine) and thus just one SMTP leader (and one listener
- * process) through the entire poll cycle.
- */
- if (!ctl->mda[0])
- {
- ctl->smtp_sockfp = (FILE *)NULL;
- for (mp = querylist; mp && mp != ctl; mp = mp->next)
- if (strcmp(mp->smtphost, ctl->smtphost) == 0)
- {
- ctl->lead_smtp = mp->lead_smtp;
- goto no_new_leader;
- }
- ctl->lead_smtp = ctl;
- no_new_leader:;
- }
-
- /* similarly, compute server leaders for queries */
- ctl->aka = (struct idlist *)NULL;
+ /* compute server leaders for queries */
for (mp = querylist; mp && mp != ctl; mp = mp->next)
- if (strcmp(mp->servername, ctl->servername) == 0)
+ if (strcmp(mp->server.names->id, ctl->server.names->id) == 0)
{
- ctl->lead_server = mp->lead_server;
+ ctl->server.lead_server = mp->server.lead_server;
goto no_new_server;
}
- ctl->lead_server = ctl;
+ ctl->server.lead_server = &(ctl->server);
no_new_server:;
+ /* this code enables flags to be turned off */
+#define DEFAULT(flag, dflt) if (flag == FLAG_TRUE)\
+ flag = TRUE;\
+ else if (flag == FLAG_FALSE)\
+ flag = FALSE;\
+ else\
+ flag = (dflt)
+ DEFAULT(ctl->keep, FALSE);
+ DEFAULT(ctl->flush, FALSE);
+ DEFAULT(ctl->fetchall, FALSE);
+ DEFAULT(ctl->rewrite, TRUE);
+ DEFAULT(ctl->stripcr, (ctl->mda != (char *)NULL));
+ DEFAULT(ctl->forcecr, FALSE);
+ DEFAULT(ctl->server.dns, TRUE);
+ DEFAULT(ctl->server.uidl, FALSE);
+#undef DEFAULT
+
+ /* plug in the semi-standard way of indicating a mail address */
+ if (ctl->server.envelope == (char *)NULL)
+ ctl->server.envelope = "X-Envelope-To:";
+
/* sanity checks */
- if (ctl->port < 0)
+ if (ctl->server.port < 0)
{
(void) fprintf(stderr,
"%s configuration invalid, port number cannot be negative",
- ctl->servername);
+ ctl->server.names->id);
exit(PS_SYNTAX);
}
-
- /* expand MDA commands */
- if (!check_only && ctl->mda[0])
+ if (ctl->server.protocol == P_RPOP && ctl->server.port >= 1024)
{
- char *argp;
-
- /* punch nulls into the delimiting whitespace in the args */
- for (argp = ctl->mda, ctl->mda_argcount = 1; *argp != '\0'; ctl->mda_argcount++)
- {
- ctl->mda_argv[ctl->mda_argcount] = argp;
- while (!(*argp == '\0' || isspace(*argp)))
- argp++;
- if (*argp != '\0')
- *(argp++) = '\0';
- }
-
- ctl->mda_argv[ctl->mda_argcount] = (char *)NULL;
-
- ctl->mda_argv[0] = ctl->mda_argv[1];
- if ((argp = strrchr(ctl->mda_argv[1], '/')) != (char *)NULL)
- ctl->mda_argv[1] = argp + 1 ;
+ (void) fprintf(stderr,
+ "%s configuration invalid, RPOP requires a privileged port",
+ ctl->server.names->id);
+ exit(PS_SYNTAX);
}
}
}
else
initialize_saved_lists(querylist, idfile);
- /* if cmd_batchlimit was explicitly set, use it to override batchlimit */
- if (cmd_batchlimit > -1)
- batchlimit = cmd_batchlimit;
+ /* if cmd_logfile was explicitly set, use it to override logfile */
+ if (cmd_logfile)
+ logfile = cmd_logfile;
+
+ /* likewise for poll_interval */
+ if (cmd_daemon >= 0)
+ poll_interval = cmd_daemon;
+
+ /* check and daemon options are not compatible */
+ if (check_only && poll_interval)
+ poll_interval = 0;
return(implicitmode);
}
{
struct query *ctl;
- if (sig != 0)
- fprintf(stderr, "terminated with signal %d\n", sig);
+ /*
+ * 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 disable 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.
+ */
- /* terminate all SMTP connections cleanly */
- for (ctl = querylist; ctl; ctl = ctl->next)
- if (ctl->lead_smtp == ctl && ctl->smtp_sockfp != (FILE *)NULL)
- SMTP_quit(ctl->smtp_sockfp);
+ if (sig != 0)
+ error(0, 0, "terminated with signal %d", sig);
+ else
+ /* terminate all SMTP connections cleanly */
+ for (ctl = querylist; ctl; ctl = ctl->next)
+ if (ctl->smtp_sockfp != (FILE *)NULL)
+ SMTP_quit(ctl->smtp_sockfp);
if (!check_only)
write_saved_lists(querylist, idfile);
case P_POP3: return("POP3"); break;
case P_IMAP: return("IMAP"); break;
case P_APOP: return("APOP"); break;
+ case P_RPOP: return("RPOP"); break;
+ case P_ETRN: return("ETRN"); break;
default: return("unknown?!?"); break;
}
}
time_t now;
time(&now);
- fprintf(stderr, "Querying %s (protocol %s) at %s",
- ctl->servername, showproto(ctl->protocol), ctime(&now));
+ fprintf(stderr, "fetchmail: %s querying %s (protocol %s) at %s",
+ RELEASE_ID,
+ ctl->server.names->id, showproto(ctl->server.protocol), ctime(&now));
}
- switch (ctl->protocol) {
+ switch (ctl->server.protocol) {
case P_AUTO:
for (i = 0; i < sizeof(autoprobe)/sizeof(autoprobe[0]); i++)
{
- ctl->protocol = autoprobe[i];
+ ctl->server.protocol = autoprobe[i];
if ((st = query_host(ctl)) == PS_SUCCESS || st == PS_NOMAIL || st == PS_AUTHFAIL)
break;
}
- ctl->protocol = P_AUTO;
+ ctl->server.protocol = P_AUTO;
return(st);
break;
case P_POP2:
break;
case P_POP3:
case P_APOP:
+ case P_RPOP:
return(doPOP3(ctl));
break;
case P_IMAP:
return(doIMAP(ctl));
break;
+ case P_ETRN:
+ return(doETRN(ctl));
default:
- fprintf(stderr,"fetchmail: unsupported protocol selected.\n");
+ error(0, 0, "unsupported protocol selected.");
return(PS_PROTOCOL);
}
}
/* display query parameters in English */
{
printf("Options for retrieving from %s@%s:\n",
- ctl->remotename, visbuf(ctl->servername));
+ ctl->remotename, visbuf(ctl->server.names->id));
+
+ if (logfile)
+ printf(" Logfile is %s\n", logfile);
+ if (poll_interval)
+ printf(" Poll interval is %d seconds\n", poll_interval);
#ifdef HAVE_GETHOSTBYNAME
- if (ctl->canonical_name)
- printf(" Canonical DNS name of server is %s.\n", ctl->canonical_name);
+ if (ctl->server.canonical_name)
+ printf(" Canonical DNS name of server is %s.\n", ctl->server.canonical_name);
#endif /* HAVE_GETHOSTBYNAME */
- if (ctl->skip || outlevel == O_VERBOSE)
+ if (ctl->server.names->next)
+ {
+ struct idlist *idp;
+
+ printf(" Predeclared mailserver aliases:");
+ for (idp = ctl->server.names->next; idp; idp = idp->next)
+ printf(" %s", idp->id);
+ putchar('\n');
+ }
+ if (ctl->server.skip || outlevel == O_VERBOSE)
printf(" This host will%s be queried when no host is specified.\n",
- ctl->skip ? " not" : "");
- if (ctl->password[0] == '\0')
+ ctl->server.skip ? " not" : "");
+ if (!ctl->password)
printf(" Password will be prompted for.\n");
else if (outlevel == O_VERBOSE)
- if (ctl->protocol == P_APOP)
+ 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->protocol == P_POP3
- && ctl->port == KPOP_PORT
- && ctl->authenticate == A_KERBEROS)
+ if (ctl->server.protocol == P_POP3
+ && ctl->server.port == KPOP_PORT
+ && ctl->server.authenticate == A_KERBEROS_V4)
printf(" Protocol is KPOP");
else
- printf(" Protocol is %s", showproto(ctl->protocol));
- if (ctl->port)
- printf(" (using port %d)", ctl->port);
+ printf(" Protocol is %s", showproto(ctl->server.protocol));
+ if (ctl->server.port)
+ printf(" (using port %d)", ctl->server.port);
else if (outlevel == O_VERBOSE)
printf(" (using default port)");
+ if (ctl->server.uidl)
+ printf(" (forcing UIDL use)");
putchar('.');
putchar('\n');
- if (ctl->authenticate == A_KERBEROS)
- printf(" Kerberos authentication enabled.\n");
- printf(" Server nonresponse timeout is %d seconds", ctl->timeout);
- if (ctl->timeout == CLIENT_TIMEOUT)
+ if (ctl->server.authenticate == A_KERBEROS_V4)
+ printf(" Kerberos V4 preauthentication enabled.\n");
+ 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.localdomains)
+ {
+ struct idlist *idp;
+
+ printf(" Local domains:");
+ for (idp = ctl->server.localdomains; idp; idp = idp->next)
+ printf(" %s", idp->id);
+ putchar('\n');
+ }
printf(" %s messages will be retrieved (--all %s).\n",
ctl->fetchall ? "All" : "Only new",
ctl->flush ? "" : " not",
ctl->flush ? "on" : "off");
printf(" Rewrite of server-local addresses is %sabled (--norewrite %s).\n",
- ctl->norewrite ? "dis" : "en",
- ctl->norewrite ? "on" : "off");
+ ctl->rewrite ? "en" : "dis",
+ ctl->rewrite ? "off" : "on");
+ printf(" Carriage-return stripping is %sabled (--stripcr %s).\n",
+ ctl->stripcr ? "en" : "dis",
+ ctl->stripcr ? "on" : "off");
+ printf(" Carriage-return forcing is %sabled (--forcecr %s).\n",
+ ctl->forcecr ? "en" : "dis",
+ ctl->forcecr ? "on" : "off");
if (ctl->limit)
- printf(" Message size limit is %d bytes\n", ctl->limit);
+ printf(" Message size limit is %d bytes (--limit %d).\n",
+ ctl->limit, ctl->limit);
+ else if (outlevel == O_VERBOSE)
+ printf(" No message size limit (--limit 0).\n");
+ if (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 (ctl->batchlimit)
+ printf(" SMTP message batch limit is %d.\n", ctl->batchlimit);
else if (outlevel == O_VERBOSE)
- printf(" No message size limit\n");
- if (ctl->mda[0])
+ printf(" No SMTP message batch limit.\n");
+ if (ctl->mda)
+ printf(" Messages will be delivered with '%s.'\n", visbuf(ctl->mda));
+ else
{
- char **cp;
+ struct idlist *idp;
- printf(" Messages will be delivered with %s, args:",
- visbuf(ctl->mda_argv[0]));
- for (cp = ctl->mda_argv+1; *cp; cp++)
- printf(" %s", visbuf(*cp));
- putchar('\n');
+ printf(" Messages will be SMTP-forwarded to:");
+ for (idp = ctl->smtphunt; idp; idp = idp->next)
+ printf(" %s", idp->id);
+ printf("\n");
}
- else
- printf(" Messages will be SMTP-forwarded to '%s'.\n",
- visbuf(ctl->smtphost));
+ if (ctl->preconnect)
+ printf(" Server connection will be preinitialized with '%s.'\n", visbuf(ctl->preconnect));
+ else if (outlevel == O_VERBOSE)
+ printf(" No preinitialization command.\n");
if (!ctl->localnames)
printf(" No localnames declared for this host.\n");
else
count,
(count == 1 && !strcmp(ctl->localnames->id, user)) ? " (by default)" : "");
if (outlevel == O_VERBOSE)
+ {
for (idp = ctl->localnames; idp; idp = idp->next)
if (idp->val.id2)
- fprintf(stderr, "\t%s -> %s\n", idp->id, idp->val.id2);
+ printf("\t%s -> %s\n", idp->id, idp->val.id2);
else
- fprintf(stderr, "\t%s\n", idp->id);
+ printf("\t%s\n", idp->id);
+ if (ctl->wildcard)
+ fputs("*\n", stdout);
+ }
+
+ printf(" DNS lookup for multidrop addresses is %sabled.\n",
+ ctl->server.dns ? "en" : "dis",
+ ctl->server.dns ? "off" : "on");
+
+ if (count > 1)
+ 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);
}
+#ifdef linux
+ 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->protocol > P_POP2)
+ if (ctl->server.protocol > P_POP2)
if (!ctl->oldsaved)
printf(" No UIDs saved from this host.\n");
else
printf(" %d UIDs saved.\n", count);
if (outlevel == O_VERBOSE)
for (idp = ctl->oldsaved; idp; idp = idp->next)
- fprintf(stderr, "\t%s %s\n", ctl->servername, idp->id);
- }
-}
-
-int openmailpipe (char **argv)
-/* open a one-way pipe to a mail delivery agent */
-{
- int pipefd [2];
- int childpid;
-
- if (outlevel == O_VERBOSE)
- {
- char **cp;
-
- printf("fetchmail: about to deliver via MDA %s, args:",
- visbuf(argv[0]));
- for (cp = argv+1; *cp; cp++)
- printf(" %s", visbuf(*cp));
- putchar('\n');
- }
-
- if (pipe(pipefd) < 0) {
- perror("fetchmail: openmailpipe: pipe");
- return(-1);
- }
- if ((childpid = fork()) < 0) {
- perror("fetchmail: openmailpipe: fork");
- return(-1);
- }
- else if (childpid == 0) {
-
- /* in child process space */
- close(pipefd[1]); /* close the 'write' end of the pipe */
- close(0); /* get rid of inherited stdin */
- if (dup(pipefd[0]) != 0) {
- fputs("fetchmail: openmailpipe: dup() failed\n",stderr);
- exit(1);
+ fprintf(stderr, "\t%s\n", idp->id);
}
-
- execv(argv[0], argv + 1);
-
- /* if we got here, an error occurred */
- perror("fetchmail: openmailpipe: exec");
- _exit(PS_SYNTAX);
-
- }
-
- /* in the parent process space */
- close(pipefd[0]); /* close the 'read' end of the pipe */
- return(pipefd[1]);
-}
-
-int closemailpipe (fd)
-/* close the pipe to the mail delivery agent */
-int fd;
-{
- int err, status;
- int childpid;
-
- if ((err = close(fd)) != 0)
- perror("fetchmail: closemailpipe: close failed");
-
- childpid = wait(&status);
-
-#if defined(WIFEXITED) && defined(WEXITSTATUS)
- /*
- * Try to pass up an error if the MDA returned nonzero status,
- * on the assumption that this means it was reporting failure.
- */
- if (WIFEXITED(status) == 0 && WEXITSTATUS(status) != 0)
- {
- perror("fetchmail: MDA exited abnormally or returned nonzero status");
- err = -1;
- }
-#endif
-
- return(err);
}
/* helper functions for string interpretation and display */
-#define CTRL(x) ((x) & 0x1f)
-
void escapes(cp, tp)
/* process standard C-style escape sequences in a string */
const char *cp; /* source string with escapes */
}
cp++;
}
- else if (*cp == '^') /* expand control-character syntax */
- {
- cval = CTRL(*++cp);
- cp++;
- }
else
cval = *cp++;
*tp++ = cval;