]> Pileus Git - ~andy/fetchmail/blob - driver.c
Whitespace cleanup.
[~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 #ifdef HAVE_MEMORY_H
14 #include  <memory.h>
15 #endif /* HAVE_MEMORY_H */
16 #if defined(STDC_HEADERS)
17 #include  <stdlib.h>
18 #endif
19 #if defined(HAVE_UNISTD_H)
20 #include <unistd.h>
21 #endif
22 #if defined(HAVE_SYS_ITIMER_H)
23 #include <sys/itimer.h>
24 #endif
25 #include  <sys/time.h>
26 #include  <signal.h>
27
28 #ifdef HAVE_NET_SOCKET_H
29 #include <net/socket.h>
30 #endif
31
32 #ifdef HAVE_RES_SEARCH
33 #include <netdb.h>
34 #include "mx.h"
35 #endif /* HAVE_RES_SEARCH */
36
37 #include "kerberos.h"
38 #ifdef KERBEROS_V4
39 #include <netinet/in.h>
40 #endif /* KERBEROS_V4 */
41
42 #include "i18n.h"
43
44 #include "fetchmail.h"
45 #include "tunable.h"
46
47 /* throw types for runtime errors */
48 #define THROW_TIMEOUT   1               /* server timed out */
49 #define THROW_SIGPIPE   2               /* SIGPIPE on stream socket */
50
51 static int timeoutcount;                /* count consecutive timeouts */
52
53 static jmp_buf  restart;
54
55 void set_timeout(int timeleft)
56 /* reset the nonresponse-timeout */
57 {
58 #if !defined(__EMX__) && !defined(__BEOS__) 
59     struct itimerval ntimeout;
60
61     if (timeleft == 0)
62         timeoutcount = 0;
63
64     ntimeout.it_interval.tv_sec = ntimeout.it_interval.tv_usec = 0;
65     ntimeout.it_value.tv_sec  = timeleft;
66     ntimeout.it_value.tv_usec = 0;
67     setitimer(ITIMER_REAL, &ntimeout, (struct itimerval *)NULL);
68 #endif
69 }
70
71 static void timeout_handler (int signal)
72 /* handle SIGALRM signal indicating a server timeout */
73 {
74     timeoutcount++;
75     longjmp(restart, THROW_TIMEOUT);
76 }
77
78 static void sigpipe_handler (int signal)
79 /* handle SIGPIPE signal indicating a broken stream socket */
80 {
81     longjmp(restart, THROW_SIGPIPE);
82 }
83
84 #ifdef KERBEROS_V4
85 static int kerberos_auth(socket, canonical, principal) 
86 /* authenticate to the server host using Kerberos V4 */
87 int socket;             /* socket to server host */
88 char *canonical;        /* server name */
89 char *principal;
90 {
91     char * host_primary;
92     KTEXT ticket;
93     MSG_DAT msg_data;
94     CREDENTIALS cred;
95     Key_schedule schedule;
96     int rem;
97     char * prin_copy = (char *) NULL;
98     char * prin = (char *) NULL;
99     char * inst = (char *) NULL;
100     char * realm = (char *) NULL;
101
102     if (principal != (char *)NULL && *principal)
103     {
104         char *cp;
105         prin = prin_copy = xstrdup(principal);
106         for (cp = prin_copy; *cp && *cp != '.'; ++cp)
107             ;
108         if (*cp)
109         {
110             *cp++ = '\0';
111             inst = cp;
112             while (*cp && *cp != '@')
113                 ++cp;
114             if (*cp)
115             {
116                 *cp++ = '\0';
117                 realm = cp;
118             }
119         }
120     }
121   
122     xalloca(ticket, KTEXT, sizeof (KTEXT_ST));
123     rem = (krb_sendauth (0L, socket, ticket,
124                          prin ? prin : "pop",
125                          inst ? inst : canonical,
126                          realm ? realm : ((char *) (krb_realmofhost (canonical))),
127                          ((unsigned long) 0),
128                          (&msg_data),
129                          (&cred),
130                          (schedule),
131                          ((struct sockaddr_in *) 0),
132                          ((struct sockaddr_in *) 0),
133                          "KPOPV0.1"));
134     if (prin_copy)
135     {
136         free(prin_copy);
137     }
138     if (rem != KSUCCESS)
139     {
140         report(stderr, _("kerberos error %s\n"), (krb_get_err_text (rem)));
141         return (PS_AUTHFAIL);
142     }
143     return (0);
144 }
145 #endif /* KERBEROS_V4 */
146
147 #ifdef KERBEROS_V5
148 static int kerberos5_auth(socket, canonical)
149 /* authenticate to the server host using Kerberos V5 */
150 int socket;             /* socket to server host */
151 const char *canonical;  /* server name */
152 {
153     krb5_error_code retval;
154     krb5_context context;
155     krb5_ccache ccdef;
156     krb5_principal client = NULL, server = NULL;
157     krb5_error *err_ret = NULL;
158
159     krb5_auth_context auth_context = NULL;
160
161     krb5_init_context(&context);
162     krb5_init_ets(context);
163     krb5_auth_con_init(context, &auth_context);
164
165     if (retval = krb5_cc_default(context, &ccdef)) {
166         report(stderr, "krb5_cc_default: %s\n", error_message(retval));
167         return(PS_ERROR);
168     }
169
170     if (retval = krb5_cc_get_principal(context, ccdef, &client)) {
171         report(stderr, "krb5_cc_get_principal: %s\n", error_message(retval));
172         return(PS_ERROR);
173     }
174
175     if (retval = krb5_sname_to_principal(context, canonical, "pop",
176            KRB5_NT_UNKNOWN,
177            &server)) {
178         report(stderr, "krb5_sname_to_principal: %s\n", error_message(retval));
179         return(PS_ERROR);
180     }
181
182     retval = krb5_sendauth(context, &auth_context, (krb5_pointer) &socket,
183          "KPOPV1.0", client, server,
184          AP_OPTS_MUTUAL_REQUIRED,
185          NULL,  /* no data to checksum */
186          0,   /* no creds, use ccache instead */
187          ccdef,
188          &err_ret, 0,
189
190          NULL); /* don't need reply */
191
192     krb5_free_principal(context, server);
193     krb5_free_principal(context, client);
194     krb5_auth_con_free(context, auth_context);
195
196     if (retval) {
197 #ifdef HEIMDAL
198       if (err_ret && err_ret->e_text) {
199           report(stderr, _("krb5_sendauth: %s [server says '%*s'] \n"),
200                  error_message(retval),
201                  err_ret->e_text);
202 #else
203       if (err_ret && err_ret->text.length) {
204           report(stderr, _("krb5_sendauth: %s [server says '%*s'] \n"),
205                  error_message(retval),
206                  err_ret->text.length,
207                  err_ret->text.data);
208 #endif
209           krb5_free_error(context, err_ret);
210       } else
211           report(stderr, "krb5_sendauth: %s\n", error_message(retval));
212       return(PS_ERROR);
213     }
214
215     return 0;
216 }
217 #endif /* KERBEROS_V5 */
218
219 static void clean_skipped_list(struct idlist **skipped_list)
220 /* struct "idlist" contains no "prev" ptr; we must remove unused items first */
221 {
222     struct idlist *current=NULL, *prev=NULL, *tmp=NULL, *head=NULL;
223     prev = current = head = *skipped_list;
224
225     if (!head)
226         return;
227     do
228     {
229         /* if item has no reference, remove it */
230         if (current && current->val.status.mark == 0)
231         {
232             if (current == head) /* remove first item (head) */
233             {
234                 head = current->next;
235                 if (current->id) free(current->id);
236                 free(current);
237                 prev = current = head;
238             }
239             else /* remove middle/last item */
240             {
241                 tmp = current->next;
242                 prev->next = tmp;
243                 if (current->id) free(current->id);
244                 free(current);
245                 current = tmp;
246             }
247         }
248         else /* skip this item */
249         {
250             prev = current;
251             current = current->next;
252         }
253     } while(current);
254
255     *skipped_list = head;
256 }
257
258 static void send_size_warnings(struct query *ctl)
259 /* send warning mail with skipped msg; reset msg count when user notified */
260 {
261     int size, nbr;
262     int msg_to_send = FALSE;
263     struct idlist *head=NULL, *current=NULL;
264     int max_warning_poll_count;
265
266     head = ctl->skipped;
267     if (!head)
268         return;
269
270     /* don't start a notification message unless we need to */
271     for (current = head; current; current = current->next)
272         if (current->val.status.num == 0 && current->val.status.mark)
273             msg_to_send = TRUE;
274     if (!msg_to_send)
275         return;
276
277     /*
278      * There's no good way to recover if we can't send notification mail, 
279      * but it's not a disaster, either, since the skipped mail will not
280      * be deleted.
281      */
282     if (open_warning_by_mail(ctl, (struct msgblk *)NULL))
283         return;
284     stuff_warning(ctl,
285            _("Subject: Fetchmail oversized-messages warning.\r\n"
286              "\r\n"
287              "The following oversized messages remain on the mail server %s:"),
288                   ctl->server.pollname);
289  
290     if (run.poll_interval == 0)
291         max_warning_poll_count = 0;
292     else
293         max_warning_poll_count = ctl->warnings/run.poll_interval;
294
295     /* parse list of skipped msg, adding items to the mail */
296     for (current = head; current; current = current->next)
297     {
298         if (current->val.status.num == 0 && current->val.status.mark)
299         {
300             nbr = current->val.status.mark;
301             size = atoi(current->id);
302             stuff_warning(ctl, 
303                     _("\t%d msg %d octets long skipped by fetchmail.\r\n"),
304                     nbr, size);
305         }
306         current->val.status.num++;
307         current->val.status.mark = 0;
308
309         if (current->val.status.num >= max_warning_poll_count)
310             current->val.status.num = 0;
311     }
312
313     close_warning_by_mail(ctl, (struct msgblk *)NULL);
314 }
315
316 static int fetch_messages(int mailserver_socket, struct query *ctl, 
317                           int count, int *msgsizes, 
318                           int new, int force, int maxfetch,
319                           int *fetches, int *dispatches, int *deletions)
320 /* fetch messages in lockstep mode */
321 {
322     int num, ok, len;
323     struct idlist *current=NULL, *tmp=NULL;
324
325     for (num = 1; num <= count; num++)
326     {
327         flag toolarge = NUM_NONZERO(ctl->limit)
328             && msgsizes && (msgsizes[num-1] > ctl->limit);
329         flag oldmsg = (!new) || (ctl->server.base_protocol->is_old && (ctl->server.base_protocol->is_old)(mailserver_socket,ctl,num));
330         flag fetch_it = !toolarge 
331             && (ctl->fetchall || force || !oldmsg);
332         flag suppress_delete = FALSE;
333         flag suppress_forward = FALSE;
334         flag suppress_readbody = FALSE;
335         flag retained = FALSE;
336
337         /*
338          * This check copes with Post Office/NT's
339          * annoying habit of randomly prepending bogus
340          * LIST items of length -1.  Patrick Audley
341          * <paudley@pobox.com> tells us: LIST shows a
342          * size of -1, RETR and TOP return "-ERR
343          * System error - couldn't open message", and
344          * DELE succeeds but doesn't actually delete
345          * the message.
346          */
347         if (msgsizes && msgsizes[num-1] == -1)
348         {
349             if (outlevel >= O_VERBOSE)
350                 report(stdout, 
351                        _("Skipping message %d, length -1\n"),
352                        num);
353             continue;
354         }
355
356         /*
357          * We may want to reject this message if it's old
358          * or oversized, and we're not forcing retrieval.
359          */
360         if (!fetch_it)
361         {
362             if (outlevel > O_SILENT)
363             {
364                 report_build(stdout, 
365                              _("skipping message %d (%d octets)"),
366                              num, msgsizes[num-1]);
367                 if (toolarge && !check_only) 
368                 {
369                     char size[32];
370                     int cnt;
371
372                     /* convert sz to string */
373                     sprintf(size, "%d", msgsizes[num-1]);
374
375                     /* build a list of skipped messages
376                      * val.id = size of msg (string cnvt)
377                      * val.status.num = warning_poll_count
378                      * val.status.mask = nbr of msg this size
379                      */
380
381                     current = ctl->skipped;
382
383                     /* initialise warning_poll_count to the
384                      * current value so that all new msg will
385                      * be included in the next mail
386                      */
387                     cnt = current ? current->val.status.num : 0;
388
389                     /* if entry exists, increment the count */
390                     if (current && 
391                         str_in_list(&current, size, FALSE))
392                     {
393                         for ( ; current; 
394                               current = current->next)
395                         {
396                             if (strcmp(current->id, size) == 0)
397                             {
398                                 current->val.status.mark++;
399                                 break;
400                             }
401                         }
402                     }
403                     /* otherwise, create a new entry */
404                     /* initialise with current poll count */
405                     else
406                     {
407                         tmp = save_str(&ctl->skipped, size, 1);
408                         tmp->val.status.num = cnt;
409                     }
410
411                     report_build(stdout, _(" (oversized, %d octets)"),
412                                  msgsizes[num-1]);
413                 }
414             }
415         }
416         else
417         {
418             flag wholesize = !ctl->server.base_protocol->fetch_body;
419
420             /* request a message */
421             ok = (ctl->server.base_protocol->fetch_headers)(mailserver_socket,ctl,num, &len);
422             if (ok != 0)
423                 return(FALSE);
424
425             /* -1 means we didn't see a size in the response */
426             if (len == -1 && msgsizes)
427             {
428                 len = msgsizes[num - 1];
429                 wholesize = TRUE;
430             }
431
432             if (outlevel > O_SILENT)
433             {
434                 report_build(stdout, _("reading message %d of %d"),
435                              num,count);
436
437                 if (len > 0)
438                     report_build(stdout, _(" (%d %soctets)"),
439                                  len, wholesize ? "" : _("header "));
440                 if (outlevel >= O_VERBOSE)
441                     report_complete(stdout, "\n");
442                 else
443                     report_complete(stdout, " ");
444             }
445
446             /* 
447              * Read the message headers and ship them to the
448              * output sink.  
449              */
450             ok = readheaders(mailserver_socket, len, msgsizes[num-1],
451                              ctl, num);
452             if (ok == PS_RETAINED)
453                 suppress_forward = retained = TRUE;
454             else if (ok == PS_TRANSIENT)
455                 suppress_delete = suppress_forward = TRUE;
456             else if (ok == PS_REFUSED)
457                 suppress_forward = TRUE;
458             else if (ok == PS_TRUNCATED)
459                 suppress_readbody = TRUE;
460             else if (ok)
461                 return(FALSE);
462
463             /* 
464              * If we're using IMAP4 or something else that
465              * can fetch headers separately from bodies,
466              * it's time to request the body now.  This
467              * fetch may be skipped if we got an anti-spam
468              * or other PS_REFUSED error response during
469              * readheaders.
470              */
471             if (ctl->server.base_protocol->fetch_body && !suppress_readbody) 
472             {
473                 if (outlevel >= O_VERBOSE && !isafile(1))
474                 {
475                     fputc('\n', stdout);
476                     fflush(stdout);
477                 }
478
479                 if ((ok = (ctl->server.base_protocol->trail)(mailserver_socket, ctl, num)))
480                     return(FALSE);
481                 len = 0;
482                 if (!suppress_forward)
483                 {
484                     if ((ok=(ctl->server.base_protocol->fetch_body)(mailserver_socket,ctl,num,&len)))
485                         return(FALSE);
486                     /*
487                      * Work around a bug in Novell's
488                      * broken GroupWise IMAP server;
489                      * its body FETCH response is missing
490                      * the required length for the data
491                      * string.  This violates RFC2060.
492                      */
493                     if (len == -1)
494                         len = msgsizes[num-1] - msgblk.msglen;
495                     if (outlevel > O_SILENT && !wholesize)
496                         report_complete(stdout,
497                                         _(" (%d body octets) "), len);
498                 }
499             }
500
501             /* process the body now */
502             if (len > 0)
503             {
504                 if (suppress_readbody)
505                 {
506                     /* When readheaders returns PS_TRUNCATED,
507                        the body (which has no content
508                        has already been read by readheaders,
509                        so we say readbody returned PS_SUCCESS */
510                     ok = PS_SUCCESS;
511                 }
512                 else
513                 {
514                     ok = readbody(mailserver_socket,
515                                   ctl,
516                                   !suppress_forward,
517                                   len);
518                 }
519                 if (ok == PS_TRANSIENT)
520                     suppress_delete = suppress_forward = TRUE;
521                 else if (ok)
522                     return(FALSE);
523
524                 /* tell server we got it OK and resynchronize */
525                 if (ctl->server.base_protocol->trail)
526                 {
527                     if (outlevel >= O_VERBOSE && !isafile(1))
528                     {
529                         fputc('\n', stdout);
530                         fflush(stdout);
531                     }
532
533                     ok = (ctl->server.base_protocol->trail)(mailserver_socket, ctl, num);
534                     if (ok != 0)
535                         return(FALSE);
536                 }
537             }
538
539             /* count # messages forwarded on this pass */
540             if (!suppress_forward)
541                 (*dispatches)++;
542
543             /*
544              * Check to see if the numbers matched?
545              *
546              * Yes, some servers foo this up horribly.
547              * All IMAP servers seem to get it right, and
548              * so does Eudora QPOP at least in 2.xx
549              * versions.
550              *
551              * Microsoft Exchange gets it completely
552              * wrong, reporting compressed rather than
553              * actual sizes (so the actual length of
554              * message is longer than the reported size).
555              * Another fine example of Microsoft brain death!
556              *
557              * Some older POP servers, like the old UCB
558              * POP server and the pre-QPOP QUALCOMM
559              * versions, report a longer size in the LIST
560              * response than actually gets shipped up.
561              * It's unclear what is going on here, as the
562              * QUALCOMM server (at least) seems to be
563              * reporting the on-disk size correctly.
564              */
565             if (msgsizes && msgblk.msglen != msgsizes[num-1])
566             {
567                 if (outlevel >= O_DEBUG)
568                     report(stdout,
569                            _("message %d was not the expected length (%d actual != %d expected)\n"),
570                            num, msgblk.msglen, msgsizes[num-1]);
571             }
572
573             /* end-of-message processing starts here */
574             if (!close_sink(ctl, &msgblk, !suppress_forward))
575             {
576                 ctl->errcount++;
577                 suppress_delete = TRUE;
578             }
579             (*fetches)++;
580         }
581
582         /*
583          * At this point in flow of control, either
584          * we've bombed on a protocol error or had
585          * delivery refused by the SMTP server
586          * (unlikely -- I've never seen it) or we've
587          * seen `accepted for delivery' and the
588          * message is shipped.  It's safe to mark the
589          * message seen and delete it on the server
590          * now.
591          */
592
593         /* tell the UID code we've seen this */
594         if (ctl->newsaved)
595         {
596             struct idlist       *sdp;
597
598             for (sdp = ctl->newsaved; sdp; sdp = sdp->next)
599                 if ((sdp->val.status.num == num) && (!toolarge || oldmsg)) 
600                 {
601                     sdp->val.status.mark = UID_SEEN;
602                     save_str(&ctl->oldsaved, sdp->id,UID_SEEN);
603                 }
604         }
605
606         /* maybe we delete this message now? */
607         if (retained)
608         {
609             if (outlevel > O_SILENT) 
610                 report(stdout, _(" retained\n"));
611         }
612         else if (ctl->server.base_protocol->delete
613                  && !suppress_delete
614                  && (fetch_it ? !ctl->keep : ctl->flush))
615         {
616             (*deletions)++;
617             if (outlevel > O_SILENT) 
618                 report_complete(stdout, _(" flushed\n"));
619             ok = (ctl->server.base_protocol->delete)(mailserver_socket, ctl, num);
620             if (ok != 0)
621                 return(FALSE);
622 #ifdef POP3_ENABLE
623             delete_str(&ctl->newsaved, num);
624 #endif /* POP3_ENABLE */
625         }
626         else if (outlevel > O_SILENT) 
627             report_complete(stdout, _(" not flushed\n"));
628
629         /* perhaps this as many as we're ready to handle */
630         if (maxfetch && maxfetch <= *fetches && *fetches < count)
631         {
632             report(stdout, _("fetchlimit %d reached; %d messages left on server\n"),
633                    maxfetch, count - *fetches);
634             ok = PS_MAXFETCH;
635             return(FALSE);
636         }
637     }
638
639     return(TRUE);
640 }
641
642 static int do_session(ctl, proto, maxfetch)
643 /* retrieve messages from server using given protocol method table */
644 struct query *ctl;              /* parsed options with merged-in defaults */
645 const struct method *proto;     /* protocol method table */
646 const int maxfetch;             /* maximum number of messages to fetch */
647 {
648     int js;
649 #ifdef HAVE_VOLATILE
650     volatile int ok, mailserver_socket = -1;    /* pacifies -Wall */
651 #else
652     int ok, mailserver_socket = -1;
653 #endif /* HAVE_VOLATILE */
654     const char *msg;
655     void (*pipesave)(int);
656     void (*alrmsave)(int);
657
658     ctl->server.base_protocol = proto;
659
660     pass = 0;
661     ok = 0;
662     init_transact(proto);
663
664     /* set up the server-nonresponse timeout */
665     alrmsave = signal(SIGALRM, timeout_handler);
666     mytimeout = ctl->server.timeout;
667
668     /* set up the broken-pipe timeout */
669     pipesave = signal(SIGPIPE, sigpipe_handler);
670
671     if ((js = setjmp(restart)))
672     {
673 #ifdef HAVE_SIGPROCMASK
674         /*
675          * Don't rely on setjmp() to restore the blocked-signal mask.
676          * It does this under BSD but is required not to under POSIX.
677          *
678          * If your Unix doesn't have sigprocmask, better hope it has
679          * BSD-like behavior.  Otherwise you may see fetchmail get
680          * permanently wedged after a second timeout on a bad read,
681          * because alarm signals were blocked after the first.
682          */
683         sigset_t        allsigs;
684
685         sigfillset(&allsigs);
686         sigprocmask(SIG_UNBLOCK, &allsigs, NULL);
687 #endif /* HAVE_SIGPROCMASK */
688
689         if (js == THROW_SIGPIPE)
690         {
691             signal(SIGPIPE, SIG_IGN);
692             report(stdout,
693                    _("SIGPIPE thrown from an MDA or a stream socket error\n"));
694             ok = PS_SOCKET;
695             goto cleanUp;
696         }
697         else if (js == THROW_TIMEOUT)
698         {
699             if (phase == OPEN_WAIT)
700                 report(stdout,
701                        _("timeout after %d seconds waiting to connect to server %s.\n"),
702                        ctl->server.timeout, ctl->server.pollname);
703             else if (phase == SERVER_WAIT)
704                 report(stdout,
705                        _("timeout after %d seconds waiting for server %s.\n"),
706                        ctl->server.timeout, ctl->server.pollname);
707             else if (phase == FORWARDING_WAIT)
708                 report(stdout,
709                        _("timeout after %d seconds waiting for %s.\n"),
710                        ctl->server.timeout,
711                        ctl->mda ? "MDA" : "SMTP");
712             else if (phase == LISTENER_WAIT)
713                 report(stdout,
714                        _("timeout after %d seconds waiting for listener to respond.\n"), ctl->server.timeout);
715             else
716                 report(stdout, 
717                        _("timeout after %d seconds.\n"), ctl->server.timeout);
718
719             /*
720              * If we've exceeded our threshold for consecutive timeouts, 
721              * try to notify the user, then mark the connection wedged.
722              * Don't do this if the connection can idle, though; idle
723              * timeouts just mean the frequency of mail is low.
724              */
725             if (timeoutcount > MAX_TIMEOUTS 
726                 && !open_warning_by_mail(ctl, (struct msgblk *)NULL))
727             {
728                 stuff_warning(ctl,
729                               _("Subject: fetchmail sees repeated timeouts\r\n"));
730                 stuff_warning(ctl,
731                               _("Fetchmail saw more than %d timeouts while attempting to get mail from %s@%s.\r\n"), 
732                               MAX_TIMEOUTS,
733                               ctl->remotename,
734                               ctl->server.truename);
735                 stuff_warning(ctl, 
736     _("This could mean that your mailserver is stuck, or that your SMTP\r\n" \
737     "server is wedged, or that your mailbox file on the server has been\r\n" \
738     "corrupted by a server error.  You can run `fetchmail -v -v' to\r\n" \
739     "diagnose the problem.\r\n\r\n" \
740     "Fetchmail won't poll this mailbox again until you restart it.\r\n"));
741                 close_warning_by_mail(ctl, (struct msgblk *)NULL);
742                 ctl->wedged = TRUE;
743             }
744
745             ok = PS_ERROR;
746         }
747
748         /* try to clean up all streams */
749         release_sink(ctl);
750         if (ctl->smtp_socket != -1)
751             SockClose(ctl->smtp_socket);
752         if (mailserver_socket != -1)
753             SockClose(mailserver_socket);
754     }
755     else
756     {
757         char buf[MSGBUFSIZE+1], *realhost;
758         int count, new, bytes, deletions = 0, *msgsizes = NULL;
759 #if INET6_ENABLE
760         int fetches, dispatches, oldphase;
761 #else /* INET6_ENABLE */
762         int port, fetches, dispatches, oldphase;
763 #endif /* INET6_ENABLE */
764         struct idlist *idp;
765
766         /* execute pre-initialization command, if any */
767         if (ctl->preconnect && (ok = system(ctl->preconnect)))
768         {
769             report(stderr, 
770                    _("pre-connection command failed with status %d\n"), ok);
771             ok = PS_SYNTAX;
772             goto closeUp;
773         }
774
775         /* open a socket to the mail server */
776         oldphase = phase;
777         phase = OPEN_WAIT;
778         set_timeout(mytimeout);
779 #if !INET6_ENABLE
780 #ifdef SSL_ENABLE
781         port = ctl->server.port ? ctl->server.port : ( ctl->use_ssl ? ctl->server.base_protocol->sslport : ctl->server.base_protocol->port );
782 #else
783         port = ctl->server.port ? ctl->server.port : ctl->server.base_protocol->port;
784 #endif
785 #endif /* !INET6_ENABLE */
786         realhost = ctl->server.via ? ctl->server.via : ctl->server.pollname;
787
788         /* allow time for the port to be set up if we have a plugin */
789         if (ctl->server.plugin)
790             (void)sleep(1);
791 #if INET6_ENABLE
792         if ((mailserver_socket = SockOpen(realhost, 
793                              ctl->server.service ? ctl->server.service : ( ctl->use_ssl ? ctl->server.base_protocol->sslservice : ctl->server.base_protocol->service ),
794                              ctl->server.netsec, ctl->server.plugin)) == -1)
795 #else /* INET6_ENABLE */
796         if ((mailserver_socket = SockOpen(realhost, port, NULL, ctl->server.plugin)) == -1)
797 #endif /* INET6_ENABLE */
798         {
799             char        errbuf[BUFSIZ];
800 #if !INET6_ENABLE
801             int err_no = errno;
802 #ifdef HAVE_RES_SEARCH
803             if (err_no != 0 && h_errno != 0)
804                 report(stderr, _("internal inconsistency\n"));
805 #endif
806             /*
807              * Avoid generating a bogus error every poll cycle when we're
808              * in daemon mode but the connection to the outside world
809              * is down.
810              */
811             if (!((err_no == EHOSTUNREACH || err_no == ENETUNREACH) 
812                   && run.poll_interval))
813             {
814                 report_build(stderr, _("%s connection to %s failed"), 
815                              ctl->server.base_protocol->name, ctl->server.pollname);
816 #ifdef HAVE_RES_SEARCH
817                 if (h_errno != 0)
818                 {
819                     if (h_errno == HOST_NOT_FOUND)
820                         strcpy(errbuf, _("host is unknown."));
821 #ifndef __BEOS__
822                     else if (h_errno == NO_ADDRESS)
823                         strcpy(errbuf, _("name is valid but has no IP address."));
824 #endif
825                     else if (h_errno == NO_RECOVERY)
826                         strcpy(errbuf, _("unrecoverable name server error."));
827                     else if (h_errno == TRY_AGAIN)
828                         strcpy(errbuf, _("temporary name server error."));
829                     else
830                         sprintf(errbuf, _("unknown DNS error %d."), h_errno);
831                 }
832                 else
833 #endif /* HAVE_RES_SEARCH */
834                     strcpy(errbuf, strerror(err_no));
835                 report_complete(stderr, ": %s\n", errbuf);
836
837 #ifdef __UNUSED
838                 /* 
839                  * Don't use this.  It was an attempt to address Debian bug
840                  * #47143 (Notify user by mail when pop server nonexistent).
841                  * Trouble is, that doesn't work; you trip over the case 
842                  * where your SLIP or PPP link is down...
843                  */
844                 /* warn the system administrator */
845                 if (open_warning_by_mail(ctl, (struct msgblk *)NULL) == 0)
846                 {
847                     stuff_warning(ctl,
848                          _("Subject: Fetchmail unreachable-server warning.\r\n"
849                            "\r\n"
850                            "Fetchmail could not reach the mail server %s:")
851                                   ctl->server.pollname);
852                     stuff_warning(ctl, errbuf, ctl->server.pollname);
853                     close_warning_by_mail(ctl, (struct msgblk *)NULL);
854                 }
855 #endif
856             }
857 #endif /* INET6_ENABLE */
858             ok = PS_SOCKET;
859             set_timeout(0);
860             phase = oldphase;
861             goto closeUp;
862         }
863         set_timeout(0);
864         phase = oldphase;
865
866 #ifdef SSL_ENABLE
867         /* perform initial SSL handshake on open connection */
868         /* Note:  We pass the realhost name over for certificate
869                 verification.  We may want to make this configurable */
870         if (ctl->use_ssl && SSLOpen(mailserver_socket,ctl->sslkey,ctl->sslcert,ctl->sslproto,ctl->sslcertck,
871             ctl->sslcertpath,ctl->sslfingerprint,realhost,ctl->server.pollname) == -1) 
872         {
873             report(stderr, _("SSL connection failed.\n"));
874             goto closeUp;
875         }
876 #endif
877
878 #ifdef KERBEROS_V4
879         if (ctl->server.authenticate == A_KERBEROS_V4)
880         {
881             set_timeout(mytimeout);
882             ok = kerberos_auth(mailserver_socket, ctl->server.truename,
883                                ctl->server.principal);
884             set_timeout(0);
885             if (ok != 0)
886                 goto cleanUp;
887         }
888 #endif /* KERBEROS_V4 */
889
890 #ifdef KERBEROS_V5
891         if (ctl->server.authenticate == A_KERBEROS_V5)
892         {
893             set_timeout(mytimeout);
894             ok = kerberos5_auth(mailserver_socket, ctl->server.truename);
895             set_timeout(0);
896             if (ok != 0)
897                 goto cleanUp;
898         }
899 #endif /* KERBEROS_V5 */
900
901         /* accept greeting message from mail server */
902         ok = (ctl->server.base_protocol->parse_response)(mailserver_socket, buf);
903         if (ok != 0)
904             goto cleanUp;
905
906         /* try to get authorized to fetch mail */
907         stage = STAGE_GETAUTH;
908         if (ctl->server.base_protocol->getauth)
909         {
910             ok = (ctl->server.base_protocol->getauth)(mailserver_socket, ctl, buf);
911
912             if (ok != 0)
913             {
914                 if (ok == PS_LOCKBUSY)
915                     report(stderr, _("Lock-busy error on %s@%s\n"),
916                           ctl->remotename,
917                           ctl->server.truename);
918                 else if (ok == PS_SERVBUSY)
919                     report(stderr, _("Server busy error on %s@%s\n"),
920                           ctl->remotename,
921                           ctl->server.truename);
922                 else if (ok == PS_AUTHFAIL)
923                 {
924                     report(stderr, _("Authorization failure on %s@%s%s\n"), 
925                            ctl->remotename,
926                            ctl->server.truename,
927                            (ctl->wehaveauthed ? _(" (previously authorized)") : "")
928                         );
929
930                     /*
931                      * If we're running in background, try to mail the
932                      * calling user a heads-up about the authentication 
933                      * failure once it looks like this isn't a fluke 
934                      * due to the server being temporarily inaccessible.
935                      * When we get third succesive failure, we notify the user
936                      * but only if we haven't already managed to get
937                      * authorization.  After that, once we get authorization
938                      * we let the user know service is restored.
939                      */
940                     if (run.poll_interval
941                         && ctl->wehavesentauthnote
942                         && ((ctl->wehaveauthed && ++ctl->authfailcount == 10)
943                             || ++ctl->authfailcount == 3)
944                         && !open_warning_by_mail(ctl, (struct msgblk *)NULL))
945                     {
946                         ctl->wehavesentauthnote = 1;
947                         stuff_warning(ctl,
948                                       _("Subject: fetchmail authentication failed on %s@%s\r\n"),
949                             ctl->remotename, ctl->server.truename);
950                         stuff_warning(ctl,
951                                       _("Fetchmail could not get mail from %s@%s.\r\n"), 
952                                       ctl->remotename,
953                                       ctl->server.truename);
954                         if (ctl->wehaveauthed)
955                             stuff_warning(ctl, _("\
956 The attempt to get authorization failed.\r\n\
957 Since we have already succeeded in getting authorization for this\r\n\
958 connection, this is probably another failure mode (such as busy server)\r\n\
959 that fetchmail cannot distinguish because the server didn't send a useful\r\n\
960 error message.\r\n\
961 \r\n\
962 However, if you HAVE changed you account details since starting the\r\n\
963 fetchmail daemon, you need to stop the daemon, change your configuration\r\n\
964 of fetchmail, and then restart the daemon.\r\n\
965 \r\n\
966 The fetchmail daemon will continue running and attempt to connect\r\n\
967 at each cycle.  No future notifications will be sent until service\r\n\
968 is restored."));
969                         else
970                             stuff_warning(ctl, _("\
971 The attempt to get authorization failed.\r\n\
972 This probably means your password is invalid, but some servers have\r\n\
973 other failure modes that fetchmail cannot distinguish from this\r\n\
974 because they don't send useful error messages on login failure.\r\n\
975 \r\n\
976 The fetchmail daemon will continue running and attempt to connect\r\n\
977 at each cycle.  No future notifications will be sent until service\r\n\
978 is restored."));
979                         close_warning_by_mail(ctl, (struct msgblk *)NULL);
980                     }
981                 }
982                 else
983                     report(stderr, _("Unknown login or authentication error on %s@%s\n"),
984                            ctl->remotename,
985                            ctl->server.truename);
986                     
987                 goto cleanUp;
988             }
989             else
990             {
991                 /*
992                  * This connection has given us authorization at least once.
993                  *
994                  * There are dodgy server (clubinternet.fr for example) that
995                  * give spurious authorization failures on patently good
996                  * account/password details, then 5 minutes later let you in!
997                  *
998                  * This is meant to build in some tolerance of such nasty bits
999                  * of work.
1000                  */
1001                 ctl->wehaveauthed = 1;
1002                 /*if (ctl->authfailcount >= 3)*/
1003                 if (ctl->wehavesentauthnote)
1004                 {
1005                     ctl->wehavesentauthnote = 0;
1006                     report(stderr,
1007                            _("Authorization OK on %s@%s\n"),
1008                            ctl->remotename,
1009                            ctl->server.truename);
1010                     if (!open_warning_by_mail(ctl, (struct msgblk *)NULL))
1011                     {
1012                         stuff_warning(ctl,
1013                               _("Subject: fetchmail authentication OK on %s@%s\r\n"),
1014                                       ctl->remotename, ctl->server.truename);
1015                         stuff_warning(ctl,
1016                               _("Fetchmail was able to log into %s@%s.\r\n"), 
1017                                       ctl->remotename,
1018                                       ctl->server.truename);
1019                         stuff_warning(ctl, 
1020                                       _("Service has been restored.\r\n"));
1021                         close_warning_by_mail(ctl, (struct msgblk *)NULL);
1022                     
1023                     }
1024                 }
1025                 /*
1026                  * Reporting only after the first three
1027                  * consecutive failures, or ten consecutive
1028                  * failures after we have managed to get
1029                  * authorization.
1030                  */
1031                 ctl->authfailcount = 0;
1032             }
1033         }
1034
1035         ctl->errcount = fetches = 0;
1036
1037         /* now iterate over each folder selected */
1038         for (idp = ctl->mailboxes; idp; idp = idp->next)
1039         {
1040             pass = 0;
1041             do {
1042                 dispatches = 0;
1043                 ++pass;
1044
1045                 /* reset timeout, in case we did an IDLE */
1046                 mytimeout = ctl->server.timeout;
1047
1048                 if (outlevel >= O_DEBUG)
1049                 {
1050                     if (idp->id)
1051                         report(stdout, _("selecting or re-polling folder %s\n"), idp->id);
1052                     else
1053                         report(stdout, _("selecting or re-polling default folder\n"));
1054                 }
1055
1056                 /* compute # of messages and number of new messages waiting */
1057                 stage = STAGE_GETRANGE;
1058                 ok = (ctl->server.base_protocol->getrange)(mailserver_socket, ctl, idp->id, &count, &new, &bytes);
1059                 if (ok != 0)
1060                     goto cleanUp;
1061
1062                 /* show user how many messages we downloaded */
1063                 if (idp->id)
1064                     (void) sprintf(buf, _("%s at %s (folder %s)"),
1065                                    ctl->remotename, ctl->server.truename, idp->id);
1066                 else
1067                     (void) sprintf(buf, _("%s at %s"),
1068                                    ctl->remotename, ctl->server.truename);
1069                 if (outlevel > O_SILENT)
1070                 {
1071                     if (count == -1)            /* only used for ETRN */
1072                         report(stdout, _("Polling %s\n"), ctl->server.truename);
1073                     else if (count != 0)
1074                     {
1075                         if (new != -1 && (count - new) > 0)
1076                             report_build(stdout, _("%d %s (%d seen) for %s"),
1077                                   count, count > 1 ? _("messages") :
1078                                                      _("message"),
1079                                   count-new, buf);
1080                         else
1081                             report_build(stdout, _("%d %s for %s"), 
1082                                   count, count > 1 ? _("messages") :
1083                                                      _("message"), buf);
1084                         if (bytes == -1)
1085                             report_complete(stdout, ".\n");
1086                         else
1087                             report_complete(stdout, _(" (%d octets).\n"), bytes);
1088                     }
1089                     else
1090                     {
1091                         /* these are pointless in normal daemon mode */
1092                         if (pass == 1 && (run.poll_interval == 0 || outlevel >= O_VERBOSE))
1093                             report(stdout, _("No mail for %s\n"), buf); 
1094                     }
1095                 }
1096
1097                 /* very important, this is where we leave the do loop */ 
1098                 if (count == 0)
1099                     break;
1100
1101                 if (check_only)
1102                 {
1103                     if (new == -1 || ctl->fetchall)
1104                         new = count;
1105                     fetches = new;      /* set error status ccorrectly */
1106                     /*
1107                      * There used to be a `got noerror' here, but this
1108                      * prevneted checking of multiple folders.  This
1109                      * comment is a reminder in case I introduced some
1110                      * subtle bug by removing it...
1111                      */
1112                 }
1113                 else if (count > 0)
1114                 {    
1115                     flag        force_retrieval;
1116
1117                     /*
1118                      * What forces this code is that in POP2 and
1119                      * IMAP2bis you can't fetch a message without
1120                      * having it marked `seen'.  In POP3 and IMAP4, on the
1121                      * other hand, you can (peek_capable is set by 
1122                      * each driver module to convey this; it's not a
1123                      * method constant because of the difference between
1124                      * IMAP2bis and IMAP4, and because POP3 doesn't  peek
1125                      * if fetchall is on).
1126                      *
1127                      * The result of being unable to peek is that if there's
1128                      * any kind of transient error (DNS lookup failure, or
1129                      * sendmail refusing delivery due to process-table limits)
1130                      * the message will be marked "seen" on the server without
1131                      * having been delivered.  This is not a big problem if
1132                      * fetchmail is running in foreground, because the user
1133                      * will see a "skipped" message when it next runs and get
1134                      * clued in.
1135                      *
1136                      * But in daemon mode this leads to the message
1137                      * being silently ignored forever.  This is not
1138                      * acceptable.
1139                      *
1140                      * We compensate for this by checking the error
1141                      * count from the previous pass and forcing all
1142                      * messages to be considered new if it's nonzero.
1143                      */
1144                     force_retrieval = !peek_capable && (ctl->errcount > 0);
1145
1146                     /* 
1147                      * We need the size of each message before it's
1148                      * loaded in order to pass it to the ESMTP SIZE
1149                      * option.  If the protocol has a getsizes method,
1150                      * we presume this means it doesn't get reliable
1151                      * sizes from message fetch responses.
1152                      */
1153                     if (proto->getsizes)
1154                     {
1155                         int     i;
1156
1157                         xalloca(msgsizes, int *, sizeof(int) * count);
1158                         for (i = 0; i < count; i++)
1159                             msgsizes[i] = -1;
1160
1161                         stage = STAGE_GETSIZES;
1162                         ok = (proto->getsizes)(mailserver_socket, count, msgsizes);
1163                         if (ok != 0)
1164                             goto cleanUp;
1165
1166                         if (bytes == -1)
1167                         {
1168                             bytes = 0;
1169                             for (i = 0; i < count; i++)
1170                                 bytes += msgsizes[i];
1171                         }
1172                     }
1173
1174                     /* read, forward, and delete messages */
1175                     stage = STAGE_FETCH;
1176
1177                     /* fetch in lockstep mode */
1178                     if (!fetch_messages(mailserver_socket, ctl, 
1179                                         count, msgsizes, 
1180                                         new, force_retrieval, maxfetch,
1181                                         &fetches, &dispatches, &deletions))
1182                         goto cleanUp;
1183
1184                     if (!check_only && ctl->skipped
1185                         && run.poll_interval > 0 && !nodetach)
1186                     {
1187                         clean_skipped_list(&ctl->skipped);
1188                         send_size_warnings(ctl);
1189                     }
1190                 }
1191             } while
1192                   /*
1193                    * Only re-poll if we either had some actual forwards and 
1194                    * either allowed deletions and had no errors.
1195                    * Otherwise it is far too easy to get into infinite loops.
1196                    */
1197                   (dispatches && ctl->server.base_protocol->retry && !ctl->keep && !ctl->errcount);
1198         }
1199
1200     /* no_error: */
1201         /* ordinary termination with no errors -- officially log out */
1202         ok = (ctl->server.base_protocol->logout_cmd)(mailserver_socket, ctl);
1203         /*
1204          * Hmmmm...arguably this would be incorrect if we had fetches but
1205          * no dispatches (due to oversized messages, etc.)
1206          */
1207         if (ok == 0)
1208             ok = (fetches > 0) ? PS_SUCCESS : PS_NOMAIL;
1209         SockClose(mailserver_socket);
1210         goto closeUp;
1211
1212     cleanUp:
1213         /* we only get here on error */
1214         if (ok != 0 && ok != PS_SOCKET)
1215         {
1216             stage = STAGE_LOGOUT;
1217             (ctl->server.base_protocol->logout_cmd)(mailserver_socket, ctl);
1218         }
1219         SockClose(mailserver_socket);
1220     }
1221
1222     msg = (const char *)NULL;   /* sacrifice to -Wall */
1223     switch (ok)
1224     {
1225     case PS_SOCKET:
1226         msg = _("socket");
1227         break;
1228     case PS_SYNTAX:
1229         msg = _("missing or bad RFC822 header");
1230         break;
1231     case PS_IOERR:
1232         msg = _("MDA");
1233         break;
1234     case PS_ERROR:
1235         msg = _("client/server synchronization");
1236         break;
1237     case PS_PROTOCOL:
1238         msg = _("client/server protocol");
1239         break;
1240     case PS_LOCKBUSY:
1241         msg = _("lock busy on server");
1242         break;
1243     case PS_SMTP:
1244         msg = _("SMTP transaction");
1245         break;
1246     case PS_DNS:
1247         msg = _("DNS lookup");
1248         break;
1249     case PS_UNDEFINED:
1250         report(stderr, _("undefined error\n"));
1251         break;
1252     }
1253     /* no report on PS_MAXFETCH or PS_UNDEFINED or PS_AUTHFAIL */
1254     if (ok==PS_SOCKET || ok==PS_SYNTAX
1255                 || ok==PS_IOERR || ok==PS_ERROR || ok==PS_PROTOCOL 
1256                 || ok==PS_LOCKBUSY || ok==PS_SMTP || ok==PS_DNS)
1257     {
1258         char    *stem;
1259
1260         if (phase == FORWARDING_WAIT || phase == LISTENER_WAIT)
1261             stem = _("%s error while delivering to SMTP host %s\n");
1262         else
1263             stem = _("%s error while fetching from %s\n");
1264         report(stderr, stem, msg, ctl->server.pollname);
1265     }
1266
1267 closeUp:
1268     /* execute wrapup command, if any */
1269     if (ctl->postconnect && (ok = system(ctl->postconnect)))
1270     {
1271         report(stderr, _("post-connection command failed with status %d\n"), ok);
1272         if (ok == PS_SUCCESS)
1273             ok = PS_SYNTAX;
1274     }
1275
1276     signal(SIGALRM, alrmsave);
1277     signal(SIGPIPE, pipesave);
1278     return(ok);
1279 }
1280
1281 int do_protocol(ctl, proto)
1282 /* retrieve messages from server using given protocol method table */
1283 struct query *ctl;              /* parsed options with merged-in defaults */
1284 const struct method *proto;     /* protocol method table */
1285 {
1286     int ok;
1287
1288 #ifndef KERBEROS_V4
1289     if (ctl->server.authenticate == A_KERBEROS_V4)
1290     {
1291         report(stderr, _("Kerberos V4 support not linked.\n"));
1292         return(PS_ERROR);
1293     }
1294 #endif /* KERBEROS_V4 */
1295
1296 #ifndef KERBEROS_V5
1297     if (ctl->server.authenticate == A_KERBEROS_V5)
1298     {
1299         report(stderr, _("Kerberos V5 support not linked.\n"));
1300         return(PS_ERROR);
1301     }
1302 #endif /* KERBEROS_V5 */
1303
1304     /* lacking methods, there are some options that may fail */
1305     if (!proto->is_old)
1306     {
1307         /* check for unsupported options */
1308         if (ctl->flush) {
1309             report(stderr,
1310                     _("Option --flush is not supported with %s\n"),
1311                     proto->name);
1312             return(PS_SYNTAX);
1313         }
1314         else if (ctl->fetchall) {
1315             report(stderr,
1316                     _("Option --all is not supported with %s\n"),
1317                     proto->name);
1318             return(PS_SYNTAX);
1319         }
1320     }
1321     if (!proto->getsizes && NUM_SPECIFIED(ctl->limit))
1322     {
1323         report(stderr,
1324                 _("Option --limit is not supported with %s\n"),
1325                 proto->name);
1326         return(PS_SYNTAX);
1327     }
1328
1329     /*
1330      * If no expunge limit or we do expunges within the driver,
1331      * then just do one session, passing in any fetchlimit.
1332      */
1333     if (proto->retry || !NUM_SPECIFIED(ctl->expunge))
1334         return(do_session(ctl, proto, NUM_VALUE_OUT(ctl->fetchlimit)));
1335     /*
1336      * There's an expunge limit, and it isn't handled in the driver itself.
1337      * OK; do multiple sessions, each fetching a limited # of messages.
1338      * Stop if the total count of retrieved messages exceeds ctl->fetchlimit
1339      * (if it was nonzero).
1340      */
1341     else
1342     {
1343         int totalcount = 0; 
1344         int lockouts   = 0;
1345         int expunge    = NUM_VALUE_OUT(ctl->expunge);
1346         int fetchlimit = NUM_VALUE_OUT(ctl->fetchlimit);
1347
1348         do {
1349             if (fetchlimit > 0 && (expunge == 0 || expunge > fetchlimit - totalcount))
1350                 expunge = fetchlimit - totalcount;
1351             ok = do_session(ctl, proto, expunge);
1352             totalcount += expunge;
1353             if (NUM_SPECIFIED(ctl->fetchlimit) && totalcount >= fetchlimit)
1354                 break;
1355             if (ok != PS_LOCKBUSY)
1356                 lockouts = 0;
1357             else if (lockouts >= MAX_LOCKOUTS)
1358                 break;
1359             else /* ok == PS_LOCKBUSY */
1360             {
1361                 /*
1362                  * Allow time for the server lock to release.  if we
1363                  * don't do this, we'll often hit a locked-mailbox
1364                  * condition and fail.
1365                  */
1366                 lockouts++;
1367                 sleep(3);
1368             }
1369         } while
1370             (ok == PS_MAXFETCH || ok == PS_LOCKBUSY);
1371
1372         return(ok);
1373     }
1374 }
1375
1376
1377 /* driver.c ends here */