aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>1996-10-01 07:14:12 +0000
committerEric S. Raymond <esr@thyrsus.com>1996-10-01 07:14:12 +0000
commitaaeb3055402a95323d97a7807c0b92848afb0aa5 (patch)
tree1a56fe9fefee1d4f9c4e8a4dc21e778110290c37
parent9822112a35d7962b08730668ea2aa2355315ea42 (diff)
downloadfetchmail-aaeb3055402a95323d97a7807c0b92848afb0aa5.tar.gz
fetchmail-aaeb3055402a95323d97a7807c0b92848afb0aa5.tar.bz2
fetchmail-aaeb3055402a95323d97a7807c0b92848afb0aa5.zip
Better IMAP support.
svn path=/trunk/; revision=185
-rw-r--r--NEWS8
-rw-r--r--imap.c93
2 files changed, 30 insertions, 71 deletions
diff --git a/NEWS b/NEWS
index 566151f6..120f9434 100644
--- a/NEWS
+++ b/NEWS
@@ -3,8 +3,7 @@
Test RPOP feature against a server that has it.
Support IMAP4 extensions for secure challenge-response, once they're actually
-standardized. Also, use the CAPABILITY command to detect when we're talking
-to a true IMAP4 server and use SEARCH UNSEEN.
+standardized.
Inflict pain on the person(s) responsible for removing LAST from POP3.
@@ -18,6 +17,11 @@ fetchmail-1.3 (Sun Sep 29 01:22:21 EDT 1996):
* Kill off -2 and -3 options, redundant popclient remnants.
+* IMAP code simplification and robustification. Use FETCH FLAGS to find
+ seen messages. Code should now work even if unseen messages are
+ interspersed with seen ones, and even if messages are appended to the
+ mailbox during the run.
+
fetchmail-1.2 (Sat Sep 28 15:40:50 EDT 1996):
* The great option massacre. Remove --stdout, --limit, --local, --mda.
diff --git a/imap.c b/imap.c
index 70e29150..cd7e4bdf 100644
--- a/imap.c
+++ b/imap.c
@@ -9,54 +9,11 @@
programmer: Eric S. Raymond
description: IMAP client code
-Chris Newman, one of the IMAP maintainers, criticized this as follows:
-------------------------------- CUT HERE -----------------------------------
-On Wed, 18 Sep 1996, Eric S. Raymond wrote:
-> 1. I do one one SELECT, at the beginning of the fetch.
->
-> 2. I assume that I can pick an upper bound on message numbers from the EXISTS
-> reponse.
-
-Correct.
-
-> 3. If there is an UNSEEN nnn trailer on the OK response to SELECT, I assume
-> that the unseen messages have message numbers which are the nnn consecutive
-> integers up to and including the upper bound.
->
-> 4. Otherwise, if the response included RECENT nnn, I assume that the unseen
-> messages have message numbers which are the nnn consecutive integers up to
-> and including the upper bound.
-
-These will only work if your client is the only client that accesses the
-INBOX. There is no requirement that the UNSEEN and RECENT messages are at
-the end of the folder in general.
-
-If you want to present all UNSEEN messages and flag all the messages you
-download as SEEN, you could do a SEARCH UNSEEN and just fetch those
-messages.
-
-However, the proper thing to do if you want to present the messages when
-disconnected from the server is to use UIDs. To do this, you remember the
-highest UID you have (you can initialize to 0), and fetch everything with
-a higher UID. Ideally, you shouldn't cause the SEEN flag to be set until
-the user has actually seen the message. This requires STORE +FLAGS SEEN
-for those messages which have been seen since the last update.
-
-The key thing to remember is that in IMAP the server holds the
-authoratative list of messages and the client just holds a cache. This is
-a very different model from POP.
-------------------------------- CUT HERE -----------------------------------
-
-A problem with this recommendation is that the UID commands don't exist
-in IMAP2bis. Since we want to preserve IMAP2bis capability (so fetchmail
-will continue to work with the pre-IMAP4 imapd) and we've warned the user
-that multiple concurrent fetchmail runs are a Bad Idea, we'll stick with
-this logic for now.
-
***********************************************************************/
#include <config.h>
#include <stdio.h>
+#include <string.h>
#include "socket.h"
#include "fetchmail.h"
@@ -66,8 +23,7 @@ this logic for now.
*********************************************************************/
-static int count, first;
-static int exists, unseen, recent;
+static int count, seen;
int imap_ok (argbuf,socket)
/* parse command response */
@@ -79,6 +35,7 @@ int socket;
char *bufp;
int n;
+ seen = 0;
do {
if (SockGets(socket, buf, sizeof(buf)) < 0)
return(PS_SOCKET);
@@ -88,12 +45,9 @@ int socket;
/* interpret untagged status responses */
if (strstr(buf, "EXISTS"))
- exists = atoi(buf+2);
- if (strstr(buf, "RECENT"))
- recent = atoi(buf+2);
- if (sscanf(buf + 2, "OK [UNSEEN %d]", &n) == 1)
- unseen = n;
-
+ count = atoi(buf+2);
+ if (strstr(buf, "FLAGS"))
+ seen = (strstr(buf, "Seen") != (char *)NULL);
} while
(tag[0] != '\0' && strncmp(buf, tag, strlen(tag)));
@@ -146,31 +100,32 @@ int *firstp;
int ok;
/* find out how many messages are waiting */
- exists = unseen = recent = -1;
ok = gen_transact(socket,
"SELECT %s",
queryctl->remotefolder[0] ? queryctl->remotefolder : "INBOX");
if (ok != 0)
return(ok);
- /* compute size of message run */
- *countp = exists;
- if (queryctl->fetchall)
- *firstp = 1;
- else {
- if (exists > 0 && unseen == -1) {
- fprintf(stderr,
- "no UNSEEN response; assuming all %d RECENT messages are unseen\n",
- recent);
- *firstp = exists - recent + 1;
- } else {
- *firstp = unseen;
- }
- }
+ *countp = count;
+ *firstp = 1;
return(0);
}
+static imap_is_old(socket, queryctl, num)
+int socket;
+struct hostrec *queryctl;
+int num;
+{
+ char buf [POPBUFSIZE+1];
+ int ok;
+
+ if ((ok = gen_transact(socket, "FETCH %d FLAGS", num)) != 0)
+ exit(PS_ERROR);
+
+ return(seen);
+}
+
static int imap_fetch(socket, number, lenp)
/* request nth message */
int socket;
@@ -215,7 +170,7 @@ int socket;
struct hostrec *queryctl;
int number;
{
- return(socket, gen_transact("STORE %d +FLAGS (\\Deleted)", number));
+ return(gen_transact(socket, "STORE %d +FLAGS (\\Deleted)", number));
}
static struct method imap =
@@ -227,7 +182,7 @@ static struct method imap =
imap_ok, /* parse command response */
imap_getauth, /* get authorization */
imap_getrange, /* query range of messages */
- NULL, /* no UID check */
+ imap_is_old, /* no UID check */
imap_fetch, /* request given message */
imap_trail, /* eat message trailer */
imap_delete, /* set IMAP delete flag */