]> Pileus Git - ~andy/fetchmail/blob - driver.c
Copyright cleanup.
[~andy/fetchmail] / driver.c
1 /*
2  * driver.c -- generic driver for mail fetch method protocols
3  *
4  * Copyright 1997 by Eric S. Raymond
5  * For license terms, see the file COPYING in this directory.
6  */
7
8 #include  <config.h>
9 #include  <stdio.h>
10 #include  <setjmp.h>
11 #include  <errno.h>
12 #include  <ctype.h>
13 #include  <string.h>
14 #if defined(STDC_HEADERS)
15 #include  <stdlib.h>
16 #endif
17 #if defined(HAVE_UNISTD_H)
18 #include <unistd.h>
19 #endif
20 #if defined(HAVE_STDARG_H)
21 #include  <stdarg.h>
22 #else
23 #include  <varargs.h>
24 #endif
25 #if defined(HAVE_ALLOCA_H)
26 #include <alloca.h>
27 #endif
28 #if defined(HAVE_SYS_ITIMER_H)
29 #include <sys/itimer.h>
30 #endif
31 #include  <sys/time.h>
32 #include  <signal.h>
33
34 #ifdef HAVE_GETHOSTBYNAME
35 #include <netdb.h>
36 #include "mx.h"
37 #endif /* HAVE_GETHOSTBYNAME */
38
39 #ifdef SUNOS
40 #include <memory.h>
41 #endif
42
43 #ifdef KERBEROS_V4
44 #include <krb.h>
45 #include <des.h>
46 #include <netinet/in.h>
47 #include <netdb.h>
48 #endif /* KERBEROS_V4 */
49 #include  "socket.h"
50 #include  "fetchmail.h"
51 #include  "socket.h"
52 #include  "smtp.h"
53
54 /* BSD portability hack...I know, this is an ugly place to put it */
55 #if !defined(SIGCHLD) && defined(SIGCLD)
56 #define SIGCHLD SIGCLD
57 #endif
58
59 #define SMTP_PORT       25      /* standard SMTP service port */
60
61 extern char *strstr();  /* needed on sysV68 R3V7.1. */
62
63 int fetchlimit;         /* how often to tear down the server connection */
64 int batchcount;         /* count of messages sent in current batch */
65 bool peek_capable;      /* can we peek for better error recovery? */
66
67 static const struct method *protocol;
68 static jmp_buf  restart;
69
70 char tag[TAGLEN];
71 static int tagnum;
72 #define GENSYM  (sprintf(tag, "a%04d", ++tagnum), tag)
73
74 static char *shroud;    /* string to shroud in debug output, if  non-NULL */
75 static int mytimeout;   /* value of nonreponse timeout */
76
77 static void set_timeout(int timeleft)
78 /* reset the nonresponse-timeout */
79 {
80     struct itimerval ntimeout;
81
82     ntimeout.it_interval.tv_sec = ntimeout.it_interval.tv_usec = 0;
83     ntimeout.it_value.tv_sec  = timeleft;
84     ntimeout.it_value.tv_usec = 0;
85     setitimer(ITIMER_REAL, &ntimeout, (struct itimerval *)NULL);
86 }
87
88 static void timeout_handler (int signal)
89 /* handle server-timeout SIGALRM signal */
90 {
91     longjmp(restart, 1);
92 }
93
94 #define XMIT_ACCEPT             1
95 #define XMIT_REJECT             2
96 #define XMIT_ANTISPAM           3       
97 static int accept_count, reject_count;
98
99 #ifdef HAVE_RES_SEARCH
100 #define MX_RETRIES      3
101
102 static int is_host_alias(const char *name, struct query *ctl)
103 /* determine whether name is a DNS alias of the hostname */
104 {
105     struct hostent      *he;
106     struct mxentry      *mxp, *mxrecords;
107
108     /*
109      * The first two checks are optimizations that will catch a good
110      * many cases.  (1) check against the hostname the user
111      * specified.  Odds are good this will either be the mailserver's
112      * FQDN or a suffix of it with the mailserver's domain's default
113      * host name omitted.  Then check the rest of the `also known as'
114      * cache accumulated by previous DNS checks.  This cache is primed
115      * by the aka list option.
116      *
117      * (2) check against the mailserver's FQDN, in case
118      * it's not the same as the declared hostname.
119      *
120      * Either of these on a mail address is definitive.  Only if the
121      * name doesn't match either is it time to call the bind library.
122      * If this happens odds are good we're looking at an MX name.
123      */
124     if (str_in_list(&ctl->server.lead_server->names, name))
125         return(TRUE);
126     else if (strcmp(name, ctl->server.canonical_name) == 0)
127         return(TRUE);
128     else if (!ctl->server.dns)
129         return(FALSE);
130
131     /*
132      * We know DNS service was up at the beginning of this poll cycle.
133      * If it's down, our nameserver has crashed.  We don't want to try
134      * delivering the current message or anything else from this
135      * mailbox until it's back up.
136      */
137     else if ((he = gethostbyname(name)) != (struct hostent *)NULL)
138     {
139         if (strcmp(ctl->server.canonical_name, he->h_name) == 0)
140             goto match;
141         else
142             return(FALSE);
143     }
144     else
145         switch (h_errno)
146         {
147         case HOST_NOT_FOUND:    /* specified host is unknown */
148         case NO_ADDRESS:        /* valid, but does not have an IP address */
149             break;
150
151         case NO_RECOVERY:       /* non-recoverable name server error */
152         case TRY_AGAIN:         /* temporary error on authoritative server */
153         default:
154             if (outlevel != O_SILENT)
155                 putchar('\n');  /* terminate the progress message */
156             error(0, 0,
157                 "nameserver failure while looking for `%s' during poll of %s.",
158                 name, ctl->server.names->id);
159             ctl->errcount++;
160             break;
161         }
162
163     /*
164      * We're only here if DNS was OK but the gethostbyname() failed
165      * with a HOST_NOT_FOUND or NO_ADDRESS error.
166      * Search for a name match on MX records pointing to the server.
167      */
168     h_errno = 0;
169     if ((mxrecords = getmxrecords(name)) == (struct mxentry *)NULL)
170     {
171         switch (h_errno)
172         {
173         case HOST_NOT_FOUND:    /* specified host is unknown */
174         case NO_ADDRESS:        /* valid, but does not have an IP address */
175             return(FALSE);
176             break;
177
178         case NO_RECOVERY:       /* non-recoverable name server error */
179         case TRY_AGAIN:         /* temporary error on authoritative server */
180         default:
181             error(0, 0,
182                 "nameserver failure while looking for `%s' during poll of %s.",
183                 name, ctl->server.names->id);
184             ctl->errcount++;
185             break;
186         }
187     }
188     else
189     {
190         for (mxp = mxrecords; mxp->name; mxp++)
191             if (strcmp(ctl->server.canonical_name, mxp->name) == 0)
192                 goto match;
193         return(FALSE);
194     match:;
195     }
196
197     /* add this name to relevant server's `also known as' list */
198     save_str(&ctl->server.lead_server->names, -1, name);
199     return(TRUE);
200 }
201
202 static void map_name(name, ctl, xmit_names)
203 /* add given name to xmit_names if it matches declared localnames */
204 const char *name;               /* name to map */
205 struct query *ctl;              /* list of permissible aliases */
206 struct idlist **xmit_names;     /* list of recipient names parsed out */
207 {
208     const char  *lname;
209
210     lname = idpair_find(&ctl->localnames, name);
211     if (!lname && ctl->wildcard)
212         lname = name;
213
214     if (lname != (char *)NULL)
215     {
216         if (outlevel == O_VERBOSE)
217             error(0, 0, "mapped %s to local %s", name, lname);
218         save_str(xmit_names, XMIT_ACCEPT, lname);
219         accept_count++;
220     }
221 }
222
223 void find_server_names(hdr, ctl, xmit_names)
224 /* parse names out of a RFC822 header into an ID list */
225 const char *hdr;                /* RFC822 header in question */
226 struct query *ctl;              /* list of permissible aliases */
227 struct idlist **xmit_names;     /* list of recipient names parsed out */
228 {
229     if (hdr == (char *)NULL)
230         return;
231     else
232     {
233         char    *cp;
234
235         if ((cp = nxtaddr(hdr)) != (char *)NULL)
236             do {
237                 char    *atsign;
238
239                 if ((atsign = strchr(cp, '@')))
240                 {
241                     struct idlist       *idp;
242
243                     /*
244                      * Does a trailing segment of the hostname match something
245                      * on the localdomains list?  If so, save the whole name
246                      * and keep going.
247                      */
248                     for (idp = ctl->server.localdomains; idp; idp = idp->next)
249                     {
250                         char    *rhs;
251
252                         rhs = atsign + (strlen(atsign) - strlen(idp->id));
253                         if ((rhs[-1] == '.' || rhs[-1] == '@')
254                                         && strcasecmp(rhs, idp->id) == 0)
255                         {
256                             if (outlevel == O_VERBOSE)
257                                 error(0, 0, "passed through %s matching %s", 
258                                       cp, idp->id);
259                             save_str(xmit_names, XMIT_ACCEPT, cp);
260                             accept_count++;
261                             continue;
262                         }
263                     }
264
265                     /*
266                      * Check to see if the right-hand part is an alias
267                      * or MX equivalent of the mailserver.  If it's
268                      * not, skip this name.  If it is, we'll keep
269                      * going and try to find a mapping to a client name.
270                      */
271                     if (!is_host_alias(atsign+1, ctl))
272                     {
273                         save_str(xmit_names, XMIT_REJECT, cp);
274                         reject_count++;
275                         continue;
276                     }
277                     atsign[0] = '\0';
278                 }
279
280                 map_name(cp, ctl, xmit_names);
281             } while
282                 ((cp = nxtaddr((char *)NULL)) != (char *)NULL);
283     }
284 }
285
286 char *parse_received(struct query *ctl, char *bufp)
287 /* try to extract real addressee from the Received line */
288 {
289     char *ok;
290     static char rbuf[HOSTLEN + USERNAMELEN + 4]; 
291
292     /*
293      * Try to extract the real envelope addressee.  We look here
294      * specifically for the mailserver's Received line.
295      * Note: this will only work for sendmail, or an MTA that
296      * shares sendmail's convention for embedding the envelope
297      * address in the Received line.  Sendmail itself only
298      * does this when the mail has a single recipient.
299      */
300     if ((ok = strstr(bufp, "by ")) == (char *)NULL)
301         ok = (char *)NULL;
302     else
303     {
304         char    *sp, *tp;
305
306         /* extract space-delimited token after "by " */
307         for (sp = ok + 3; isspace(*sp); sp++)
308             continue;
309         tp = rbuf;
310         for (; !isspace(*sp); sp++)
311             *tp++ = *sp;
312         *tp = '\0';
313
314         /*
315          * If it's a DNS name of the mail server, look for the
316          * recipient name after a following "for".  Otherwise
317          * punt.
318          */
319         if (is_host_alias(rbuf, ctl))
320             ok = strstr(sp, "for ");
321         else
322             ok = (char *)NULL;
323     }
324
325     if (ok != 0)
326     {
327         char    *sp, *tp;
328
329         tp = rbuf;
330         sp = ok + 4;
331         if (*sp == '<')
332             sp++;
333         while (*sp && *sp != '>' && *sp != '@' && *sp != ';')
334             if (!isspace(*sp))
335                 *tp++ = *sp++;
336             else
337             {
338                 /* uh oh -- whitespace here can't be right! */
339                 ok = (char *)NULL;
340                 break;
341             }
342         *tp = '\0';
343     }
344
345     if (!ok)
346         return(NULL);
347     else
348     {
349         if (outlevel == O_VERBOSE)
350             error(0, 0, "found Received address `%s'", rbuf);
351         return(rbuf);
352     }
353 }
354 #endif /* HAVE_RES_SEARCH */
355
356 int smtp_open(struct query *ctl)
357 /* try to open a socket to the appropriate SMTP server for this query */ 
358 {
359     struct idlist       *idp;
360
361     /* maybe it's time to close the socket in order to force delivery */
362     if (ctl->batchlimit > 0 && (ctl->smtp_socket != -1) && batchcount++ == ctl->batchlimit)
363     {
364         close(ctl->smtp_socket);
365         ctl->smtp_socket = -1;
366         batchcount = 0;
367     }
368
369     /* run down the SMTP hunt list looking for a server that's up */
370     for (idp = ctl->smtphunt; idp; idp = idp->next)
371     {
372         /* 
373          * RFC 1123 requires that the domain name in HELO address is a
374          * "valid principal domain name" for the client host.  We
375          * violate this with malice aforethought in order to make the
376          * Received headers and logging look right.
377          *
378          * In fact this code relies on the RFC1123 requirement that the
379          * SMTP listener must accept messages even if verification of the
380          * HELO name fails (RFC1123 section 5.2.5, paragraph 2).
381          */
382
383         /* if no socket to this host is already set up, try to open ESMTP */
384         if (ctl->smtp_socket == -1)
385         {
386             if ((ctl->smtp_socket = SockOpen(idp->id,SMTP_PORT)) == -1)
387                 continue;
388             else if (SMTP_ok(ctl->smtp_socket) != SM_OK
389                      || SMTP_ehlo(ctl->smtp_socket, 
390                                   ctl->server.names->id,
391                                   &ctl->server.esmtp_options) != SM_OK)
392             {
393                 /*
394                  * RFC 1869 warns that some listeners hang up on a failed EHLO,
395                  * so it's safest not to assume the socket will still be good.
396                  */
397                 close(ctl->smtp_socket);
398                 ctl->smtp_socket = -1;
399             }
400             else
401             {
402                 ctl->smtphost = idp->id;
403                 break;
404             }
405         }
406
407         /* if opening for ESMTP failed, try SMTP */
408         if (ctl->smtp_socket == -1)
409         {
410             if ((ctl->smtp_socket = SockOpen(idp->id,SMTP_PORT)) == -1)
411                 continue;
412             else if (SMTP_ok(ctl->smtp_socket) != SM_OK
413                      || SMTP_helo(ctl->smtp_socket, ctl->server.names->id) != SM_OK)
414             {
415                 close(ctl->smtp_socket);
416                 ctl->smtp_socket = -1;
417             }
418             else
419             {
420                 ctl->smtphost = idp->id;
421                 break;
422             }
423         }
424     }
425
426     return(ctl->smtp_socket);
427 }
428
429 /* these are shared by readheaders and readbody */
430 static FILE *sinkfp;
431 static RETSIGTYPE (*sigchld)();
432 static int sizeticker;
433
434 static int readheaders(sock, len, ctl, realname)
435 /* read message headers and ship to SMTP or MDA */
436 int sock;               /* to which the server is connected */
437 long len;               /* length of message */
438 struct query *ctl;      /* query control record */
439 char *realname;         /* real name of host */
440 {
441     char buf[MSGBUFSIZE+1], return_path[MSGBUFSIZE+1]; 
442     int from_offs, to_offs, cc_offs, bcc_offs, ctt_offs, env_offs;
443     char *headers, *received_for;
444     int n, linelen, oldlen, ch, remaining;
445     char                *cp;
446     struct idlist       *idp, *xmit_names;
447     bool                        good_addresses, bad_addresses, has_nuls;
448 #ifdef HAVE_RES_SEARCH
449     bool                no_local_matches = FALSE;
450 #endif /* HAVE_RES_SEARCH */
451     int                 olderrs;
452
453     sizeticker = 0;
454     has_nuls = FALSE;
455     return_path[0] = '\0';
456     olderrs = ctl->errcount;
457
458     /* read message headers */
459     headers = received_for = NULL;
460     from_offs = to_offs = cc_offs = bcc_offs = ctt_offs = env_offs = -1;
461     oldlen = 0;
462     for (remaining = len; remaining > 0; remaining -= linelen)
463     {
464         char *line;
465
466         line = xmalloc(sizeof(buf));
467         linelen = 0;
468         line[0] = '\0';
469         do {
470             if ((n = SockRead(sock, buf, sizeof(buf)-1)) == -1)
471                 return(PS_SOCKET);
472             linelen += n;
473
474             /* lines may not be properly CRLF terminated; fix this for qmail */
475             if (ctl->forcecr)
476             {
477                 cp = buf + strlen(buf) - 1;
478                 if (*cp == '\n' && (cp == buf || cp[-1] != '\r'))
479                 {
480                     *cp++ = '\r';
481                     *cp++ = '\n';
482                     *cp++ = '\0';
483                 }
484             }
485
486             set_timeout(ctl->server.timeout);
487             /* leave extra room for reply_hack to play with */
488             line = (char *) realloc(line, strlen(line) + strlen(buf) + HOSTLEN + 1);
489             strcat(line, buf);
490             if (line[0] == '\r' && line[1] == '\n')
491                 break;
492         } while
493             /* we may need to grab RFC822 continuations */
494             ((ch = SockPeek(sock)) == ' ' || ch == '\t');
495
496         /* write the message size dots */
497         if ((outlevel > O_SILENT && outlevel < O_VERBOSE) && linelen > 0)
498         {
499             sizeticker += linelen;
500             while (sizeticker >= SIZETICKER)
501             {
502                 error_build(".");
503                 sizeticker -= SIZETICKER;
504             }
505         }
506
507         if (linelen != strlen(line))
508             has_nuls = TRUE;
509
510         /* check for end of headers; don't save terminating line */
511         if (line[0] == '\r' && line[1] == '\n')
512         {
513             free(line);
514             break;
515         }
516      
517         /*
518          * This code prevents fetchmail from becoming an accessory after
519          * the fact to upstream sendmails with the `E' option on.  This
520          * can result in an escaped Unix From_ line at the beginning of
521          * the headers.  If fetchmail just passes it through, the client
522          * listener may think the message has *no* headers (since the first)
523          * line it sees doesn't look RFC822-conformant) and fake up a set.
524          *
525          * What the user would see in this case is bogus (synthesized)
526          * headers, followed by a blank line, followed by the >From, 
527          * followed by the real headers, followed by a blank line,
528          * followed by text.
529          *
530          * We forestall this lossage by tossing anything that looks
531          * like an escaped From_ line in headers.  These aren't RFC822
532          * so our conscience is clear...
533          */
534         if (!strncasecmp(line, ">From ", 6))
535         {
536             free(line);
537             continue;
538         }
539
540         /*
541          * OK, this is messy.  If we're forwarding by SMTP, it's the
542          * SMTP-receiver's job (according to RFC821, page 22, section
543          * 4.1.1) to generate a Return-Path line on final delivery.
544          * The trouble is, we've already got one because the
545          * mailserver's SMTP thought *it* was responsible for final
546          * delivery.
547          *
548          * Stash away the contents of Return-Path for use in generating
549          * MAIL FROM later on, then prevent the header from being saved
550          * with the others.  In effect, we strip it off here.
551          *
552          * If the SMTP server conforms to the standards, and fetchmail gets the
553          * envelope sender from the Return-Path, the new Return-Path should be
554          * exactly the same as the original one.
555          */
556         if (!ctl->mda && !strncasecmp("Return-Path:", line, 12))
557         {
558             strcpy(return_path, nxtaddr(line));
559             free(line);
560             continue;
561         }
562
563         if (ctl->rewrite)
564             reply_hack(line, realname);
565
566         if (!headers)
567         {
568             oldlen = strlen(line);
569             headers = xmalloc(oldlen + 1);
570             (void) strcpy(headers, line);
571             free(line);
572             line = headers;
573         }
574         else
575         {
576             int newlen;
577
578             newlen = oldlen + strlen(line);
579             headers = (char *) realloc(headers, newlen + 1);
580             if (headers == NULL)
581                 return(PS_IOERR);
582             strcpy(headers + oldlen, line);
583             free(line);
584             line = headers + oldlen;
585             oldlen = newlen;
586         }
587
588         if (from_offs == -1 && !strncasecmp("From:", line, 5))
589             from_offs = (line - headers);
590         else if (from_offs == -1 && !strncasecmp("Resent-From:", line, 12))
591             from_offs = (line - headers);
592         else if (from_offs == -1 && !strncasecmp("Apparently-From:", line, 16))
593             from_offs = (line - headers);
594
595         else if (!strncasecmp("To:", line, 3))
596             to_offs = (line - headers);
597
598         else if (ctl->server.envelope != STRING_DISABLED && env_offs == -1
599                  && !strncasecmp(ctl->server.envelope,
600                                                 line,
601                                                 strlen(ctl->server.envelope)))
602             env_offs = (line - headers);
603
604         else if (!strncasecmp("Cc:", line, 3))
605             cc_offs = (line - headers);
606
607         else if (!strncasecmp("Bcc:", line, 4))
608             bcc_offs = (line - headers);
609
610         else if (!strncasecmp("Content-Transfer-Encoding:", line, 26))
611             ctt_offs = (line - headers);
612
613 #ifdef HAVE_RES_SEARCH
614         else if (ctl->server.envelope != STRING_DISABLED && MULTIDROP(ctl) && !received_for && !strncasecmp("Received:", line, 9))
615             received_for = parse_received(ctl, line);
616 #endif /* HAVE_RES_SEARCH */
617     }
618
619     /*
620      * Hack time.  If the first line of the message was blank, with no headers
621      * (this happens occasionally due to bad gatewaying software) cons up
622      * a set of fake headers.  
623      *
624      * If you modify the fake header template below, be sure you don't
625      * make either From or To address @-less, otherwise the reply_hack
626      * logic will do bad things.
627      */
628     if (headers == (char *)NULL)
629     {
630         sprintf(buf, 
631         "From: <FETCHMAIL-DAEMON@%s>\r\nTo: %s@localhost\r\nSubject: Headerless mail from %s's mailbox on %s\r\n",
632                 fetchmailhost, user, ctl->remotename, realname);
633         headers = xstrdup(buf);
634     }
635
636     /*
637      * We can now process message headers before reading the text.
638      * In fact we have to, as this will tell us where to forward to.
639      */
640
641     /* cons up a list of local recipients */
642     xmit_names = (struct idlist *)NULL;
643     bad_addresses = good_addresses = accept_count = reject_count = 0;
644 #ifdef HAVE_RES_SEARCH
645     /* is this a multidrop box? */
646     if (MULTIDROP(ctl))
647     {
648         if (env_offs > -1)          /* We have the actual envelope addressee */
649             find_server_names(headers + env_offs, ctl, &xmit_names);
650         else if (received_for)
651             /*
652              * We have the Received for addressee.  
653              * It has to be a mailserver address, or we
654              * wouldn't have got here.
655              */
656             map_name(received_for, ctl, &xmit_names);
657         else
658         {
659             /*
660              * We haven't extracted the envelope address.
661              * So check all the header addresses.
662              */
663             if (to_offs > -1)
664                 find_server_names(headers + to_offs,  ctl, &xmit_names);
665             if (cc_offs > -1)
666                 find_server_names(headers + cc_offs,  ctl, &xmit_names);
667             if (bcc_offs > -1)
668                 find_server_names(headers + bcc_offs, ctl, &xmit_names);
669         }
670         if (!accept_count)
671         {
672             no_local_matches = TRUE;
673             save_str(&xmit_names, XMIT_ACCEPT, user);
674             if (outlevel == O_VERBOSE)
675                 error(0, 0, 
676                       "no local matches, forwarding to %s",
677                       user);
678         }
679     }
680     else        /* it's a single-drop box, use first localname */
681 #endif /* HAVE_RES_SEARCH */
682         save_str(&xmit_names, XMIT_ACCEPT, ctl->localnames->id);
683
684
685     /*
686      * Time to either address the message or decide we can't deliver it yet.
687      */
688     if (ctl->errcount > olderrs)        /* there were DNS errors above */
689     {
690         if (outlevel == O_VERBOSE)
691             error(0,0, "forwarding and deletion suppressed due to DNS errors");
692         free(headers);
693         return(PS_TRANSIENT);
694     }
695     else if (ctl->mda)          /* we have a declared MDA */
696     {
697         int     length = 0;
698         char    *names, *cmd;
699
700         /*
701          * We go through this in order to be able to handle very
702          * long lists of users and (re)implement %s.
703          */
704         for (idp = xmit_names; idp; idp = idp->next)
705             if (idp->val.num == XMIT_ACCEPT)
706                 length += (strlen(idp->id) + 1);
707         names = (char *)alloca(length);
708         names[0] = '\0';
709         for (idp = xmit_names; idp; idp = idp->next)
710             if (idp->val.num == XMIT_ACCEPT)
711             {
712                 strcat(names, idp->id);
713                 strcat(names, " ");
714             }
715         cmd = (char *)alloca(strlen(ctl->mda) + length);
716         sprintf(cmd, ctl->mda, names);
717         if (outlevel == O_VERBOSE)
718             error(0, 0, "about to deliver with: %s", cmd);
719
720 #ifdef HAVE_SETEUID
721         /*
722          * Arrange to run with user's permissions if we're root.
723          * This will initialize the ownership of any files the
724          * MDA creates properly.  (The seteuid call is available
725          * under all BSDs and Linux)
726          */
727         seteuid(ctl->uid);
728 #endif /* HAVE_SETEUID */
729
730         sinkfp = popen(cmd, "w");
731
732 #ifdef HAVE_SETEUID
733         /* this will fail quietly if we didn't start as root */
734         seteuid(0);
735 #endif /* HAVE_SETEUID */
736
737         if (!sinkfp)
738         {
739             error(0, -1, "MDA open failed");
740             return(PS_IOERR);
741         }
742
743         sigchld = signal(SIGCHLD, SIG_DFL);
744     }
745     else
746     {
747         char    *ap, *ctt, options[MSGBUFSIZE];
748
749         /* build a connection to the SMTP listener */
750         if ((smtp_open(ctl) == -1))
751         {
752             free_str_list(&xmit_names);
753             error(0, -1, "SMTP connect to %s failed",
754                   ctl->smtphost ? ctl->smtphost : "localhost");
755             return(PS_SMTP);
756         }
757
758         /*
759          * Compute ESMTP options.  It's a kluge to use nxtaddr()
760          * here because the contents of the Content-Transfer-Encoding
761          * headers isn't semantically an address.  But it has the
762          * desired tokenizing effect.
763          */
764         options[0] = '\0';
765         if ((ctl->server.esmtp_options & ESMTP_8BITMIME)
766             && (ctt_offs >= 0)
767             && (ctt = nxtaddr(headers + ctt_offs)))
768             if (!strcasecmp(ctt,"7BIT"))
769                 sprintf(options, " BODY=7BIT");
770             else if (!strcasecmp(ctt,"8BIT"))
771                 sprintf(options, " BODY=8BITMIME");
772         if ((ctl->server.esmtp_options & ESMTP_SIZE))
773             sprintf(options + strlen(options), " SIZE=%ld", len);
774
775         /*
776          * If there is a Return-Path address on the message, this was
777          * almost certainly the MAIL FROM address given the originating
778          * sendmail.  This is the best thing to use for logging the
779          * message origin (it sets up the right behavior for bounces and
780          * mailing lists).  Otherwise, take the From address.
781          *
782          * Try to get the SMTP listener to take the Return-Path or
783          * From address as MAIL FROM .  If it won't, fall back on the
784          * calling-user ID.  This won't affect replies, which use the
785          * header From address anyway.
786          *
787          * RFC 1123 requires that the domain name part of the
788          * MAIL FROM address be "canonicalized", that is a
789          * FQDN or MX but not a CNAME.  We'll assume the From
790          * header is already in this form here (it certainly
791          * is if rewrite is on).  RFC 1123 is silent on whether
792          * a nonexistent hostname part is considered canonical.
793          *
794          * This is a potential problem if the MTAs further upstream
795          * didn't pass canonicalized From/Return-Path lines, *and* the
796          * local SMTP listener insists on them.
797          */
798         ap = (char *)NULL;
799         if (return_path[0])
800             ap = return_path;
801         else if (from_offs == -1 || !(ap = nxtaddr(headers + from_offs)))
802             ap = user;
803         if (SMTP_from(ctl->smtp_socket, ap, options) != SM_OK)
804         {
805             int smtperr = atoi(smtp_response);
806
807             /*
808              * Suppress error message only if the response specifically 
809              * means `excluded for policy reasons'.  We *should* see
810              * an error when the return code is less specific.
811              */
812             if (smtperr >= 400 && smtperr != 571)
813                 error(0, -1, "SMTP error: %s", smtp_response);
814
815             switch (smtperr)
816             {
817             case 571:   /* sendmail's "unsolicited email refused" */
818             case 501:   /* exim's old antispam response */
819             case 550:   /* exim's new antispam response (temporary) */
820                 /*
821                  * SMTP listener explicitly refuses to deliver
822                  * mail coming from this address, probably due
823                  * to an anti-spam domain exclusion.  Respect
824                  * this.  Don't try to ship the message, and
825                  * don't prevent it from being deleted.
826                  */
827                 free(headers);
828                 return(PS_REFUSED);
829
830             case 452: /* insufficient system storage */
831                 /*
832                  * Temporary out-of-queue-space condition on the
833                  * ESMTP server.  Don't try to ship the message, 
834                  * and suppress deletion so it can be retried on
835                  * a future retrieval cycle.
836                  */
837                 SMTP_rset(ctl->smtp_socket);    /* required by RFC1870 */
838                 free(headers);
839                 return(PS_TRANSIENT);
840
841             case 552: /* message exceeds fixed maximum message size */
842                 /*
843                  * Permanent no-go condition on the
844                  * ESMTP server.  Don't try to ship the message, 
845                  * and allow it to be deleted.
846                  */
847                 SMTP_rset(ctl->smtp_socket);    /* required by RFC1870 */
848                 free(headers);
849                 return(PS_REFUSED);
850
851             default:    /* retry with invoking user's address */
852                 if (SMTP_from(ctl->smtp_socket, user, options) != SM_OK)
853                 {
854                     error(0, -1, "SMTP error: %s", smtp_response);
855                     free(headers);
856                     return(PS_SMTP);    /* should never happen */
857                 }
858             }
859         }
860
861         /*
862          * Now list the recipient addressees
863          *
864          * RFC 1123 requires that the domain name part of the
865          * RCPT TO address be "canonicalized", that is a FQDN
866          * or MX but not a CNAME.  RFC1123 doesn't say whether
867          * the FQDN part can be null (as it frequently will be
868          * here), but it's hard to see how this could cause a
869          * problem.
870          */
871         for (idp = xmit_names; idp; idp = idp->next)
872             if (idp->val.num == XMIT_ACCEPT)
873                 if (SMTP_rcpt(ctl->smtp_socket, idp->id) == SM_OK)
874                     good_addresses++;
875                 else
876                 {
877                     bad_addresses++;
878                     idp->val.num = XMIT_ANTISPAM;
879                     error(0, 0, 
880                           "SMTP listener doesn't like recipient address `%s'", idp->id);
881                 }
882         if (!good_addresses && SMTP_rcpt(ctl->smtp_socket, user) != SM_OK)
883         {
884             error(0, 0, 
885                   "can't even send to calling user!");
886             free(headers);
887             return(PS_SMTP);
888         }
889
890         /* tell it we're ready to send data */
891         SMTP_data(ctl->smtp_socket);
892     }
893
894     /* we may need to strip carriage returns */
895     if (ctl->stripcr)
896     {
897         char    *sp, *tp;
898
899         for (sp = tp = headers; *sp; sp++)
900             if (*sp != '\r')
901                 *tp++ =  *sp;
902         *tp = '\0';
903
904     }
905
906     /* write all the headers */
907     n = 0;
908     if (ctl->mda && sinkfp)
909         n = fwrite(headers, 1, strlen(headers), sinkfp);
910     else if (ctl->smtp_socket != -1)
911         n = SockWrite(ctl->smtp_socket, headers, strlen(headers));
912     free(headers);
913
914     if (n < 0)
915     {
916         error(0, errno, "writing RFC822 headers");
917         if (ctl->mda)
918         {
919             pclose(sinkfp);
920             signal(SIGCHLD, sigchld);
921         }
922         return(PS_IOERR);
923     }
924     else if (outlevel == O_VERBOSE)
925         fputs("#", stderr);
926
927     /* write error notifications */
928 #ifdef HAVE_RES_SEARCH
929     if (no_local_matches || has_nuls || bad_addresses)
930 #else
931     if (has_nuls || bad_addresses)
932 #endif /* HAVE_RES_SEARCH */
933     {
934         int     errlen = 0;
935         char    errhd[USERNAMELEN + POPBUFSIZE], *errmsg;
936
937         errmsg = errhd;
938         (void) strcpy(errhd, "X-Fetchmail-Warning: ");
939 #ifdef HAVE_RES_SEARCH
940         if (no_local_matches)
941         {
942             if (reject_count != 1)
943                 strcat(errhd, "no recipient addresses matched declared local names");
944             else
945             {
946                 for (idp = xmit_names; idp; idp = idp->next)
947                     if (idp->val.num == XMIT_REJECT)
948                         break;
949                 sprintf(errhd+strlen(errhd), "recipient address %s didn't match any local name", idp->id);
950             }
951         }
952 #endif /* HAVE_RES_SEARCH */
953
954         if (has_nuls)
955         {
956             if (errhd[sizeof("X-Fetchmail-Warning: ")])
957                 strcat(errhd, "; ");
958             strcat(errhd, "message has embedded NULs");
959         }
960
961         if (bad_addresses)
962         {
963             if (errhd[sizeof("X-Fetchmail-Warning: ")])
964                 strcat(errhd, "; ");
965             strcat(errhd, "SMTP listener rejected local recipient addresses: ");
966             errlen = strlen(errhd);
967             for (idp = xmit_names; idp; idp = idp->next)
968                 if (idp->val.num == XMIT_ANTISPAM)
969                     errlen += strlen(idp->id) + 2;
970
971             errmsg = alloca(errlen+3);
972             (void) strcpy(errmsg, errhd);
973             for (idp = xmit_names; idp; idp = idp->next)
974                 if (idp->val.num == XMIT_ANTISPAM)
975                 {
976                     strcat(errmsg, idp->id);
977                     if (idp->next)
978                         strcat(errmsg, ", ");
979                 }
980
981         }
982
983         if (ctl->mda && !ctl->forcecr)
984             strcat(errmsg, "\n");
985         else
986             strcat(errmsg, "\r\n");
987
988         /* we may need to strip carriage returns */
989         if (ctl->stripcr)
990         {
991             char        *sp, *tp;
992
993             for (sp = tp = errmsg; *sp; sp++)
994                 if (*sp != '\r')
995                     *tp++ =  *sp;
996             *tp = '\0';
997         }
998
999         /* ship out the error line */
1000         if (sinkfp)
1001         {
1002             if (ctl->mda)
1003                 fwrite(errmsg, sizeof(char), strlen(errmsg), sinkfp);
1004             else
1005                 SockWrite(ctl->smtp_socket, errmsg, strlen(errmsg));
1006         }
1007     }
1008
1009     free_str_list(&xmit_names);
1010
1011     /* issue the delimiter line */
1012     if (sinkfp && ctl->mda)
1013         fputc('\n', sinkfp);
1014     else if (ctl->smtp_socket != -1)
1015     {
1016         if (ctl->stripcr)
1017             SockWrite(ctl->smtp_socket, "\n", 1);
1018         else
1019             SockWrite(ctl->smtp_socket, "\r\n", 2);
1020     }
1021
1022     return(PS_SUCCESS);
1023 }
1024
1025 static int readbody(sock, ctl, forward, len, delimited)
1026 /* read and dispose of a message body presented on sock */
1027 struct query *ctl;      /* query control record */
1028 int sock;               /* to which the server is connected */
1029 int len;                /* length of message */
1030 bool forward;           /* TRUE to forward */
1031 bool delimited;         /* does the protocol use a message delimiter? */
1032 {
1033     int linelen;
1034     char buf[MSGBUFSIZE+1], *cp;
1035
1036     /* pass through the text lines */
1037     while (delimited || len > 0)
1038     {
1039         if ((linelen = SockRead(sock, buf, sizeof(buf)-1)) == -1)
1040             return(PS_SOCKET);
1041         set_timeout(ctl->server.timeout);
1042
1043         /* write the message size dots */
1044         if (linelen > 0)
1045         {
1046             sizeticker += linelen;
1047             while (sizeticker >= SIZETICKER)
1048             {
1049                 if (outlevel > O_SILENT)
1050                     error_build(".");
1051                 sizeticker -= SIZETICKER;
1052             }
1053         }
1054         len -= linelen;
1055
1056         /* fix messages that have only \n line-termination (for qmail) */
1057         if (ctl->forcecr)
1058         {
1059             cp = buf + strlen(buf) - 1;
1060             if (*cp == '\n' && (cp == buf || cp[-1] != '\r'))
1061             {
1062                 *cp++ = '\r';
1063                 *cp++ = '\n';
1064                 *cp++ = '\0';
1065             }
1066         }
1067
1068         /* check for end of message */
1069         if (delimited && *buf == '.')
1070             if (buf[1] == '\r' && buf[2] == '\n')
1071                 break;
1072
1073         /* ship out the text line */
1074         if (forward)
1075         {
1076             int n;
1077
1078             /*
1079              * SMTP byte-stuffing.  We only do this if the protocol does *not*
1080              * use .<CR><LF> as EOM.  If it does, the server will already have
1081              * decorated any . lines it sends back up.
1082              */
1083             if (!delimited && *buf == '.')
1084                 if (sinkfp && ctl->mda)
1085                     fputs(".", sinkfp);
1086                 else if (ctl->smtp_socket != -1)
1087                     SockWrite(ctl->smtp_socket, buf, 1);
1088
1089             /* we may need to strip carriage returns */
1090             if (ctl->stripcr)
1091             {
1092                 char    *sp, *tp;
1093
1094                 for (sp = tp = buf; *sp; sp++)
1095                     if (*sp != '\r')
1096                         *tp++ =  *sp;
1097                 *tp = '\0';
1098             }
1099
1100             n = 0;
1101             if (ctl->mda)
1102                 n = fwrite(buf, 1, strlen(buf), sinkfp);
1103             else if (ctl->smtp_socket != -1)
1104                 n = SockWrite(ctl->smtp_socket, buf, strlen(buf));
1105
1106             if (n < 0)
1107             {
1108                 error(0, errno, "writing message text");
1109                 if (ctl->mda)
1110                 {
1111                     pclose(sinkfp);
1112                     signal(SIGCHLD, sigchld);
1113                 }
1114                 return(PS_IOERR);
1115             }
1116             else if (outlevel == O_VERBOSE)
1117                 fputc('*', stderr);
1118         }
1119     }
1120
1121     return(PS_SUCCESS);
1122 }
1123
1124 #ifdef KERBEROS_V4
1125 int
1126 kerberos_auth (socket, canonical) 
1127 /* authenticate to the server host using Kerberos V4 */
1128 int socket;             /* socket to server host */
1129 const char *canonical;  /* server name */
1130 {
1131     char * host_primary;
1132     KTEXT ticket;
1133     MSG_DAT msg_data;
1134     CREDENTIALS cred;
1135     Key_schedule schedule;
1136     int rem;
1137   
1138     ticket = ((KTEXT) (malloc (sizeof (KTEXT_ST))));
1139     rem = (krb_sendauth (0L, socket, ticket, "pop",
1140                          canonical,
1141                          ((char *) (krb_realmofhost (canonical))),
1142                          ((unsigned long) 0),
1143                          (&msg_data),
1144                          (&cred),
1145                          (schedule),
1146                          ((struct sockaddr_in *) 0),
1147                          ((struct sockaddr_in *) 0),
1148                          "KPOPV0.1"));
1149     free (ticket);
1150     if (rem != KSUCCESS)
1151     {
1152         error(0, -1, "kerberos error %s", (krb_get_err_text (rem)));
1153         return (PS_ERROR);
1154     }
1155     return (0);
1156 }
1157 #endif /* KERBEROS_V4 */
1158
1159 int do_protocol(ctl, proto)
1160 /* retrieve messages from server using given protocol method table */
1161 struct query *ctl;              /* parsed options with merged-in defaults */
1162 const struct method *proto;     /* protocol method table */
1163 {
1164     int ok, js, pst;
1165     char *msg, *cp, realname[HOSTLEN];
1166     void (*sigsave)();
1167
1168 #ifndef KERBEROS_V4
1169     if (ctl->server.preauthenticate == A_KERBEROS_V4)
1170     {
1171         error(0, -1, "Kerberos V4 support not linked.");
1172         return(PS_ERROR);
1173     }
1174 #endif /* KERBEROS_V4 */
1175
1176     /* lacking methods, there are some options that may fail */
1177     if (!proto->is_old)
1178     {
1179         /* check for unsupported options */
1180         if (ctl->flush) {
1181             error(0, 0,
1182                     "Option --flush is not supported with %s",
1183                     proto->name);
1184             return(PS_SYNTAX);
1185         }
1186         else if (ctl->fetchall) {
1187             error(0, 0,
1188                     "Option --all is not supported with %s",
1189                     proto->name);
1190             return(PS_SYNTAX);
1191         }
1192     }
1193     if (!proto->getsizes && ctl->limit)
1194     {
1195         error(0, 0,
1196                 "Option --limit is not supported with %s",
1197                 proto->name);
1198         return(PS_SYNTAX);
1199     }
1200
1201     protocol = proto;
1202     tagnum = 0;
1203     tag[0] = '\0';      /* nuke any tag hanging out from previous query */
1204     ok = 0;
1205     error_init(poll_interval == 0 && !logfile);
1206
1207     /* set up the server-nonresponse timeout */
1208     sigsave = signal(SIGALRM, timeout_handler);
1209     set_timeout(mytimeout = ctl->server.timeout);
1210
1211     if ((js = setjmp(restart)) == 1)
1212     {
1213         error(0, 0,
1214                 "timeout after %d seconds waiting for %s.",
1215                 ctl->server.timeout, ctl->server.names->id);
1216         ok = PS_ERROR;
1217     }
1218     else
1219     {
1220         char buf [POPBUFSIZE+1], *sp;
1221         int *msgsizes, len, num, count, new, deletions = 0;
1222         int sock, port, fetches;
1223         struct idlist *idp;
1224
1225         /* execute pre-initialization command, if any */
1226         if (ctl->preconnect && (ok = system(ctl->preconnect)))
1227         {
1228             sprintf(buf, "pre-connection command failed with status %d", ok);
1229             error(0, 0, buf);
1230             ok = PS_SYNTAX;
1231             goto closeUp;
1232         }
1233
1234         /* open a socket to the mail server */
1235         port = ctl->server.port ? ctl->server.port : protocol->port;
1236         if ((sock = SockOpen(ctl->server.names->id, port)) == -1)
1237         {
1238 #ifndef EHOSTUNREACH
1239 #define EHOSTUNREACH (-1)
1240 #endif
1241             if (outlevel == O_VERBOSE || errno != EHOSTUNREACH)
1242                 error(0, errno, "connecting to host");
1243             ok = PS_SOCKET;
1244             goto closeUp;
1245         }
1246
1247 #ifdef KERBEROS_V4
1248         if (ctl->server.preauthenticate == A_KERBEROS_V4)
1249         {
1250             ok = kerberos_auth(sock, ctl->server.canonical_name);
1251             if (ok != 0)
1252                 goto cleanUp;
1253             set_timeout(ctl->server.timeout);
1254         }
1255 #endif /* KERBEROS_V4 */
1256
1257         /* accept greeting message from mail server */
1258         ok = (protocol->parse_response)(sock, buf);
1259         if (ok != 0)
1260             goto cleanUp;
1261         set_timeout(ctl->server.timeout);
1262
1263         /*
1264          * Try to parse the host's actual name out of the greeting
1265          * message.  We do this so that the progress messages will
1266          * make sense even if the connection is indirected through
1267          * ssh. *Do* use this for hacking reply headers, but *don't*
1268          * use it for error logging, as the names in the log should
1269          * correlate directly back to rc file entries.
1270          *
1271          * This assumes that the first space-delimited token found
1272          * that contains at least two dots (with the characters on
1273          * each side of the dot alphanumeric to exclude version
1274          * numbers) is the hostname.  The hostname candidate may not
1275          * contain @ -- if it does it's probably a mailserver
1276          * maintainer's name.  If no such token is found, fall back on
1277          * the .fetchmailrc id.
1278          */
1279         pst = 0;
1280         sp = (char *)NULL;      /* sacrifice to -Wall */
1281         for (cp = buf; *cp; cp++)
1282         {
1283             switch (pst)
1284             {
1285             case 0:             /* skip to end of current token */
1286                 if (*cp == ' ')
1287                     pst = 1;
1288                 break;
1289
1290             case 1:             /* look for blank-delimited token */
1291                 if (*cp != ' ')
1292                 {
1293                     sp = cp;
1294                     pst = 2;
1295                 }
1296                 break;
1297
1298             case 2:             /* look for first dot */
1299                 if (*cp == '@')
1300                     pst = 0;
1301                 else if (*cp == ' ')
1302                     pst = 1;
1303                 else if (*cp == '.' && isalpha(cp[1]) && isalpha(cp[-1]))
1304                     pst = 3;
1305                 break;
1306
1307             case 3:             /* look for second dot */
1308                 if (*cp == '@')
1309                     pst = 0;
1310                 else if (*cp == ' ')
1311                     pst = 1;
1312                 else if (*cp == '.' && isalpha(cp[1]) && isalpha(cp[-1]))
1313                     pst = 4;
1314                 break;
1315
1316             case 4:             /* look for trailing space */
1317                 if (*cp == '@')
1318                     pst = 0;
1319                 else if (*cp == ' ')
1320                 {
1321                     pst = 5;
1322                     goto done;
1323                 }
1324                 break;
1325             }
1326         }
1327     done:
1328         if (pst == 5)
1329         {
1330             char        *tp = realname;
1331
1332             while (sp < cp)
1333                 *tp++ = *sp++;
1334             *tp = '\0';
1335         }
1336         else
1337             strcpy(realname, ctl->server.names->id);
1338
1339         /* try to get authorized to fetch mail */
1340         if (protocol->getauth)
1341         {
1342             shroud = ctl->password;
1343             ok = (protocol->getauth)(sock, ctl, buf);
1344             shroud = (char *)NULL;
1345             if (ok == PS_ERROR)
1346                 ok = PS_AUTHFAIL;
1347             if (ok != 0)
1348             {
1349                 error(0, -1, "Authorization failure on %s@%s", 
1350                       ctl->remotename,
1351                       realname);
1352                 goto cleanUp;
1353             }
1354             set_timeout(ctl->server.timeout);
1355         }
1356
1357         ctl->errcount = fetches = 0;
1358
1359         /* now iterate over each folder selected */
1360         for (idp = ctl->mailboxes; idp; idp = idp->next)
1361         {
1362             if (outlevel >= O_VERBOSE)
1363                 if (idp->next)
1364                     error(0, 0, "selecting folder %s");
1365                 else
1366                     error(0, 0, "selecting default folder");
1367
1368             /* compute number of messages and number of new messages waiting */
1369             ok = (protocol->getrange)(sock, ctl, idp->id, &count, &new);
1370             if (ok != 0)
1371                 goto cleanUp;
1372             set_timeout(ctl->server.timeout);
1373
1374             /* show user how many messages we downloaded */
1375             if (idp->id)
1376                 (void) sprintf(buf, "%s@%s:%s",
1377                                ctl->remotename, realname, idp->id);
1378             else
1379                 (void) sprintf(buf, "%s@%s", ctl->remotename, realname);
1380             if (outlevel > O_SILENT)
1381                 if (count == -1)                /* only used for ETRN */
1382                     error(0, 0, "Polling %s", buf);
1383                 else if (count == 0)
1384                     error(0, 0, "No mail at %s", buf); 
1385                 else
1386                 {
1387                     if (new != -1 && (count - new) > 0)
1388                         error(0, 0, "%d message%s (%d seen) at %s.",
1389                               count, count > 1 ? "s" : "", count-new, buf);
1390                     else
1391                         error(0, 0, "%d message%s at %s.", 
1392                               count, count > 1 ? "s" : "", buf);
1393                 }
1394
1395             /*
1396              * We may need to get sizes in order to check message
1397              * limits.  If we ever decide that always having accurate
1398              * whole-message (as opposed to header) lengths in the
1399              * progress messages is important, all we have to do is
1400              * remove the `&& ctl->limit' here.
1401              */
1402             msgsizes = (int *)NULL;
1403             if (proto->getsizes && ctl->limit > 0)
1404             {
1405                 msgsizes = (int *)alloca(sizeof(int) * count);
1406
1407                 ok = (proto->getsizes)(sock, count, msgsizes);
1408                 if (ok != 0)
1409                     goto cleanUp;
1410                 set_timeout(ctl->server.timeout);
1411             }
1412
1413             if (check_only)
1414             {
1415                 if (new == -1 || ctl->fetchall)
1416                     new = count;
1417                 ok = ((new > 0) ? PS_SUCCESS : PS_NOMAIL);
1418                 goto cleanUp;
1419             }
1420             else if (count > 0)
1421             {    
1422                 bool    force_retrieval;
1423
1424                 /*
1425                  * What forces this code is that in POP3 and IMAP2BIS you can't
1426                  * fetch a message without having it marked `seen'.  In IMAP4,
1427                  * on the other hand, you can (peek_capable is set to convey
1428                  * this).
1429                  *
1430                  * The result of being unable to peek is that if there's
1431                  * any kind of transient error (DNS lookup failure, or
1432                  * sendmail refusing delivery due to process-table limits)
1433                  * the message will be marked "seen" on the server without
1434                  * having been delivered.  This is not a big problem if
1435                  * fetchmail is running in foreground, because the user
1436                  * will see a "skipped" message when it next runs and get
1437                  * clued in.
1438                  *
1439                  * But in daemon mode this leads to the message being silently
1440                  * ignored forever.  This is not acceptable.
1441                  *
1442                  * We compensate for this by checking the error count from the 
1443                  * previous pass and forcing all messages to be considered new
1444                  * if it's nonzero.
1445                  */
1446                 force_retrieval = !peek_capable && (ctl->errcount > 0);
1447
1448                 /* read, forward, and delete messages */
1449                 for (num = 1; num <= count; num++)
1450                 {
1451                     bool toolarge = (ctl->limit > 0)
1452                         && msgsizes && (msgsizes[num-1] > ctl->limit);
1453                     bool fetch_it = !toolarge 
1454                         && (ctl->fetchall || force_retrieval || !(protocol->is_old && (protocol->is_old)(sock,ctl,num)));
1455                     bool suppress_delete = FALSE;
1456                     bool suppress_forward = FALSE;
1457
1458                     /* we may want to reject this message if it's old */
1459                     if (!fetch_it)
1460                     {
1461                         if (outlevel > O_SILENT)
1462                         {
1463                             error_build("skipping message %d", num);
1464                             if (toolarge)
1465                                 error_build(" (oversized, %d bytes)", msgsizes[num-1]);
1466                         }
1467                     }
1468                     else
1469                     {
1470                         /* request a message */
1471                         ok = (protocol->fetch_headers)(sock, ctl, num, &len);
1472                         if (ok != 0)
1473                             goto cleanUp;
1474                         set_timeout(ctl->server.timeout);
1475
1476                         if (outlevel > O_SILENT)
1477                         {
1478                             bool havesizes;
1479                             int mlen;
1480
1481                             error_build("reading message %d", num);
1482
1483                             if (!protocol->fetch_body)
1484                             {
1485                                 havesizes = TRUE;
1486                                 mlen = len;
1487                             }
1488                             else if (msgsizes)
1489                             {
1490                                 havesizes = TRUE;
1491                                 mlen = msgsizes[num - 1];
1492                             }
1493                             else        /* no way to know body size yet */
1494                             {
1495                                 havesizes = FALSE;
1496                                 mlen = len;
1497                             }
1498
1499                             if (mlen > 0)
1500                                 error_build(" (%d %sbytes)",
1501                                             mlen, havesizes ? "" : "header ");
1502                             if (outlevel == O_VERBOSE)
1503                                 error_complete(0, 0, "");
1504                             else
1505                                 error_build(" ");
1506                         }
1507
1508                         /* 
1509                          * Read the message headers and ship them to the
1510                          * output sink.  
1511                          */
1512                         ok = readheaders(sock, len, ctl, realname);
1513                         if (ok == PS_TRANSIENT)
1514                             suppress_delete = TRUE;
1515                         else if (ok == PS_REFUSED)
1516                             suppress_forward = TRUE;
1517                         else if (ok)
1518                             goto cleanUp;
1519                         set_timeout(ctl->server.timeout);
1520
1521                         /* 
1522                          * If we're using IMAP4 or something else that
1523                          * can fetch headers separately from bodies,
1524                          * it's time to request the body now.  This
1525                          * fetch may be skipped if we got an anti-spam
1526                          * or other PS_REFUSED error response during
1527                          * read_headers.
1528                          */
1529                         if (protocol->fetch_body) 
1530                         {
1531                             if ((ok = (protocol->trail)(sock, ctl, num)))
1532                                 goto cleanUp;
1533                             set_timeout(ctl->server.timeout);
1534                             len = 0;
1535                             if (!suppress_forward)
1536                             {
1537                                 if ((ok=(protocol->fetch_body)(sock,ctl,num,&len)))
1538                                     goto cleanUp;
1539                                 if (!msgsizes)
1540                                     error_build(" (%d body bytes) ", len);
1541                                 set_timeout(ctl->server.timeout);
1542                             }
1543                         }
1544
1545                         /* process the body now */
1546                         if (len > 0)
1547                         {
1548                             ok = readbody(sock,
1549                                           ctl,
1550                                           !suppress_forward,
1551                                           len,
1552                                           protocol->delimited);
1553                             if (ok == PS_TRANSIENT)
1554                                 suppress_delete = TRUE;
1555                             else if (ok)
1556                                 goto cleanUp;
1557                             set_timeout(ctl->server.timeout);
1558
1559                             /* tell server we got it OK and resynchronize */
1560                             if (protocol->trail)
1561                             {
1562                                 ok = (protocol->trail)(sock, ctl, num);
1563                                 if (ok != 0)
1564                                     goto cleanUp;
1565                                 set_timeout(ctl->server.timeout);
1566                             }
1567                         }
1568
1569                         /* end-of-message processing starts here */
1570                         if (outlevel == O_VERBOSE)
1571                             fputc('\n', stderr);
1572
1573                         if (ctl->mda)
1574                         {
1575                             int rc;
1576
1577                             /* close the delivery pipe, we'll reopen before next message */
1578                             rc = pclose(sinkfp);
1579                             signal(SIGCHLD, sigchld);
1580                             if (rc)
1581                             {
1582                                 error(0, -1, "MDA exited abnormally or returned nonzero status");
1583                                 goto cleanUp;
1584                             }
1585                         }
1586                         else if (!suppress_forward)
1587                         {
1588                             /* write message terminator */
1589                             if (SMTP_eom(ctl->smtp_socket) != SM_OK)
1590                             {
1591                                 error(0, -1, "SMTP listener refused delivery");
1592                                 ctl->errcount++;
1593                                 suppress_delete = TRUE;
1594                             }
1595                         }
1596
1597                         fetches++;
1598                     }
1599
1600                     /*
1601                      * At this point in flow of control, either we've bombed
1602                      * on a protocol error or had delivery refused by the SMTP
1603                      * server (unlikely -- I've never seen it) or we've seen
1604                      * `accepted for delivery' and the message is shipped.
1605                      * It's safe to mark the message seen and delete it on the
1606                      * server now.
1607                      */
1608
1609                     /* maybe we delete this message now? */
1610                     if (protocol->delete
1611                         && !suppress_delete
1612                         && (fetch_it ? !ctl->keep : ctl->flush))
1613                     {
1614                         deletions++;
1615                         if (outlevel > O_SILENT) 
1616                             error_complete(0, 0, " flushed");
1617                         ok = (protocol->delete)(sock, ctl, num);
1618                         if (ok != 0)
1619                             goto cleanUp;
1620                         set_timeout(ctl->server.timeout);
1621                         delete_str(&ctl->newsaved, num);
1622                     }
1623                     else if (outlevel > O_SILENT) 
1624                         error_complete(0, 0, " not flushed");
1625
1626                     /* perhaps this as many as we're ready to handle */
1627                     if (ctl->fetchlimit > 0 && ctl->fetchlimit <= fetches)
1628                         goto no_error;
1629                 }
1630             }
1631         }
1632
1633    no_error:
1634         set_timeout(ctl->server.timeout);
1635         ok = gen_transact(sock, protocol->exit_cmd);
1636         if (ok == 0)
1637             ok = (fetches > 0) ? PS_SUCCESS : PS_NOMAIL;
1638         set_timeout(0);
1639         close(sock);
1640         goto closeUp;
1641
1642     cleanUp:
1643         set_timeout(ctl->server.timeout);
1644         if (ok != 0 && ok != PS_SOCKET)
1645             gen_transact(sock, protocol->exit_cmd);
1646         set_timeout(0);
1647         close(sock);
1648     }
1649
1650     msg = (char *)NULL;         /* sacrifice to -Wall */
1651     switch (ok)
1652     {
1653     case PS_SOCKET:
1654         msg = "socket";
1655         break;
1656     case PS_AUTHFAIL:
1657         msg = "authorization";
1658         break;
1659     case PS_SYNTAX:
1660         msg = "missing or bad RFC822 header";
1661         break;
1662     case PS_IOERR:
1663         msg = "MDA";
1664         break;
1665     case PS_ERROR:
1666         msg = "client/server synchronization";
1667         break;
1668     case PS_PROTOCOL:
1669         msg = "client/server protocol";
1670         break;
1671     case PS_SMTP:
1672         msg = "SMTP transaction";
1673         break;
1674     case PS_UNDEFINED:
1675         error(0, 0, "undefined");
1676         break;
1677     }
1678     if (ok==PS_SOCKET || ok==PS_AUTHFAIL || ok==PS_SYNTAX || ok==PS_IOERR
1679                 || ok==PS_ERROR || ok==PS_PROTOCOL || ok==PS_SMTP)
1680         error(0, -1, "%s error while fetching from %s", msg, ctl->server.names->id);
1681
1682 closeUp:
1683     signal(SIGALRM, sigsave);
1684     return(ok);
1685 }
1686
1687 #if defined(HAVE_STDARG_H)
1688 void gen_send(int sock, char *fmt, ... )
1689 /* assemble command in printf(3) style and send to the server */
1690 #else
1691 void gen_send(sock, fmt, va_alist)
1692 /* assemble command in printf(3) style and send to the server */
1693 int sock;               /* socket to which server is connected */
1694 const char *fmt;        /* printf-style format */
1695 va_dcl
1696 #endif
1697 {
1698     char buf [POPBUFSIZE+1];
1699     va_list ap;
1700
1701     if (protocol->tagged)
1702         (void) sprintf(buf, "%s ", GENSYM);
1703     else
1704         buf[0] = '\0';
1705
1706 #if defined(HAVE_STDARG_H)
1707     va_start(ap, fmt) ;
1708 #else
1709     va_start(ap);
1710 #endif
1711     vsprintf(buf + strlen(buf), fmt, ap);
1712     va_end(ap);
1713
1714     strcat(buf, "\r\n");
1715     SockWrite(sock, buf, strlen(buf));
1716
1717     if (outlevel == O_VERBOSE)
1718     {
1719         char *cp;
1720
1721         if (shroud && shroud[0] && (cp = strstr(buf, shroud)))
1722         {
1723             char        *sp;
1724
1725             sp = cp + strlen(shroud);
1726             *cp++ = '*';
1727             while (*sp)
1728                 *cp++ = *sp++;
1729             *cp = '\0';
1730         }
1731         buf[strlen(buf)-2] = '\0';
1732         error(0, 0, "%s> %s", protocol->name, buf);
1733     }
1734 }
1735
1736 int gen_recv(sock, buf, size)
1737 /* get one line of input from the server */
1738 int sock;       /* socket to which server is connected */
1739 char *buf;      /* buffer to receive input */
1740 int size;       /* length of buffer */
1741 {
1742     if (SockRead(sock, buf, size) == -1)
1743         return(PS_SOCKET);
1744     else
1745     {
1746         if (buf[strlen(buf)-1] == '\n')
1747             buf[strlen(buf)-1] = '\0';
1748         if (buf[strlen(buf)-1] == '\r')
1749             buf[strlen(buf)-1] = '\r';
1750         if (outlevel == O_VERBOSE)
1751             error(0, 0, "%s< %s", protocol->name, buf);
1752         return(PS_SUCCESS);
1753     }
1754 }
1755
1756 #if defined(HAVE_STDARG_H)
1757 int gen_transact(int sock, char *fmt, ... )
1758 /* assemble command in printf(3) style, send to server, accept a response */
1759 #else
1760 int gen_transact(int sock, fmt, va_alist)
1761 /* assemble command in printf(3) style, send to server, accept a response */
1762 int sock;               /* socket to which server is connected */
1763 const char *fmt;        /* printf-style format */
1764 va_dcl
1765 #endif
1766 {
1767     int ok;
1768     char buf [POPBUFSIZE+1];
1769     va_list ap;
1770
1771     if (protocol->tagged)
1772         (void) sprintf(buf, "%s ", GENSYM);
1773     else
1774         buf[0] = '\0';
1775
1776 #if defined(HAVE_STDARG_H)
1777     va_start(ap, fmt) ;
1778 #else
1779     va_start(ap);
1780 #endif
1781     vsprintf(buf + strlen(buf), fmt, ap);
1782     va_end(ap);
1783
1784     strcat(buf, "\r\n");
1785     SockWrite(sock, buf, strlen(buf));
1786
1787     if (outlevel == O_VERBOSE)
1788     {
1789         char *cp;
1790
1791         if (shroud && shroud[0] && (cp = strstr(buf, shroud)))
1792         {
1793             char        *sp;
1794
1795             sp = cp + strlen(shroud);
1796             *cp++ = '*';
1797             while (*sp)
1798                 *cp++ = *sp++;
1799             *cp = '\0';
1800         }
1801         buf[strlen(buf)-1] = '\0';
1802         error(0, 0, "%s> %s", protocol->name, buf);
1803     }
1804
1805     /* we presume this does its own response echoing */
1806     ok = (protocol->parse_response)(sock, buf);
1807     set_timeout(mytimeout);
1808
1809     return(ok);
1810 }
1811
1812 /* driver.c ends here */