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