From 3fadc1e5f1217f884077968bc7d64b1540e7bd73 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 22 Jul 2003 02:32:07 +0000 Subject: Support faked IDLE. svn path=/trunk/; revision=3829 --- NEWS | 10 ++++-- fetchmail-features.html | 7 +++-- fetchmail.man | 25 ++++++++------- imap.c | 82 +++++++++++++++++++++++++++++++++---------------- 4 files changed, 81 insertions(+), 43 deletions(-) diff --git a/NEWS b/NEWS index 349c2161..e9065374 100644 --- a/NEWS +++ b/NEWS @@ -2,13 +2,17 @@ (The `lines' figures total .c, .h, .l, and .y files under version control.) +* Updated German and Turkish translations. +* IDLE is now supported using no-ops even if the server doesn't support + the IMAP IDLE extension. + fetchmail-6.2.3 (Thu Jul 17 14:53:00 EDT 2003), 22490 lines: -* German, Danish, Spanish, and Turkish translations updated. -* Brian Sammon's patch to deal with malformed message lines containiing NULs. +* French, German, Danish, Spanish, and Turkish translations updated. +* Brian Sammon's patch to deal with malformed message lines containing NULs. * Fai's patch to ignore all but the first Return-Path (some spams have more than one of these). -* Benjamin Drieu's ptch to properly byte-stuff when talking to BSNTP. +* Benjamin Drieu's patch to properly byte-stuff when talking to BSNTP. Fixes Debian bug #184469. * Benjamin Drieu's patch to enable auth=cram-md5. Fixes Debian bug #185232. diff --git a/fetchmail-features.html b/fetchmail-features.html index cbb4663b..e6458c14 100644 --- a/fetchmail-features.html +++ b/fetchmail-features.html @@ -18,7 +18,7 @@ Back to Fetchmail Home Page To Site Map -$Date: 2003/07/17 00:55:17 $ +$Date: 2003/07/22 02:32:06 $ @@ -80,7 +80,8 @@ saying `aka netaxs.com' will match not just netaxs.com but also (say) pop3.netaxs.com and mail.netaxs.com.
  • Fetchmail can optionally use the RFC 2177 IDLE extension on an -IMAP server that supports it.
  • +IMAP server that supports it. On IMAP servers that don't, it can +simulate it using periodic NOOP commands.
  • Fetchmail now recognizes the RFC 2449 extended responses [IN-USE] and [LOGIN-DELAY].
  • @@ -280,7 +281,7 @@ be unique to fetchmail if I hadn't added it to fetchpop.) Back to Fetchmail Home Page To Site Map -$Date: 2003/07/17 00:55:17 $ +$Date: 2003/07/22 02:32:06 $ diff --git a/fetchmail.man b/fetchmail.man index 86a01bd5..7a596e77 100644 --- a/fetchmail.man +++ b/fetchmail.man @@ -1670,17 +1670,20 @@ default, because doing RFC2047 conversion on headers throws away character-set information and can lead to bad results if the encoding of the headers differs from the body encoding. .PP -The `idle' option is usable only with IMAP servers supporting the -RFC2177 IDLE command extension. If it is enabled, and fetchmail -detects that IDLE is supported, an IDLE will be issued at the end -of each poll. This will tell the IMAP server to hold the connection -open and notify the client when new mail is available. If you need to -poll a link frequently, IDLE can save bandwidth by eliminating TCP/IP -connects and LOGIN/LOGOUT sequences. On the other hand, an IDLE -connection will eat almost all of your fetchmail's time, because it -will never drop the connection and allow other pools to occur unless -the server times out the IDLE. It also doesn't work with multiple -folders; only the first folder will ever be polled. +The `idle' option is intended to be used with IMAP servers supporting +the RFC2177 IDLE command extension, but does not strictly require it. +If it is enabled, and fetchmail detects that IDLE is supported, an +IDLE will be issued at the end of each poll. This will tell the IMAP +server to hold the connection open and notify the client when new mail +is available. If IDLE is not supported, fetchmail will simulate it by +periodically issuing NOOP. If you need to poll a link frequently, IDLE +can save bandwidth by eliminating TCP/IP connects and LOGIN/LOGOUT +sequences. On the other hand, an IDLE connection will eat almost all +of your fetchmail's time, because it will never drop the connection +and allow other pools to occur unless the server times out the IDLE. +It also doesn't work with multiple folders; only the first folder will +ever be polled. + .PP The `properties' option is an extension mechanism. It takes a string argument, which is ignored by fetchmail itself. The string argument may be diff --git a/imap.c b/imap.c index 3e6d80fc..9154620d 100644 --- a/imap.c +++ b/imap.c @@ -34,7 +34,7 @@ static int count = 0, recentcount = 0, unseen = 0, deletions = 0; static unsigned int startcount = 1; static int expunged, expunge_period, saved_timeout = 0; static int imap_version, preauth; -static flag do_idle; +static flag do_idle, has_idle; static char capabilities[MSGBUFSIZE+1]; static unsigned int *unseen_messages; @@ -86,10 +86,14 @@ static int imap_ok(int sock, char *argbuf) */ if (stage == STAGE_IDLE) { - /* we do our own write and report here to disable tagging */ - SockWrite(sock, "DONE\r\n", 6); - if (outlevel >= O_MONITOR) - report(stdout, "IMAP> DONE\n"); + /* If IDLE isn't supported, we were only sending NOOPs anyway. */ + if (has_idle) + { + /* we do our own write and report here to disable tagging */ + SockWrite(sock, "DONE\r\n", 6); + if (outlevel >= O_MONITOR) + report(stdout, "IMAP> DONE\n"); + } mytimeout = saved_timeout; stage = STAGE_FETCH; @@ -292,9 +296,13 @@ static void capa_probe(int sock, struct query *ctl) * Handle idling. We depend on coming through here on startup * and after each timeout (including timeouts during idles). */ - if (strstr(capabilities, "IDLE") && ctl->idle) + if (ctl->idle) { do_idle = TRUE; + if (strstr(capabilities, "IDLE")) + { + has_idle = TRUE; + } if (outlevel >= O_VERBOSE) report(stdout, GT_("will idle after poll\n")); } @@ -544,35 +552,57 @@ static int internal_expunge(int sock) } static int imap_idle(int sock) -/* start an RFC2177 IDLE */ +/* start an RFC2177 IDLE, or fake one if unsupported */ { int ok; - /* special timeout to terminate the IDLE and re-issue it - * at least every 28 minutes: - * (the server may have an inactivity timeout) */ stage = STAGE_IDLE; saved_timeout = mytimeout; - mytimeout = 1680; /* 28 min */ - /* enter IDLE mode */ - ok = gen_transact(sock, "IDLE"); + if (has_idle) { + /* special timeout to terminate the IDLE and re-issue it + * at least every 28 minutes: + * (the server may have an inactivity timeout) */ + mytimeout = 1680; /* 28 min */ + /* enter IDLE mode */ + ok = gen_transact(sock, "IDLE"); + + if (ok == PS_IDLETIMEOUT) { + /* send "DONE" continuation */ + SockWrite(sock, "DONE\r\n", 6); + if (outlevel >= O_MONITOR) + report(stdout, "IMAP> DONE\n"); + } else + /* not idle timeout */ + return ok; + } else { /* no idle support, fake it */ + /* when faking an idle, we can't assume the server will + * send us the new messages out of the blue (RFC2060); + * this timeout is potentially the delay before we notice + * new mail (can be small since NOOP checking is cheap) */ + mytimeout = 28; + ok = gen_transact(sock, "NOOP"); + /* if there's an error (not likely) or we just found mail (stage + * has changed, timeout has also been restored), we're done */ + if (ok != 0 || stage != STAGE_IDLE) + return(ok); + + /* wait (briefly) for an unsolicited status update */ + ok = imap_ok(sock, NULL); + /* again, this is new mail or an error */ + if (ok != PS_IDLETIMEOUT) + return(ok); + } - if(ok == PS_IDLETIMEOUT) { - /* send "DONE" continuation */ - SockWrite(sock, "DONE\r\n", 6); - if (outlevel >= O_MONITOR) - report(stdout, "IMAP> DONE\n"); + /* restore normal timeout value */ + mytimeout = saved_timeout; + stage = STAGE_FETCH; - /* restore normal timeout value */ - mytimeout = saved_timeout; - stage = STAGE_FETCH; + /* get OK IDLE message */ + if (has_idle) + return imap_ok(sock, NULL); - /* get OK IDLE message */ - return imap_ok(sock, NULL); - } else - /* not idle timeout */ - return ok; + return PS_SUCCESS; } static int imap_getrange(int sock, -- cgit v1.2.3