From b0bbdc4481b82f0a45a7b0d930fb57ce21319602 Mon Sep 17 00:00:00 2001
From: "Eric S. Raymond" <esr@thyrsus.com>
Date: Tue, 29 Oct 1996 19:36:30 +0000
Subject: Modularize the main logic a bit.

svn path=/trunk/; revision=424
---
 fetchmail.c | 401 +++++++++++++++++++++++++++++++-----------------------------
 1 file changed, 207 insertions(+), 194 deletions(-)

diff --git a/fetchmail.c b/fetchmail.c
index c834db6a..b8a8044f 100644
--- a/fetchmail.c
+++ b/fetchmail.c
@@ -40,6 +40,7 @@
 
 #ifdef HAVE_PROTOTYPES
 /* prototypes for internal functions */
+static void load_params(int, char **, int);
 static void dump_params (struct query *);
 static int query_host(struct query *);
 static char *visbuf(const char *);
@@ -73,15 +74,13 @@ int argc;
 char **argv;
 { 
     int st, lossage, bkgd = FALSE;
-    struct query def_opts, *ctl, *mp;
     int parsestatus, implicitmode;
     char *home, *tmpdir, tmpbuf[BUFSIZ]; 
     struct passwd *pw;
+    struct query *ctl;
     FILE	*lockfp;
     pid_t pid;
 
-    memset(&def_opts, '\0', sizeof(struct query));
-
     if ((user = getenv("USER")) == (char *)NULL)
         user = getenv("LOGNAME");
 
@@ -99,11 +98,6 @@ char **argv;
 	}
     }
 
-    def_opts.protocol = P_AUTO;
-    def_opts.timeout = CLIENT_TIMEOUT;
-    strcpy(def_opts.remotename, user);
-    strcpy(def_opts.smtphost, "localhost");
-
     /*
      * Backward-compatibility hack.  If we're called by the name of the
      * ancestral popclient, look for .poprc.  This will actually work 
@@ -133,165 +127,7 @@ char **argv;
     if (versioninfo)
 	printf("This is fetchmail release %s pl %s\n", RELEASE_ID, PATCHLEVEL);
 
-    /* this builds the host list */
-    if (prc_parse_file(rcfile) != 0)
-	exit(PS_SYNTAX);
-
-    if ((implicitmode = (optind >= argc)))
-    {
-	for (ctl = querylist; ctl; ctl = ctl->next)
-	    ctl->active = TRUE;
-    }
-    else
-	for (; optind < argc; optind++) 
-	{
-	    /*
-	     * If hostname corresponds to a host known from the rc file,
-	     * simply declare it active.  Otherwise synthesize a host
-	     * record from command line and defaults
-	     */
-	    for (ctl = querylist; ctl; ctl = ctl->next)
-		if (strcmp(ctl->servername, argv[optind]) == 0)
-		    goto foundit;
-
-	    ctl = hostalloc(&cmd_opts);
-	    strcpy(ctl->servername, argv[optind]);
-
-	foundit:
-	    ctl->active = TRUE;
-	}
-
-    /* if there's a defaults record, merge it and lose it */ 
-    if (querylist && strcmp(querylist->servername, "defaults") == 0)
-    {
-	for (ctl = querylist; 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)
-	    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))
-	{
-#ifdef HAVE_GETHOSTBYNAME
-	    struct hostent	*namerec;
-#endif /* HAVE_GETHOSTBYNAME */
-
-	    /* merge in defaults */
-	    optmerge(ctl, &def_opts);
-
-	    /* keep lusers from shooting themselves in the foot :-) */
-	    if (poll_interval && ctl->limit)
-	    {
-		fprintf(stderr,"fetchmail: you'd never see large messages!\n");
-		exit(PS_SYNTAX);
-	    }
-
-	    /* check that delivery is going to a real local user */
-	    if ((pw = getpwnam(user)) == (struct passwd *)NULL)
-	    {
-		fprintf(stderr,
-			"fetchmail: can't default delivery to %s\n", user);
-		exit(PS_SYNTAX);	/* has to be from bad rc file */
-	    }
-	    else
-		ctl->uid = pw->pw_uid;
-
-#ifdef HAVE_GETHOSTBYNAME
-	    /*
-	     * Don't do DNS lookup unless we need to because we're going
-	     * to use Kerberos or process a multidrop box.  Some sites
-	     * won't have DNS up at fetchmail initialization time but aren't
-	     * using these features -- avoid hosing them unnecessarily.
-	     */
-	    if (ctl->authenticate == A_KERBEROS || MULTIDROP(ctl))
-	    {
-		/* compute the canonical name of the host */
-		namerec = gethostbyname(ctl->servername);
-		if (namerec == (struct hostent *)NULL)
-		{
-		    fprintf(stderr,
-			    "fetchmail: can't get canonical name of host %s\n",
-			    ctl->servername);
-		    exit(PS_SYNTAX);
-		}
-		else
-		    ctl->canonical_name = xstrdup((char *)namerec->h_name);
-	    }
-#else
-	    /* can't handle multidrop mailboxes unless we can do DNS lookups */
-	    if (ctl->localnames && ctl->localnames->next)
-	    {
-		fputs("fetchmail: can't handle multidrop mailboxes without DNS\n",
-			stderr);
-		exit(PS_SYNTAX);
-	    }
-#endif /* HAVE_GETHOSTBYNAME */
-
-	    /*
-	     * 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 run.
-	     */
-	    if (!ctl->mda[0])
-	    {
-		for (mp = querylist; mp && mp != ctl; mp = mp->next)
-		    if (strcmp(mp->smtphost, ctl->smtphost) == 0)
-		    {
-			ctl->leader = mp->leader;
-			goto no_new_leader;
-		    }
-		ctl->leader = ctl;
-		ctl->smtp_socket = -1;
-	    no_new_leader:;
-	    }
-
-	    /* sanity checks */
-	    if (ctl->port < 0)
-	    {
-		(void) fprintf(stderr,
-			       "%s configuration invalid, port number cannot be negative",
-			       ctl->servername);
-		exit(PS_SYNTAX);
-	    }
-
-	    /* expand MDA commands */
-	    if (!check_only && ctl->mda[0])
-	    {
-		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 ;
-	    }
-	}
-    }
-
-    
+    load_params(argc, argv, optind);
 
     /* set up to do lock protocol */
     if ((tmpdir = getenv("TMPDIR")) == (char *)NULL)
@@ -513,40 +349,42 @@ char **argv;
 	endhostent();		/* release TCP/IP connection to nameserver */
 #endif /* HAVE_GETHOSTBYNAME */
 
-	if (outlevel == O_VERBOSE)
+	if (poll_interval)
 	{
-	    time_t	now;
+	    if (outlevel == O_VERBOSE)
+	    {
+		time_t	now;
 
-	    time(&now);
-	    fprintf(stderr, "fetchmail: sleeping at %s", ctime(&now));
-	}
+		time(&now);
+		fprintf(stderr, "fetchmail: sleeping at %s", ctime(&now));
+	    }
 
-	/*
-	 * We can't use sleep(3) here, the alarm(2) call used to
-	 * implement server nonresponse timeout collides with it.
-	 * We'll just assume setitimer(2) is available since fetchmail
-	 * has to have the socket layer to work at all.
-	 */
-	{
-	    struct itimerval ntimeout;
+	    /*
+	     * We can't use sleep(3) here, the alarm(2) call used to
+	     * implement server nonresponse timeout collides with it.
+	     * We'll just assume setitimer(2) is available since fetchmail
+	     * has to have the socket layer to work at all.
+	     */
+	    {
+		struct itimerval ntimeout;
 
-	    ntimeout.it_interval.tv_sec = ntimeout.it_interval.tv_sec = 0;
-	    ntimeout.it_value.tv_sec  = poll_interval;
-	    ntimeout.it_value.tv_usec = 0;
+		ntimeout.it_interval.tv_sec = ntimeout.it_interval.tv_sec = 0;
+		ntimeout.it_value.tv_sec  = poll_interval;
+		ntimeout.it_value.tv_usec = 0;
 
-	    if (setitimer(ITIMER_REAL,&ntimeout,(struct itimerval *)NULL)==-1
-			&& errno == EINTR)
-		(void) fputs("fetchmail: awakened by SIGHUP\n", stderr);
-	    signal(SIGALRM, donothing);
-	    pause();
-	}
+		if (setitimer(ITIMER_REAL,&ntimeout,NULL)==-1 && errno==EINTR)
+		    (void) fputs("fetchmail: awakened by SIGHUP\n", stderr);
+		signal(SIGALRM, donothing);
+		pause();
+	    }
 
-	if (outlevel == O_VERBOSE)
-	{
-	    time_t	now;
+	    if (outlevel == O_VERBOSE)
+	    {
+		time_t	now;
 
-	    time(&now);
-	    fprintf(stderr, "fetchmail: awakened at %s", ctime(&now));
+		time(&now);
+		fprintf(stderr, "fetchmail: awakened at %s", ctime(&now));
+	    }
 	}
     } while
 	(poll_interval);
@@ -558,6 +396,181 @@ char **argv;
     exit(popstatus);
 }
 
+static void load_params(argc, argv, optind)
+int	argc;
+char	**argv;
+int	optind;
+{
+    int	implicitmode;
+    struct passwd *pw;
+    struct query def_opts, *ctl, *mp;
+
+    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");
+
+    /* this builds the host list */
+    if (prc_parse_file(rcfile) != 0)
+	exit(PS_SYNTAX);
+
+    if ((implicitmode = (optind >= argc)))
+    {
+	for (ctl = querylist; ctl; ctl = ctl->next)
+	    ctl->active = TRUE;
+    }
+    else
+	for (; optind < argc; optind++) 
+	{
+	    /*
+	     * If hostname corresponds to a host known from the rc file,
+	     * simply declare it active.  Otherwise synthesize a host
+	     * record from command line and defaults
+	     */
+	    for (ctl = querylist; ctl; ctl = ctl->next)
+		if (strcmp(ctl->servername, argv[optind]) == 0)
+		    goto foundit;
+
+	    ctl = hostalloc(&cmd_opts);
+	    strcpy(ctl->servername, argv[optind]);
+
+	foundit:
+	    ctl->active = TRUE;
+	}
+
+    /* if there's a defaults record, merge it and lose it */ 
+    if (querylist && strcmp(querylist->servername, "defaults") == 0)
+    {
+	for (ctl = querylist; 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)
+	    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))
+	{
+#ifdef HAVE_GETHOSTBYNAME
+	    struct hostent	*namerec;
+#endif /* HAVE_GETHOSTBYNAME */
+
+	    /* merge in defaults */
+	    optmerge(ctl, &def_opts);
+
+	    /* keep lusers from shooting themselves in the foot :-) */
+	    if (poll_interval && ctl->limit)
+	    {
+		fprintf(stderr,"fetchmail: you'd never see large messages!\n");
+		exit(PS_SYNTAX);
+	    }
+
+	    /* check that delivery is going to a real local user */
+	    if ((pw = getpwnam(user)) == (struct passwd *)NULL)
+	    {
+		fprintf(stderr,
+			"fetchmail: can't default delivery to %s\n", user);
+		exit(PS_SYNTAX);	/* has to be from bad rc file */
+	    }
+	    else
+		ctl->uid = pw->pw_uid;
+
+#ifdef HAVE_GETHOSTBYNAME
+	    /*
+	     * Don't do DNS lookup unless we need to because we're going
+	     * to use Kerberos or process a multidrop box.  Some sites
+	     * won't have DNS up at fetchmail initialization time but aren't
+	     * using these features -- avoid hosing them unnecessarily.
+	     */
+	    if (ctl->authenticate == A_KERBEROS || MULTIDROP(ctl))
+	    {
+		/* compute the canonical name of the host */
+		namerec = gethostbyname(ctl->servername);
+		if (namerec == (struct hostent *)NULL)
+		{
+		    fprintf(stderr,
+			    "fetchmail: can't get canonical name of host %s\n",
+			    ctl->servername);
+		    exit(PS_SYNTAX);
+		}
+		else
+		    ctl->canonical_name = xstrdup((char *)namerec->h_name);
+	    }
+#else
+	    /* can't handle multidrop mailboxes unless we can do DNS lookups */
+	    if (ctl->localnames && ctl->localnames->next)
+	    {
+		fputs("fetchmail: can't handle multidrop mailboxes without DNS\n",
+			stderr);
+		exit(PS_SYNTAX);
+	    }
+#endif /* HAVE_GETHOSTBYNAME */
+
+	    /*
+	     * 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 run.
+	     */
+	    if (!ctl->mda[0])
+	    {
+		for (mp = querylist; mp && mp != ctl; mp = mp->next)
+		    if (strcmp(mp->smtphost, ctl->smtphost) == 0)
+		    {
+			ctl->leader = mp->leader;
+			goto no_new_leader;
+		    }
+		ctl->leader = ctl;
+		ctl->smtp_socket = -1;
+	    no_new_leader:;
+	    }
+
+	    /* sanity checks */
+	    if (ctl->port < 0)
+	    {
+		(void) fprintf(stderr,
+			       "%s configuration invalid, port number cannot be negative",
+			       ctl->servername);
+		exit(PS_SYNTAX);
+	    }
+
+	    /* expand MDA commands */
+	    if (!check_only && ctl->mda[0])
+	    {
+		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 termhook(int sig)
 /* to be executed on normal or signal-induced termination */
 {
-- 
cgit v1.2.3