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