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