]> Pileus Git - ~andy/fetchmail/blob - driver.c
Detect single quotes in MDA % expansions and refuse delivery.
[~andy/fetchmail] / driver.c
1 /*
2  * driver.c -- generic driver for mail fetch method protocols
3  *
4  * Copyright 1997 by Eric S. Raymond
5  * For license terms, see the file COPYING in this directory.
6  */
7
8 #include  "config.h"
9 #include  <stdio.h>
10 #include  <setjmp.h>
11 #include  <errno.h>
12 #include  <string.h>
13 #include  <stdlib.h>
14 #include  <limits.h>
15 #include <unistd.h>
16 #include  <signal.h>
17 #include <sys/wait.h>
18 #include <sys/time.h>
19
20 #include <sys/socket.h>
21 #include <netdb.h>
22 #ifdef HAVE_PKG_hesiod
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26 #include <hesiod.h>
27 #ifdef __cplusplus
28 }
29 #endif
30 #endif
31
32 #include <langinfo.h>
33
34 #include "kerberos.h"
35
36 #include "gettext.h"
37 #include "socket.h"
38
39 #include "fetchmail.h"
40 #include "getaddrinfo.h"
41 #include "tunable.h"
42
43 #include "sdump.h"
44
45 /* throw types for runtime errors */
46 #define THROW_TIMEOUT   1               /* server timed out */
47
48 /* magic values for the message length array */
49 #define MSGLEN_UNKNOWN  0               /* length unknown (0 is impossible) */
50 #define MSGLEN_INVALID  -1              /* length passed back is invalid */
51 #define MSGLEN_TOOLARGE -2              /* message is too large */
52 #define MSGLEN_OLD      -3              /* message is old */
53
54 int pass;               /* how many times have we re-polled? */
55 int stage;              /* where are we? */
56 int phase;              /* where are we, for error-logging purposes? */
57 int batchcount;         /* count of messages sent in current batch */
58 flag peek_capable;      /* can we peek for better error recovery? */
59 int mailserver_socket_temp = -1;        /* socket to free if connect timeout */ 
60
61 struct addrinfo *ai0, *ai1;     /* clean these up after signal */
62
63 static volatile int timeoutcount = 0;   /* count consecutive timeouts */
64 static volatile int idletimeout = 0;    /* timeout occured in idle stage? */
65
66 static sigjmp_buf       restart;
67
68 int is_idletimeout(void)
69 /* last timeout occured in idle stage? */
70 {
71     return idletimeout;
72 }
73
74 void resetidletimeout(void)
75 {
76     idletimeout = 0;
77 }
78
79 void set_timeout(int timeleft)
80 /* reset the nonresponse-timeout */
81 {
82     struct itimerval ntimeout;
83
84     if (timeleft == 0)
85         timeoutcount = 0;
86
87     ntimeout.it_interval.tv_sec = ntimeout.it_interval.tv_usec = 0;
88     ntimeout.it_value.tv_sec  = timeleft;
89     ntimeout.it_value.tv_usec = 0;
90     setitimer(ITIMER_REAL, &ntimeout, (struct itimerval *)NULL);
91 }
92
93 static void timeout_handler (int signal)
94 /* handle SIGALRM signal indicating a server timeout */
95 {
96     (void)signal;
97     if(stage != STAGE_IDLE) {
98         timeoutcount++;
99         /* XXX FIXME: this siglongjmp must die - it's not safe to be
100          * called from a function handler and breaks, for instance,
101          * getaddrinfo() */
102         siglongjmp(restart, THROW_TIMEOUT);
103     } else
104         idletimeout = 1;
105 }
106
107 #define CLEANUP_TIMEOUT 60 /* maximum timeout during cleanup */
108
109 static int cleanupSockClose (int fd)
110 /* close sockets in maximum CLEANUP_TIMEOUT seconds during cleanup */
111 {
112     int scerror;
113     SIGHANDLERTYPE alrmsave;
114     alrmsave = set_signal_handler(SIGALRM, null_signal_handler);
115     set_timeout(CLEANUP_TIMEOUT);
116     scerror = SockClose(fd);
117     set_timeout(0);
118     set_signal_handler(SIGALRM, alrmsave);
119     return (scerror);
120 }
121
122 #ifdef KERBEROS_V5
123 /** authenticate to the server host using Kerberos V5 */
124 static int kerberos5_auth(int socket /** socket to server host */, const char *canonical /** server name */)
125 {
126     krb5_error_code retval;
127     krb5_context context;
128     krb5_ccache ccdef;
129     krb5_principal client = NULL, server = NULL;
130     krb5_error *err_ret = NULL;
131
132     krb5_auth_context auth_context = NULL;
133
134     krb5_init_context(&context);
135     krb5_auth_con_init(context, &auth_context);
136
137     if ((retval = krb5_cc_default(context, &ccdef))) {
138         report(stderr, "krb5_cc_default: %s\n", error_message(retval));
139         return(PS_ERROR);
140     }
141
142     if ((retval = krb5_cc_get_principal(context, ccdef, &client))) {
143         report(stderr, "krb5_cc_get_principal: %s\n", error_message(retval));
144         return(PS_ERROR);
145     }
146
147     if ((retval = krb5_sname_to_principal(context, canonical, "pop",
148            KRB5_NT_UNKNOWN,
149            &server))) {
150         report(stderr, "krb5_sname_to_principal: %s\n", error_message(retval));
151         return(PS_ERROR);
152     }
153
154     retval = krb5_sendauth(context, &auth_context, (krb5_pointer) &socket,
155          "KPOPV1.0", client, server,
156          AP_OPTS_MUTUAL_REQUIRED,
157          NULL,  /* no data to checksum */
158          0,   /* no creds, use ccache instead */
159          ccdef,
160          &err_ret, 0,
161
162          NULL); /* don't need reply */
163
164     krb5_free_principal(context, server);
165     krb5_free_principal(context, client);
166     krb5_auth_con_free(context, auth_context);
167
168     if (retval) {
169 #ifdef HEIMDAL
170       if (err_ret && err_ret->e_text) {
171           char *t = err_ret->e_text;
172           char *tt = sdump(t, strlen(t));
173           report(stderr, GT_("krb5_sendauth: %s [server says '%s']\n"),
174                  error_message(retval), tt);
175           free(tt);
176 #else
177       if (err_ret && err_ret->text.length) {
178           char *tt = sdump(err_ret->text.data, err_ret->text.length);
179           report(stderr, GT_("krb5_sendauth: %s [server says '%s']\n"),
180                  error_message(retval), tt);
181           free(tt);
182 #endif
183           krb5_free_error(context, err_ret);
184       } else
185           report(stderr, "krb5_sendauth: %s\n", error_message(retval));
186       return(PS_ERROR);
187     }
188
189     return 0;
190 }
191 #endif /* KERBEROS_V5 */
192
193 static void clean_skipped_list(struct idlist **skipped_list)
194 /* struct "idlist" contains no "prev" ptr; we must remove unused items first */
195 {
196     struct idlist *current=NULL, *prev=NULL, *tmp=NULL, *head=NULL;
197     prev = current = head = *skipped_list;
198
199     if (!head)
200         return;
201     do
202     {
203         /* if item has no reference, remove it */
204         if (current && current->val.status.mark == 0)
205         {
206             if (current == head) /* remove first item (head) */
207             {
208                 head = current->next;
209                 if (current->id) free(current->id);
210                 free(current);
211                 prev = current = head;
212             }
213             else /* remove middle/last item */
214             {
215                 tmp = current->next;
216                 prev->next = tmp;
217                 if (current->id) free(current->id);
218                 free(current);
219                 current = tmp;
220             }
221         }
222         else /* skip this item */
223         {
224             prev = current;
225             current = current->next;
226         }
227     } while(current);
228
229     *skipped_list = head;
230 }
231
232 static void send_size_warnings(struct query *ctl)
233 /* send warning mail with skipped msg; reset msg count when user notified */
234 {
235     int size, nbr;
236     int msg_to_send = FALSE;
237     struct idlist *head=NULL, *current=NULL;
238     int max_warning_poll_count;
239
240     head = ctl->skipped;
241     if (!head)
242         return;
243
244     /* don't start a notification message unless we need to */
245     for (current = head; current; current = current->next)
246         if (current->val.status.num == 0 && current->val.status.mark)
247             msg_to_send = TRUE;
248     if (!msg_to_send)
249         return;
250
251     /*
252      * There's no good way to recover if we can't send notification mail, 
253      * but it's not a disaster, either, since the skipped mail will not
254      * be deleted.
255      */
256     if (open_warning_by_mail(ctl))
257         return;
258     stuff_warning(iana_charset, ctl,
259            GT_("Subject: Fetchmail oversized-messages warning"));
260     stuff_warning(NULL, ctl, "%s", "");
261     if (ctl->limitflush)
262         stuff_warning(NULL, ctl,
263                 GT_("The following oversized messages were deleted on server %s account %s:"),
264                 ctl->server.pollname, ctl->remotename);
265     else
266         stuff_warning(NULL, ctl,
267                 GT_("The following oversized messages remain on server %s account %s:"),
268                 ctl->server.pollname, ctl->remotename);
269
270     stuff_warning(NULL, ctl, "%s", "");
271
272     if (run.poll_interval == 0)
273         max_warning_poll_count = 0;
274     else
275         max_warning_poll_count = ctl->warnings/run.poll_interval;
276
277     /* parse list of skipped msg, adding items to the mail */
278     for (current = head; current; current = current->next)
279     {
280         if (current->val.status.num == 0 && current->val.status.mark)
281         {
282             nbr = current->val.status.mark;
283             size = atoi(current->id);
284             if (ctl->limitflush)
285                 stuff_warning(NULL, ctl,
286                         ngettext("  %d message  %d octets long deleted by fetchmail.",
287                                  "  %d messages %d octets long deleted by fetchmail.", nbr),
288                         nbr, size);
289             else
290                 stuff_warning(NULL, ctl,
291                         ngettext("  %d message  %d octets long skipped by fetchmail.",
292                                  "  %d messages %d octets long skipped by fetchmail.", nbr),
293                         nbr, size);
294         }
295         current->val.status.num++;
296         current->val.status.mark = 0;
297
298         if (current->val.status.num >= max_warning_poll_count)
299             current->val.status.num = 0;
300     }
301
302     stuff_warning(NULL, ctl, "%s", "");
303
304     close_warning_by_mail(ctl, (struct msgblk *)NULL);
305 }
306
307 static void mark_oversized(struct query *ctl, int size)
308 /* mark a message oversized */
309 {
310     struct idlist *current=NULL, *tmp=NULL;
311     char sizestr[32];
312     int cnt;
313
314     /* convert size to string */
315     snprintf(sizestr, sizeof(sizestr), "%d", size);
316
317     /* build a list of skipped messages
318      * val.id = size of msg (string cnvt)
319      * val.status.num = warning_poll_count
320      * val.status.mask = nbr of msg this size
321      */
322
323     current = ctl->skipped;
324
325     /* initialise warning_poll_count to the
326      * current value so that all new msg will
327      * be included in the next mail
328      */
329     cnt = current ? current->val.status.num : 0;
330
331     /* if entry exists, increment the count */
332     if (current && (tmp = str_in_list(&current, sizestr, FALSE)))
333     {
334         tmp->val.status.mark++;
335     }
336     /* otherwise, create a new entry */
337     /* initialise with current poll count */
338     else
339     {
340         tmp = save_str(&ctl->skipped, sizestr, 1);
341         tmp->val.status.num = cnt;
342     }
343 }
344
345 static int eat_trailer(int sock, struct query *ctl)
346 {
347     /* we only need this LF if we're printing ticker dots
348      * AND we are dumping protocol traces. */
349     if (outlevel >= O_VERBOSE && want_progress()) fputc('\n', stdout);
350     return (ctl->server.base_protocol->trail)(sock, ctl, tag);
351 }
352
353 static int fetch_messages(int mailserver_socket, struct query *ctl, 
354                           int count, int **msgsizes, int maxfetch,
355                           int *fetches, int *dispatches, int *deletions)
356 /* fetch messages in lockstep mode */
357 {
358     flag force_retrieval;
359     int num, firstnum = 1, lastnum = 0, err, len;
360     int fetchsizelimit = ctl->fetchsizelimit;
361     int msgsize;
362     int initialfetches = *fetches;
363
364     if (ctl->server.base_protocol->getpartialsizes && NUM_NONZERO(fetchsizelimit))
365     {
366         /* for POP3, we can get the size of one mail only! Unfortunately, this
367          * protocol specific test cannot be done elsewhere as the protocol
368          * could be "auto". */
369         switch (ctl->server.protocol)
370         {
371             case P_POP3:
372             fetchsizelimit = 1;
373         }
374
375         /* Time to allocate memory to store the sizes */
376         xfree(*msgsizes);
377         *msgsizes = (int *)xmalloc(sizeof(int) * fetchsizelimit);
378     }
379
380     /*
381      * What forces this code is that in
382      * IMAP2bis you can't fetch a message without
383      * having it marked `seen'.  In POP3 and IMAP4, on the
384      * other hand, you can (peek_capable is set by 
385      * each driver module to convey this; it's not a
386      * method constant because of the difference between
387      * IMAP2bis and IMAP4, and because POP3 doesn't  peek
388      * if fetchall is on).
389      *
390      * The result of being unable to peek is that if there's
391      * any kind of transient error (DNS lookup failure, or
392      * sendmail refusing delivery due to process-table limits)
393      * the message will be marked "seen" on the server without
394      * having been delivered.  This is not a big problem if
395      * fetchmail is running in foreground, because the user
396      * will see a "skipped" message when it next runs and get
397      * clued in.
398      *
399      * But in daemon mode this leads to the message
400      * being silently ignored forever.  This is not
401      * acceptable.
402      *
403      * We compensate for this by checking the error
404      * count from the previous pass and forcing all
405      * messages to be considered new if it's nonzero.
406      */
407     force_retrieval = !peek_capable && (ctl->errcount > 0);
408
409     for (num = 1; num <= count; num++)
410     {
411         flag suppress_delete = FALSE;
412         flag suppress_forward = FALSE;
413         flag suppress_readbody = FALSE;
414         flag retained = FALSE;
415         int msgcode = MSGLEN_UNKNOWN;
416
417         /* check if the message is old
418          * Note: the size of the message may not be known here */
419         if (ctl->fetchall || force_retrieval) {
420             /* empty */
421         } else { 
422             if (ctl->server.base_protocol->is_old && (ctl->server.base_protocol->is_old)(mailserver_socket,ctl,num)) {
423                     msgcode = MSGLEN_OLD;
424             }
425         }
426         if (msgcode == MSGLEN_OLD)
427         {
428             /*
429              * To avoid flooding the logs when using --keep, report
430              * skipping for old messages only when --flush is on.
431              */
432             if (outlevel > O_SILENT && ctl->flush)
433             {
434                 report_build(stdout, 
435                              GT_("skipping message %s@%s:%d"),
436                              ctl->remotename, ctl->server.truename, num);
437             }
438
439             goto flagthemail;
440         }
441
442         if (ctl->server.base_protocol->getpartialsizes && NUM_NONZERO(fetchsizelimit) &&
443             lastnum < num)
444         {
445             /* Instead of getting the sizes of all mails at the start, we get
446              * the sizes in blocks of fetchsizelimit. This leads to better
447              * performance when there are too many mails (say, 10000) in
448              * the mailbox and either we are not getting all the mails at
449              * one go (--fetchlimit 100) or there is a frequent socket
450              * error while just getting the sizes of all mails! */
451
452             int i;
453             int oldstage = stage;
454             firstnum = num;
455             lastnum = num + fetchsizelimit - 1;
456             if (lastnum > count)
457                 lastnum = count;
458             for (i = 0; i < fetchsizelimit; i++)
459                 (*msgsizes)[i] = 0;
460
461             stage = STAGE_GETSIZES;
462             err = (ctl->server.base_protocol->getpartialsizes)(mailserver_socket, num, lastnum, *msgsizes);
463             if (err != 0) {
464                 return err;
465             }
466             stage = oldstage;
467         }
468
469         msgsize = *msgsizes ? (*msgsizes)[num-firstnum] : 0;
470
471         /* check if the message is oversized */
472         if (NUM_NONZERO(ctl->limit) && (msgsize > ctl->limit))
473             msgcode = MSGLEN_TOOLARGE;
474 /*      else if (msgsize == 512)
475             msgcode = MSGLEN_OLD;  (hmh) sample code to skip message */
476
477         if (msgcode < 0)
478         {
479             if (msgcode == MSGLEN_TOOLARGE)
480             {
481                 mark_oversized(ctl, msgsize);
482                 if (!ctl->limitflush)
483                     suppress_delete = TRUE;
484             }
485             if (outlevel > O_SILENT)
486             {
487                 /* old messages are already handled above */
488                 report_build(stdout, 
489                              GT_("skipping message %s@%s:%d (%d octets)"),
490                              ctl->remotename, ctl->server.truename, num,
491                              msgsize);
492                 switch (msgcode)
493                 {
494                 case MSGLEN_INVALID:
495                     /*
496                      * Invalid lengths are produced by Post Office/NT's
497                      * annoying habit of randomly prepending bogus
498                      * LIST items of length -1.  Patrick Audley
499                      * <paudley@pobox.com> tells us: LIST shows a
500                      * size of -1, RETR and TOP return "-ERR
501                      * System error - couldn't open message", and
502                      * DELE succeeds but doesn't actually delete
503                      * the message.
504                      */
505                     report_build(stdout, GT_(" (length -1)"));
506                     break;
507                 case MSGLEN_TOOLARGE:
508                     report_build(stdout, GT_(" (oversized)"));
509                     break;
510                 }
511             }
512         }
513         else
514         {
515           /* XXX FIXME: make this one variable, wholesize and
516              separatefetchbody query the same variable just with
517              inverted logic */
518             flag wholesize = !ctl->server.base_protocol->fetch_body;
519             flag separatefetchbody = (ctl->server.base_protocol->fetch_body) ? TRUE : FALSE;
520
521             /* request a message */
522             err = (ctl->server.base_protocol->fetch_headers)(mailserver_socket,ctl,num, &len);
523             if (err == PS_TRANSIENT)    /* server is probably Exchange */
524             {
525                 report(stdout,
526                              GT_("couldn't fetch headers, message %s@%s:%d (%d octets)\n"),
527                              ctl->remotename, ctl->server.truename, num,
528                              msgsize);
529                 continue;
530             }
531             else if (err != 0)
532                 return(err);
533
534             /* -1 means we didn't see a size in the response */
535             if (len == -1)
536             {
537                 len = msgsize;
538                 wholesize = TRUE;
539             }
540
541             if (outlevel > O_SILENT)
542             {
543                 report_build(stdout, GT_("reading message %s@%s:%d of %d"),
544                              ctl->remotename, ctl->server.truename,
545                              num, count);
546
547                 if (len > 0)
548                     report_build(stdout, wholesize ? GT_(" (%d octets)")
549                                  : GT_(" (%d header octets)"), len);
550                 if (want_progress()) {
551                     /* flush and add a blank to append ticker dots */
552                     report_flush(stdout);
553                     putchar(' ');
554                 }
555             }
556
557             /* 
558              * Read the message headers and ship them to the
559              * output sink.  
560              */
561             err = readheaders(mailserver_socket, len, msgsize,
562                              ctl, num,
563                              /* pass the suppress_readbody flag only if the underlying
564                               * protocol does not fetch the body separately */
565                              separatefetchbody ? 0 : &suppress_readbody);
566
567             if (err == PS_RETAINED)
568                 suppress_forward = suppress_delete = retained = TRUE;
569             else if (err == PS_TRANSIENT)
570                 suppress_delete = suppress_forward = TRUE;
571             else if (err == PS_REFUSED)
572                 suppress_forward = TRUE;
573             else if (err)
574                 return(err);
575
576             /* tell server we got it OK and resynchronize */
577             if (separatefetchbody && ctl->server.base_protocol->trail)
578             {
579                 err = eat_trailer(mailserver_socket, ctl);
580                 if (err) return(err);
581             }
582
583             /* do not read the body which is not being forwarded only if
584              * the underlying protocol allows the body to be fetched
585              * separately */
586             if (separatefetchbody && suppress_forward)
587                 suppress_readbody = TRUE;
588
589             /* 
590              * If we're using IMAP4 or something else that
591              * can fetch headers separately from bodies,
592              * it's time to request the body now.  This
593              * fetch may be skipped if we got an anti-spam
594              * or other PS_REFUSED error response during
595              * readheaders.
596              */
597             if (!suppress_readbody)
598             {
599                 if (separatefetchbody)
600                 {
601                     len = -1;
602                     if ((err=(ctl->server.base_protocol->fetch_body)(mailserver_socket,ctl,num,&len))) {
603                         if (err == PS_ERROR && ctl->server.retrieveerror) {
604                             /*
605                              * Mark a message with a protocol error as seen.
606                              * This can be used to see which messages we've attempted
607                              * to download, but failed.
608                              */
609                             if (ctl->server.retrieveerror == RE_MARKSEEN) {
610                                 if ((ctl->server.base_protocol->mark_seen)(mailserver_socket,ctl,num)) {
611                                     return(err);
612                                 }
613                             }
614
615                             if (ctl->server.retrieveerror != RE_ABORT) {
616                                 /*
617                                  * Do not abort download session.  Continue with the next message.
618                                  *
619                                  * Prevents a malformed message from blocking all other messages
620                                  * behind it in the mailbox from being downloaded.
621                                  *
622                                  * Reconnect to SMTP to force this incomplete message to be dropped.
623                                  * Required because we've already begun the DATA portion of the
624                                  * interaction with the SMTP server (commands are ignored/
625                                  * considered part of the message data).
626                                  */
627                                 abort_message_sink(ctl);
628
629                                 // Ensure we don't delete the failed message from the server.
630                                 suppress_delete = TRUE;
631
632                                 // Bookkeeping required before next message can be downloaded.
633                                 goto flagthemail;
634                             }
635                         }
636
637                         return(err);
638                     }
639
640                     /*
641                      * Work around a bug in Novell's
642                      * broken GroupWise IMAP server;
643                      * its body FETCH response is missing
644                      * the required length for the data
645                      * string.  This violates RFC2060.
646                      */
647                     if (len == -1)
648                         len = msgsize - msgblk.msglen;
649                     if (!wholesize) {
650                         if (outlevel > O_SILENT)
651                             report_build(stdout,
652                                     GT_(" (%d body octets)"), len);
653                         if (want_progress()) {
654                             report_flush(stdout);
655                             putchar(' ');
656                         }
657                     }
658                 }
659
660                 /* process the body now */
661                 err = readbody(mailserver_socket,
662                               ctl,
663                               !suppress_forward,
664                               len);
665
666                 if (err == PS_TRANSIENT)
667                     suppress_delete = suppress_forward = TRUE;
668                 else if (err)
669                     return(err);
670
671                 /* tell server we got it OK and resynchronize */
672                 if (ctl->server.base_protocol->trail) {
673                     err = eat_trailer(mailserver_socket, ctl);
674                     if (err) return(err);
675                 }
676             }
677
678             /* count # messages forwarded on this pass */
679             if (!suppress_forward)
680                 (*dispatches)++;
681
682             /*
683              * Check to see if the numbers matched?
684              *
685              * Yes, some servers foo this up horribly.
686              * All IMAP servers seem to get it right, and
687              * so does Eudora QPOP at least in 2.xx
688              * versions.
689              *
690              * Microsoft Exchange gets it completely
691              * wrong, reporting compressed rather than
692              * actual sizes (so the actual length of
693              * message is longer than the reported size).
694              * Another fine example of Microsoft brain death!
695              *
696              * Some older POP servers, like the old UCB
697              * POP server and the pre-QPOP QUALCOMM
698              * versions, report a longer size in the LIST
699              * response than actually gets shipped up.
700              * It's unclear what is going on here, as the
701              * QUALCOMM server (at least) seems to be
702              * reporting the on-disk size correctly.
703              *
704              * qmail-pop3d also goofs up message sizes and does not
705              * count the line end characters properly.
706              */
707             if (msgblk.msglen != msgsize)
708             {
709                 if (outlevel >= O_DEBUG)
710                     report(stdout,
711                            GT_("message %s@%s:%d was not the expected length (%d actual != %d expected)\n"),
712                            ctl->remotename, ctl->server.truename, num,
713                            msgblk.msglen, msgsize);
714             }
715
716             /* end-of-message processing starts here */
717             if (!close_sink(ctl, &msgblk, !suppress_forward))
718             {
719                 ctl->errcount++;
720                 suppress_delete = TRUE;
721             }
722             if (!retained)
723                 (*fetches)++;
724         }
725
726 flagthemail:
727         /*
728          * At this point in flow of control,
729          * either we've bombed on a protocol error
730          * or had delivery refused by the SMTP server
731          * or we've seen `accepted for delivery' and the message is shipped.
732          * It's safe to mark the message seen and delete it on the server now.
733          */
734
735         /* in softbounce mode, suppress deletion and marking as seen */
736         if (suppress_forward)
737             suppress_delete = suppress_delete || run.softbounce;
738
739         /* maybe we delete this message now? */
740         if (retained)
741         {
742             if (outlevel > O_SILENT) 
743                 report_complete(stdout, GT_(" retained\n"));
744         }
745         else if (ctl->server.base_protocol->delete_msg
746                  && !suppress_delete
747                  && ((msgcode >= 0 && !ctl->keep)
748                      || (msgcode == MSGLEN_OLD && ctl->flush)
749                      || (msgcode == MSGLEN_TOOLARGE && ctl->limitflush)))
750         {
751             (*deletions)++;
752             if (outlevel > O_SILENT) 
753                 report_complete(stdout, GT_(" flushed\n"));
754             err = (ctl->server.base_protocol->delete_msg)(mailserver_socket, ctl, num);
755             if (err != 0)
756                 return(err);
757         }
758         else
759         {
760             /*
761              * To avoid flooding the logs when using --keep, report
762              * skipping of new messages only.
763              */
764             if (outlevel > O_SILENT && msgcode != MSGLEN_OLD)
765             report_complete(stdout, GT_(" not flushed\n"));
766
767             /* maybe we mark this message as seen now? */
768             if (ctl->server.base_protocol->mark_seen
769                 && !suppress_delete
770                 && (msgcode >= 0 && ctl->keep))
771             {
772                 err = (ctl->server.base_protocol->mark_seen)(mailserver_socket, ctl, num);
773                 if (err != 0)
774                     return(err);
775             }
776         }
777
778         /* perhaps this as many as we're ready to handle */
779         if (maxfetch && maxfetch <= *fetches && num < count)
780         {
781             int remcount = count - (*fetches - initialfetches);
782             report(stdout,
783                    ngettext("fetchlimit %d reached; %d message left on server %s account %s\n",
784                             "fetchlimit %d reached; %d messages left on server %s account %s\n", remcount),
785                    maxfetch, remcount, ctl->server.truename, ctl->remotename);
786             return(PS_MAXFETCH);
787         }
788     } /* for (num = 1; num <= count; num++) */
789
790     return(PS_SUCCESS);
791 }
792
793 /* retrieve messages from server using given protocol method table */
794 static int do_session(
795         /* parsed options with merged-in defaults */
796         struct query *ctl,
797         /* protocol method table */
798         const struct method *proto,
799         /* maximum number of messages to fetch */
800         const int maxfetch)
801 {
802     static int *msgsizes;
803     volatile int err, mailserver_socket = -1;   /* pacifies -Wall */
804     int tmperr;
805     int deletions = 0, js;
806     const char *msg;
807     SIGHANDLERTYPE alrmsave;
808
809     ctl->server.base_protocol = proto;
810
811     msgsizes = NULL;
812     pass = 0;
813     err = 0;
814     init_transact(proto);
815
816     /* set up the server-nonresponse timeout */
817     alrmsave = set_signal_handler(SIGALRM, timeout_handler);
818     mytimeout = ctl->server.timeout;
819
820     if ((js = sigsetjmp(restart,1)))
821     {
822         /* exception caught */
823         sigset_t        allsigs;
824
825         sigfillset(&allsigs);
826         sigprocmask(SIG_UNBLOCK, &allsigs, NULL);
827
828         if (ai0) {
829             fm_freeaddrinfo(ai0); ai0 = NULL;
830         }
831
832         if (ai1) {
833             fm_freeaddrinfo(ai1); ai1 = NULL;
834         }
835         
836         if (js == THROW_TIMEOUT)
837         {
838             if (phase == OPEN_WAIT)
839                 report(stdout,
840                        GT_("timeout after %d seconds waiting to connect to server %s.\n"),
841                        ctl->server.timeout, ctl->server.pollname);
842             else if (phase == SERVER_WAIT)
843                 report(stdout,
844                        GT_("timeout after %d seconds waiting for server %s.\n"),
845                        ctl->server.timeout, ctl->server.pollname);
846             else if (phase == FORWARDING_WAIT)
847                 report(stdout,
848                        GT_("timeout after %d seconds waiting for %s.\n"),
849                        ctl->server.timeout,
850                        ctl->mda ? "MDA" : "SMTP");
851             else if (phase == LISTENER_WAIT)
852                 report(stdout,
853                        GT_("timeout after %d seconds waiting for listener to respond.\n"), ctl->server.timeout);
854             else
855                 report(stdout, 
856                        GT_("timeout after %d seconds.\n"), ctl->server.timeout);
857
858             /*
859              * If we've exceeded our threshold for consecutive timeouts, 
860              * try to notify the user, then mark the connection wedged.
861              * Don't do this if the connection can idle, though; idle
862              * timeouts just mean the frequency of mail is low.
863              */
864             if (timeoutcount > MAX_TIMEOUTS 
865                 && !open_warning_by_mail(ctl))
866             {
867                 stuff_warning(iana_charset, ctl,
868                               GT_("Subject: fetchmail sees repeated timeouts"));
869                 stuff_warning(NULL, ctl, "%s", "");
870                 stuff_warning(NULL, ctl,
871                               GT_("Fetchmail saw more than %d timeouts while attempting to get mail from %s@%s.\n"), 
872                               MAX_TIMEOUTS,
873                               ctl->remotename, ctl->server.truename);
874                 stuff_warning(NULL, ctl, 
875     GT_("This could mean that your mailserver is stuck, or that your SMTP\n" \
876     "server is wedged, or that your mailbox file on the server has been\n" \
877     "corrupted by a server error.  You can run `fetchmail -v -v' to\n" \
878     "diagnose the problem.\n\n" \
879     "Fetchmail won't poll this mailbox again until you restart it.\n"));
880                 close_warning_by_mail(ctl, (struct msgblk *)NULL);
881                 ctl->wedged = TRUE;
882             }
883         }
884
885         err = PS_SOCKET;
886         goto cleanUp;
887     }
888     else
889     {
890         /* sigsetjmp returned zero -> normal operation */
891         char buf[MSGBUFSIZE+1], *realhost;
892         int count, newm, bytes;
893         int fetches, dispatches, oldphase;
894         struct idlist *idp;
895
896         /* execute pre-initialization command, if any */
897         if (ctl->preconnect && (err = system(ctl->preconnect)))
898         {
899             if (WIFSIGNALED(err))
900                 report(stderr,
901                         GT_("pre-connection command terminated with signal %d\n"), WTERMSIG(err));
902             else
903                 report(stderr,
904                         GT_("pre-connection command failed with status %d\n"), WEXITSTATUS(err));
905             err = PS_SYNTAX;
906             goto closeUp;
907         }
908
909         /* open a socket to the mail server */
910         oldphase = phase;
911         phase = OPEN_WAIT;
912         set_timeout(mytimeout);
913
914 #ifdef HAVE_PKG_hesiod
915         /* If either the pollname or vianame are "hesiod" we want to
916            lookup the user's hesiod pobox host */
917         if (!strcasecmp(ctl->server.queryname, "hesiod")) {
918             struct hes_postoffice *hes_p;
919             hes_p = hes_getmailhost(ctl->remotename);
920             if (hes_p != NULL && strcmp(hes_p->po_type, "POP") == 0) {
921                  free(ctl->server.queryname);
922                  ctl->server.queryname = xstrdup(hes_p->po_host);
923                  if (ctl->server.via)
924                      free(ctl->server.via);
925                  ctl->server.via = xstrdup(hes_p->po_host);
926             } else {
927                  report(stderr,
928                         GT_("couldn't find HESIOD pobox for %s\n"),
929                         ctl->remotename);
930             }
931         }
932 #endif /* HESIOD */
933
934         /*
935          * Canonicalize the server truename for later use.  This also
936          * functions as a probe for whether the mailserver is accessible.
937          * We try it on each poll cycle until we get a result.  This way,
938          * fetchmail won't fail if started up when the network is inaccessible.
939          */
940         if (ctl->server.dns && !ctl->server.trueaddr)
941         {
942             if (ctl->server.lead_server)
943             {
944                 char    *leadname = ctl->server.lead_server->truename;
945
946                 /* prevent core dump from ill-formed or duplicate entry */
947                 if (!leadname)
948                 {
949                     report(stderr, GT_("Lead server has no name.\n"));
950                     err = PS_DNS;
951                     set_timeout(0);
952                     phase = oldphase;
953                     goto closeUp;
954                 }
955
956                 xfree(ctl->server.truename);
957                 ctl->server.truename = xstrdup(leadname);
958             }
959             else
960             {
961                 struct addrinfo hints, *res;
962                 int error;
963
964                 memset(&hints, 0, sizeof(hints));
965                 hints.ai_socktype = SOCK_STREAM;
966                 hints.ai_family = AF_UNSPEC;
967                 hints.ai_flags = AI_CANONNAME;
968 #ifdef AI_ADDRCONFIG
969                 hints.ai_flags |= AI_ADDRCONFIG;
970 #endif
971
972                 error = fm_getaddrinfo(ctl->server.queryname, NULL, &hints, &res);
973                 if (error)
974                 {
975                     report(stderr,
976                            GT_("couldn't find canonical DNS name of %s (%s): %s\n"),
977                            ctl->server.pollname, ctl->server.queryname,
978                            gai_strerror(error));
979                     err = PS_DNS;
980                     set_timeout(0);
981                     phase = oldphase;
982                     goto closeUp;
983                 }
984                 else
985                 {
986                     xfree(ctl->server.truename);
987                     /* Older FreeBSD versions return NULL in ai_canonname
988                      * if they cannot canonicalize, rather than copying
989                      * the queryname here, as IEEE Std 1003.1-2001
990                      * requires. Work around NULL. */
991                     if (res->ai_canonname != NULL) {
992                         ctl->server.truename = xstrdup(res->ai_canonname);
993                     } else {
994                         ctl->server.truename = xstrdup(ctl->server.queryname);
995                     }
996                     ctl->server.trueaddr = (struct sockaddr *)xmalloc(res->ai_addrlen);
997                     ctl->server.trueaddr_len = res->ai_addrlen;
998                     memcpy(ctl->server.trueaddr, res->ai_addr, res->ai_addrlen);
999                     fm_freeaddrinfo(res);
1000                 }
1001             }
1002         }
1003
1004         realhost = ctl->server.via ? ctl->server.via : ctl->server.pollname;
1005
1006         /* allow time for the port to be set up if we have a plugin */
1007         if (ctl->server.plugin)
1008             (void)sleep(1);
1009         if ((mailserver_socket = SockOpen(realhost, 
1010                              ctl->server.service ? ctl->server.service : ( ctl->use_ssl ? ctl->server.base_protocol->sslservice : ctl->server.base_protocol->service ),
1011                              ctl->server.plugin, &ai0)) == -1)
1012         {
1013             char        errbuf[BUFSIZ];
1014             int err_no = errno;
1015             /*
1016              * Avoid generating a bogus error every poll cycle when we're
1017              * in daemon mode but the connection to the outside world
1018              * is down.
1019              */
1020             if (!((err_no == EHOSTUNREACH || err_no == ENETUNREACH) 
1021                   && run.poll_interval))
1022             {
1023                 report_build(stderr, GT_("%s connection to %s failed"), 
1024                              ctl->server.base_protocol->name, ctl->server.pollname);
1025                     strlcpy(errbuf, strerror(err_no), sizeof(errbuf));
1026                 report_complete(stderr, ": %s\n", errbuf);
1027             }
1028             err = PS_SOCKET;
1029             set_timeout(0);
1030             phase = oldphase;
1031             goto closeUp;
1032         }
1033
1034 #ifdef SSL_ENABLE
1035         /* Save the socket opened. Useful if Fetchmail hangs on SSLOpen 
1036          * because the socket can be closed.
1037          */
1038         mailserver_socket_temp = mailserver_socket;
1039         set_timeout(mytimeout);
1040
1041         /* perform initial SSL handshake on open connection */
1042         if (ctl->use_ssl &&
1043                 SSLOpen(mailserver_socket, ctl->sslcert, ctl->sslkey,
1044                     ctl->sslproto, ctl->sslcertck,
1045                     ctl->sslcertfile, ctl->sslcertpath,
1046                     ctl->sslfingerprint, ctl->sslcommonname ?
1047                     ctl->sslcommonname : realhost, ctl->server.pollname,
1048                     &ctl->remotename) == -1)
1049         {
1050             set_timeout(0);
1051             report(stderr, GT_("SSL connection failed.\n"));
1052             err = PS_SOCKET;
1053             goto cleanUp;
1054         }
1055         
1056         /* Fetchmail didn't hang on SSLOpen, 
1057          * then no need to set mailserver_socket_temp 
1058          */
1059         mailserver_socket_temp = -1;
1060 #endif
1061         
1062         /* A timeout is still defined before SSLOpen, 
1063          * then Fetchmail hanging on SSLOpen is handled.
1064          */
1065         set_timeout(0);
1066         phase = oldphase;
1067
1068 #ifdef KERBEROS_V5
1069         if (ctl->server.authenticate == A_KERBEROS_V5)
1070         {
1071             set_timeout(mytimeout);
1072             err = kerberos5_auth(mailserver_socket, ctl->server.truename);
1073             set_timeout(0);
1074             if (err != 0)
1075                 goto cleanUp;
1076         }
1077 #endif /* KERBEROS_V5 */
1078
1079         /* accept greeting message from mail server */
1080         err = (ctl->server.base_protocol->parse_response)(mailserver_socket, buf);
1081         if (err != 0)
1082             goto cleanUp;
1083
1084         /* try to get authorized to fetch mail */
1085         stage = STAGE_GETAUTH;
1086         if (ctl->server.base_protocol->getauth)
1087         {
1088             set_timeout(mytimeout);
1089             err = (ctl->server.base_protocol->getauth)(mailserver_socket, ctl, buf);
1090             set_timeout(0);
1091
1092             if (err != 0)
1093             {
1094                 if (err == PS_LOCKBUSY)
1095                     report(stderr, GT_("Lock-busy error on %s@%s\n"),
1096                           ctl->remotename,
1097                           ctl->server.truename);
1098                 else if (err == PS_SERVBUSY)
1099                     report(stderr, GT_("Server busy error on %s@%s\n"),
1100                           ctl->remotename,
1101                           ctl->server.truename);
1102                 else if (err == PS_AUTHFAIL)
1103                 {
1104                     report(stderr, GT_("Authorization failure on %s@%s%s\n"), 
1105                            ctl->remotename,
1106                            ctl->server.truename,
1107                            (ctl->wehaveauthed ? GT_(" (previously authorized)") : "")
1108                         );
1109                     if (ctl->server.authenticate == A_ANY && !ctl->wehaveauthed) {
1110                         report(stderr, GT_("For help, see http://www.fetchmail.info/fetchmail-FAQ.html#R15\n"));
1111                     }
1112
1113                     /*
1114                      * If we're running in background, try to mail the
1115                      * calling user a heads-up about the authentication 
1116                      * failure once it looks like this isn't a fluke 
1117                      * due to the server being temporarily inaccessible.
1118                      * When we get third succesive failure, we notify the user
1119                      * but only if we haven't already managed to get
1120                      * authorization.  After that, once we get authorization
1121                      * we let the user know service is restored.
1122                      */
1123                     if (run.poll_interval
1124                         && !ctl->wehavesentauthnote
1125                         && ((ctl->wehaveauthed && ++ctl->authfailcount >= 10)
1126                             || (!ctl->wehaveauthed && ++ctl->authfailcount >= 3))
1127                         && !open_warning_by_mail(ctl))
1128                     {
1129                         ctl->wehavesentauthnote = 1;
1130                         stuff_warning(iana_charset, ctl,
1131                                       GT_("Subject: fetchmail authentication failed on %s@%s"),
1132                             ctl->remotename, ctl->server.truename);
1133                         stuff_warning(NULL, ctl, "%s", "");
1134                         stuff_warning(NULL, ctl,
1135                                       GT_("Fetchmail could not get mail from %s@%s.\n"), 
1136                                       ctl->remotename,
1137                                       ctl->server.truename);
1138                         if (ctl->wehaveauthed) {
1139                             stuff_warning(NULL, ctl, GT_("\
1140 The attempt to get authorization failed.\n\
1141 Since we have already succeeded in getting authorization for this\n\
1142 connection, this is probably another failure mode (such as busy server)\n\
1143 that fetchmail cannot distinguish because the server didn't send a useful\n\
1144 error message."));
1145                             stuff_warning(NULL, ctl, GT_("\
1146 \n\
1147 However, if you HAVE changed your account details since starting the\n\
1148 fetchmail daemon, you need to stop the daemon, change your configuration\n\
1149 of fetchmail, and then restart the daemon.\n\
1150 \n\
1151 The fetchmail daemon will continue running and attempt to connect\n\
1152 at each cycle.  No future notifications will be sent until service\n\
1153 is restored."));
1154                         } else {
1155                             stuff_warning(NULL, ctl, GT_("\
1156 The attempt to get authorization failed.\n\
1157 This probably means your password is invalid, but some servers have\n\
1158 other failure modes that fetchmail cannot distinguish from this\n\
1159 because they don't send useful error messages on login failure.\n\
1160 \n\
1161 The fetchmail daemon will continue running and attempt to connect\n\
1162 at each cycle.  No future notifications will be sent until service\n\
1163 is restored."));
1164                         }
1165                         close_warning_by_mail(ctl, (struct msgblk *)NULL);
1166                     }
1167                 }
1168                 else if (err == PS_REPOLL)
1169                 {
1170                   if (outlevel >= O_VERBOSE)
1171                     report(stderr, GT_("Repoll immediately on %s@%s\n"),
1172                            ctl->remotename,
1173                            ctl->server.truename);
1174                 }
1175                 else
1176                     report(stderr, GT_("Unknown login or authentication error on %s@%s\n"),
1177                            ctl->remotename,
1178                            ctl->server.truename);
1179                     
1180                 goto cleanUp;
1181             }
1182             else
1183             {
1184                 /*
1185                  * This connection has given us authorization at least once.
1186                  *
1187                  * There are dodgy server (clubinternet.fr for example) that
1188                  * give spurious authorization failures on patently good
1189                  * account/password details, then 5 minutes later let you in!
1190                  *
1191                  * This is meant to build in some tolerance of such nasty bits
1192                  * of work.
1193                  */
1194                 ctl->wehaveauthed = 1;
1195                 /*if (ctl->authfailcount >= 3)*/
1196                 if (ctl->wehavesentauthnote)
1197                 {
1198                     ctl->wehavesentauthnote = 0;
1199                     report(stderr,
1200                            GT_("Authorization OK on %s@%s\n"),
1201                            ctl->remotename,
1202                            ctl->server.truename);
1203                     if (!open_warning_by_mail(ctl))
1204                     {
1205                         stuff_warning(iana_charset, ctl,
1206                               GT_("Subject: fetchmail authentication OK on %s@%s"), 
1207                                       ctl->remotename, ctl->server.truename);
1208                         stuff_warning(NULL, ctl, "%s", "");
1209                         stuff_warning(NULL, ctl,
1210                               GT_("Fetchmail was able to log into %s@%s.\n"), 
1211                                       ctl->remotename,
1212                                       ctl->server.truename);
1213                         stuff_warning(NULL, ctl, 
1214                                       GT_("Service has been restored.\n"));
1215                         close_warning_by_mail(ctl, (struct msgblk *)NULL);
1216                     
1217                     }
1218                 }
1219                 /*
1220                  * Reporting only after the first three
1221                  * consecutive failures, or ten consecutive
1222                  * failures after we have managed to get
1223                  * authorization.
1224                  */
1225                 ctl->authfailcount = 0;
1226             }
1227         }
1228
1229         ctl->errcount = fetches = 0;
1230
1231         /* now iterate over each folder selected */
1232         for (idp = ctl->mailboxes; idp; idp = idp->next)
1233         {
1234             ctl->folder = idp->id;
1235             pass = 0;
1236             do {
1237                 dispatches = 0;
1238                 ++pass;
1239
1240                 /* reset timeout, in case we did an IDLE */
1241                 mytimeout = ctl->server.timeout;
1242
1243                 if (outlevel >= O_DEBUG)
1244                 {
1245                     if (idp->id)
1246                         report(stdout, GT_("selecting or re-polling folder %s\n"), idp->id);
1247                     else
1248                         report(stdout, GT_("selecting or re-polling default folder\n"));
1249                 }
1250
1251                 /* compute # of messages and number of new messages waiting */
1252                 stage = STAGE_GETRANGE;
1253                 err = (ctl->server.base_protocol->getrange)(mailserver_socket, ctl, idp->id, &count, &newm, &bytes);
1254                 if (err != 0)
1255                     goto cleanUp;
1256
1257                 /* show user how many messages we downloaded */
1258                 if (idp->id)
1259                     (void) snprintf(buf, sizeof(buf),
1260                                    GT_("%s at %s (folder %s)"),
1261                                    ctl->remotename, ctl->server.pollname, idp->id);
1262                 else
1263                     (void) snprintf(buf, sizeof(buf), GT_("%s at %s"),
1264                                    ctl->remotename, ctl->server.pollname);
1265                 if (outlevel > O_SILENT)
1266                 {
1267                     if (count == -1)            /* only used for ETRN */
1268                         report(stdout, GT_("Polling %s\n"), ctl->server.truename);
1269                     else if (count != 0)
1270                     {
1271                         if (newm != -1 && (count - newm) > 0)
1272                             report_build(stdout, ngettext("%d message (%d %s) for %s", "%d messages (%d %s) for %s", (unsigned long)count),
1273                                   count,
1274                                   count - newm, 
1275                                   ngettext("seen", "seen", (unsigned long)count-newm),
1276                                   buf);
1277                         else
1278                             report_build(stdout, ngettext("%d message for %s",
1279                                                           "%d messages for %s",
1280                                                           count), 
1281                                   count, buf);
1282                         if (bytes == -1)
1283                             report_complete(stdout, ".\n");
1284                         else
1285                             report_complete(stdout, GT_(" (%d octets).\n"), bytes);
1286                     }
1287                     else
1288                     {
1289                         /* these are pointless in normal daemon mode */
1290                         if (pass == 1 && (run.poll_interval == 0 || outlevel >= O_VERBOSE))
1291                             report(stdout, GT_("No mail for %s\n"), buf); 
1292                     }
1293                 }
1294
1295                 /* very important, this is where we leave the do loop */ 
1296                 if (count == 0)
1297                     break;
1298
1299                 if (check_only)
1300                 {
1301                     if (newm == -1 || ctl->fetchall)
1302                         newm = count;
1303                     fetches = newm;     /* set error status correctly */
1304                     /*
1305                      * There used to be a `goto noerror' here, but this
1306                      * prevented checking of multiple folders.  This
1307                      * comment is a reminder in case I introduced some
1308                      * subtle bug by removing it...
1309                      */
1310                 }
1311                 else if (count > 0)
1312                 {    
1313                     int         i;
1314
1315                     /*
1316                      * Don't trust the message count passed by the server.
1317                      * Without this check, it might be possible to do a
1318                      * DNS-spoofing attack that would pass back a ridiculous 
1319                      * count, and allocate a malloc area that would overlap
1320                      * a portion of the stack.
1321                      */
1322                     if ((unsigned)count > INT_MAX/sizeof(int))
1323                     {
1324                         report(stderr, GT_("bogus message count!"));
1325                         err = PS_PROTOCOL;
1326                         goto cleanUp;
1327                     }
1328
1329                     /* 
1330                      * We need the size of each message before it's
1331                      * loaded in order to pass it to the ESMTP SIZE
1332                      * option.  If the protocol has a getsizes method,
1333                      * we presume this means it doesn't get reliable
1334                      * sizes from message fetch responses.
1335                      *
1336                      * If the protocol supports getting sizes of subset of
1337                      * messages, we skip this step now.
1338                      */
1339                     if (proto->getsizes &&
1340                         !(proto->getpartialsizes && NUM_NONZERO(ctl->fetchsizelimit)))
1341                     {
1342                         xfree(msgsizes);
1343                         msgsizes = (int *)xmalloc(sizeof(int) * count);
1344                         for (i = 0; i < count; i++)
1345                             msgsizes[i] = 0;
1346
1347                         stage = STAGE_GETSIZES;
1348                         err = (proto->getsizes)(mailserver_socket, count, msgsizes);
1349                         if (err != 0)
1350                             goto cleanUp;
1351
1352                         if (bytes == -1)
1353                         {
1354                             bytes = 0;
1355                             for (i = 0; i < count; i++)
1356                                 bytes += msgsizes[i];
1357                         }
1358                     }
1359
1360                     /* read, forward, and delete messages */
1361                     stage = STAGE_FETCH;
1362
1363                     /* fetch in lockstep mode */
1364                     err = fetch_messages(mailserver_socket, ctl, 
1365                                          count, &msgsizes,
1366                                          maxfetch,
1367                                          &fetches, &dispatches, &deletions);
1368                     if (err != PS_SUCCESS && err != PS_MAXFETCH)
1369                         goto cleanUp;
1370
1371                     if (!check_only && ctl->skipped
1372                         && run.poll_interval > 0 && !nodetach)
1373                     {
1374                         clean_skipped_list(&ctl->skipped);
1375                         send_size_warnings(ctl);
1376                     }
1377                 }
1378
1379                 /* end-of-mailbox processing before we repoll or switch to another one */
1380                 if (ctl->server.base_protocol->end_mailbox_poll)
1381                 {
1382                     tmperr = (ctl->server.base_protocol->end_mailbox_poll)(mailserver_socket, ctl);
1383                     if (tmperr) {
1384                         err = tmperr;
1385                         goto cleanUp;
1386                     }
1387                 }
1388                 /* Return now if we have reached the fetchlimit */
1389                 if (maxfetch && maxfetch <= fetches)
1390                     goto no_error;
1391             } while
1392                   /*
1393                    * Only repoll if we either had some actual forwards
1394                    * or are idling for new mails and had no errors.
1395                    * Otherwise it is far too easy to get into infinite loops.
1396                    */
1397                   (ctl->server.base_protocol->retry && (dispatches || ctl->idle) && !ctl->errcount);
1398         }
1399
1400         /* XXX: From this point onwards, preserve err unless a new error has occurred */
1401
1402     no_error:
1403         /* PS_SUCCESS, PS_MAXFETCH: ordinary termination with no errors -- officially log out */
1404         stage = STAGE_LOGOUT;
1405         tmperr = (ctl->server.base_protocol->logout_cmd)(mailserver_socket, ctl);
1406         if (tmperr != PS_SUCCESS)
1407             err = tmperr;
1408         /*
1409          * Hmmmm...arguably this would be incorrect if we had fetches but
1410          * no dispatches (due to oversized messages, etc.)
1411          */
1412         else if (err == PS_SUCCESS && fetches == 0)
1413             err = PS_NOMAIL;
1414         /*
1415          * Close all SMTP delivery sockets.  For optimum performance
1416          * we'd like to hold them open til end of run, but (1) this
1417          * loses if our poll interval is longer than the MTA's
1418          * inactivity timeout, and (2) some MTAs (like smail) don't
1419          * deliver after each message, but rather queue up mail and
1420          * wait to actually deliver it until the input socket is
1421          * closed.
1422          *
1423          * don't send QUIT for ODMR case because we're acting as a
1424          * proxy between the SMTP server and client.
1425          */
1426         smtp_close(ctl, ctl->server.protocol != P_ODMR);
1427         cleanupSockClose(mailserver_socket);
1428         goto closeUp;
1429
1430     cleanUp:
1431         /* we only get here on error */
1432         if (err != 0 && err != PS_SOCKET && err != PS_REPOLL)
1433         {
1434             stage = STAGE_LOGOUT;
1435             (ctl->server.base_protocol->logout_cmd)(mailserver_socket, ctl);
1436         }
1437
1438         /* try to clean up all streams */
1439         release_sink(ctl);
1440         /*
1441          * Sending SMTP QUIT on signal is theoretically nice, but led
1442          * to a subtle bug.  If fetchmail was terminated by signal
1443          * while it was shipping message text, it would hang forever
1444          * waiting for a command acknowledge.  In theory we could
1445          * enable the QUIT only outside of the message send.  In
1446          * practice, we don't care.  All mailservers hang up on a
1447          * dropped TCP/IP connection anyway.
1448          */
1449         smtp_close(ctl, 0);
1450         if (mailserver_socket != -1) {
1451             cleanupSockClose(mailserver_socket);
1452         }
1453         /* If there was a connect timeout, the socket should be closed.
1454          * mailserver_socket_temp contains the socket to close.
1455          */
1456         if (mailserver_socket_temp != -1) {
1457             cleanupSockClose(mailserver_socket_temp);
1458             mailserver_socket_temp = -1;
1459         }
1460     }
1461
1462     /* no report on PS_AUTHFAIL */
1463     msg = NULL;
1464     switch (err)
1465     {
1466     case PS_SOCKET:
1467         msg = GT_("socket");
1468         break;
1469     case PS_SYNTAX:
1470         msg = GT_("missing or bad RFC822 header or command line option");
1471         break;
1472     case PS_IOERR:
1473         msg = GT_("MDA");
1474         break;
1475     case PS_ERROR:
1476         msg = GT_("client/server synchronization");
1477         break;
1478     case PS_PROTOCOL:
1479         msg = GT_("client/server protocol");
1480         break;
1481     case PS_LOCKBUSY:
1482         msg = GT_("lock busy on server");
1483         break;
1484     case PS_SMTP:
1485         msg = GT_("SMTP transaction");
1486         break;
1487     case PS_DNS:
1488         msg = GT_("DNS lookup");
1489         break;
1490     case PS_UNDEFINED:
1491         msg = GT_("undefined");
1492         break;
1493     }
1494     if (msg) {
1495         if (phase == FORWARDING_WAIT || phase == LISTENER_WAIT
1496                 || err == PS_SMTP)
1497             report(stderr, GT_("%s error while fetching from %s@%s and delivering to SMTP host %s\n"),
1498                     msg, ctl->remotename, ctl->server.pollname,
1499                     ctl->smtphost ? ctl->smtphost : GT_("unknown"));
1500         else
1501             report(stderr, GT_("%s error while fetching from %s@%s\n"),
1502                     msg, ctl->remotename, ctl->server.pollname);
1503     }
1504
1505 closeUp:
1506     xfree(msgsizes);
1507     ctl->folder = NULL;
1508
1509     /* execute wrapup command, if any */
1510     if (ctl->postconnect && (tmperr = system(ctl->postconnect)))
1511     {
1512         if (WIFSIGNALED(tmperr))
1513             report(stderr, GT_("post-connection command terminated with signal %d\n"), WTERMSIG(tmperr));
1514         else
1515             report(stderr, GT_("post-connection command failed with status %d\n"), WEXITSTATUS(tmperr));
1516         if (err == PS_SUCCESS)
1517             err = PS_SYNTAX;
1518     }
1519
1520     set_timeout(0); /* cancel any pending alarm */
1521     set_signal_handler(SIGALRM, alrmsave);
1522     return(err);
1523 }
1524
1525 /** retrieve messages from server using given protocol method table */
1526 int do_protocol(struct query *ctl /** parsed options with merged-in defaults */,
1527                 const struct method *proto /** protocol method table */)
1528 {
1529     int err;
1530
1531 #ifndef KERBEROS_V5
1532     if (ctl->server.authenticate == A_KERBEROS_V5)
1533     {
1534         report(stderr, GT_("Kerberos V5 support not linked.\n"));
1535         return(PS_ERROR);
1536     }
1537 #endif /* KERBEROS_V5 */
1538
1539     /* lacking methods, there are some options that may fail */
1540     if (!proto->is_old)
1541     {
1542         /* check for unsupported options */
1543         if (ctl->flush) {
1544             report(stderr,
1545                     GT_("Option --flush is not supported with %s\n"),
1546                     proto->name);
1547             return(PS_SYNTAX);
1548         }
1549         else if (ctl->fetchall) {
1550             report(stderr,
1551                     GT_("Option --all is not supported with %s\n"),
1552                     proto->name);
1553             return(PS_SYNTAX);
1554         }
1555     }
1556     if (!(proto->getsizes || proto->getpartialsizes)
1557             && NUM_SPECIFIED(ctl->limit))
1558     {
1559         report(stderr,
1560                 GT_("Option --limit is not supported with %s\n"),
1561                 proto->name);
1562         return(PS_SYNTAX);
1563     }
1564
1565     /*
1566      * If no expunge limit or we do expunges within the driver,
1567      * then just do one session, passing in any fetchlimit.
1568      */
1569     if ((ctl->keep && !ctl->flush) ||
1570         proto->retry || !NUM_SPECIFIED(ctl->expunge))
1571         return(do_session(ctl, proto, NUM_VALUE_OUT(ctl->fetchlimit)));
1572     /*
1573      * There's an expunge limit, and it isn't handled in the driver itself.
1574      * OK; do multiple sessions, each fetching a limited # of messages.
1575      * Stop if the total count of retrieved messages exceeds ctl->fetchlimit
1576      * (if it was nonzero).
1577      */
1578     else
1579     {
1580         int totalcount = 0; 
1581         int lockouts   = 0;
1582         int expunge    = NUM_VALUE_OUT(ctl->expunge);
1583         int fetchlimit = NUM_VALUE_OUT(ctl->fetchlimit);
1584
1585         do {
1586             if (fetchlimit > 0 && (expunge == 0 || expunge > fetchlimit - totalcount))
1587                 expunge = fetchlimit - totalcount;
1588             err = do_session(ctl, proto, expunge);
1589             totalcount += expunge;
1590             if (NUM_SPECIFIED(ctl->fetchlimit) && totalcount >= fetchlimit)
1591                 break;
1592             if (err != PS_LOCKBUSY)
1593                 lockouts = 0;
1594             else if (lockouts >= MAX_LOCKOUTS)
1595                 break;
1596             else /* err == PS_LOCKBUSY */
1597             {
1598                 /*
1599                  * Allow time for the server lock to release.  if we
1600                  * don't do this, we'll often hit a locked-mailbox
1601                  * condition and fail.
1602                  */
1603                 lockouts++;
1604                 sleep(3);
1605             }
1606         } while
1607             (err == PS_MAXFETCH || err == PS_LOCKBUSY);
1608
1609         return(err);
1610     }
1611 }
1612
1613
1614 /* driver.c ends here */