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