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