1 /* Copyright 1996 by Eric S. Raymond
3 * For license terms, see the file COPYING in this directory.
6 /***********************************************************************
9 programmer: Eric S. Raymond
10 description: IMAP client code
12 ***********************************************************************/
17 #include "fetchmail.h"
19 /*********************************************************************
21 Method declarations for IMAP
23 *********************************************************************/
25 static int count, first;
26 static int exists, unseen, recent;
28 int imap_ok (argbuf,socket)
29 /* parse command response */
34 char buf [POPBUFSIZE+1];
39 if (SockGets(socket, buf, sizeof(buf)) < 0)
42 if (outlevel == O_VERBOSE)
43 fprintf(stderr,"%s\n",buf);
45 /* interpret untagged status responses */
46 if (strstr(buf, "EXISTS"))
48 if (strstr(buf, "RECENT"))
50 if (sscanf(buf + 2, "OK [UNSEEN %d]", &n) == 1)
54 (tag[0] != '\0' && strncmp(buf, tag, strlen(tag)));
61 if (strncmp(buf + TAGLEN + 1, "OK", 2) == 0) {
62 strcpy(argbuf, buf + TAGLEN);
65 else if (strncmp(buf + TAGLEN + 1, "BAD", 2) == 0)
72 int imap_getauth(socket, queryctl, buf)
73 /* apply for connection authorization */
75 struct hostrec *queryctl;
78 /* try to get authorized */
79 return(gen_transact(socket,
81 queryctl->remotename, queryctl->password));
84 static imap_getrange(socket, queryctl, countp, firstp)
85 /* get range of messages to be fetched */
87 struct hostrec *queryctl;
93 /* find out how many messages are waiting */
94 exists = unseen = recent = -1;
95 ok = gen_transact(socket,
97 queryctl->remotefolder[0] ? queryctl->remotefolder : "INBOX");
101 /* compute size of message run */
103 if (queryctl->fetchall)
106 if (exists > 0 && unseen == -1) {
108 "no UNSEEN response; assuming all %d RECENT messages are unseen\n",
110 *firstp = exists - recent + 1;
119 static int imap_fetch(socket, number, limit, lenp)
120 /* request nth message */
126 char buf [POPBUFSIZE+1];
131 "PARTIAL %d RFC822 0 %d",
138 /* looking for FETCH response */
140 if (SockGets(socket, buf,sizeof(buf)) < 0)
143 (sscanf(buf+2, "%d FETCH (RFC822 {%d}", &num, lenp) != 2);
151 static imap_trail(socket, queryctl, number)
152 /* discard tail of FETCH response */
154 struct hostrec *queryctl;
157 char buf [POPBUFSIZE+1];
159 if (SockGets(socket, buf,sizeof(buf)) < 0)
165 static struct method imap =
167 "IMAP", /* Internet Message Access Protocol */
168 143, /* standard IMAP2bis/IMAP4 port */
169 1, /* this is a tagged protocol */
170 0, /* no message delimiter */
171 imap_ok, /* parse command response */
172 imap_getauth, /* get authorization */
173 imap_getrange, /* query range of messages */
174 imap_fetch, /* request given message */
175 imap_trail, /* eat message trailer */
176 "STORE %d +FLAGS (\\Deleted)", /* set IMAP delete flag */
177 "EXPUNGE", /* the IMAP expunge command */
178 "LOGOUT", /* the IMAP exit command */
181 int doIMAP (queryctl)
182 /* retrieve messages using IMAP Version 2bis or Version 4 */
183 struct hostrec *queryctl;
185 return(do_protocol(queryctl, &imap));