diff options
author | Eric S. Raymond <esr@thyrsus.com> | 1996-10-01 07:14:12 +0000 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 1996-10-01 07:14:12 +0000 |
commit | aaeb3055402a95323d97a7807c0b92848afb0aa5 (patch) | |
tree | 1a56fe9fefee1d4f9c4e8a4dc21e778110290c37 | |
parent | 9822112a35d7962b08730668ea2aa2355315ea42 (diff) | |
download | fetchmail-aaeb3055402a95323d97a7807c0b92848afb0aa5.tar.gz fetchmail-aaeb3055402a95323d97a7807c0b92848afb0aa5.tar.bz2 fetchmail-aaeb3055402a95323d97a7807c0b92848afb0aa5.zip |
Better IMAP support.
svn path=/trunk/; revision=185
-rw-r--r-- | NEWS | 8 | ||||
-rw-r--r-- | imap.c | 93 |
2 files changed, 30 insertions, 71 deletions
@@ -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. @@ -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 */ |