]> Pileus Git - ~andy/fetchmail/blob - imap.c
RC file syntax change, folder->mailbox, remote->remotename.
[~andy/fetchmail] / imap.c
1 /* Copyright 1996 by Eric S. Raymond
2  * All rights reserved.
3  * For license terms, see the file COPYING in this directory.
4  */
5
6 /***********************************************************************
7   module:       imap.c
8   project:      fetchmail
9   programmer:   Eric S. Raymond
10   description:  IMAP client code
11
12  ***********************************************************************/
13
14 #include  <config.h>
15 #include  <stdio.h>
16 #include  <string.h>
17 #include  "socket.h"
18 #include  "fetchmail.h"
19
20 /*********************************************************************
21
22  Method declarations for IMAP 
23
24  *********************************************************************/
25
26 static int count, seen;
27
28 int imap_ok (socket, argbuf)
29 /* parse command response */
30 char *argbuf;
31 int socket;
32 {
33     int ok;
34     char buf [POPBUFSIZE+1];
35     char *bufp;
36     int n;
37
38     seen = 0;
39     do {
40         if (SockGets(socket, buf, sizeof(buf)) < 0)
41             return(PS_SOCKET);
42
43         if (outlevel == O_VERBOSE)
44             fprintf(stderr,"%s\n",buf);
45
46         /* interpret untagged status responses */
47         if (strstr(buf, "EXISTS"))
48             count = atoi(buf+2);
49         if (strstr(buf, "FLAGS"))
50             seen = (strstr(buf, "Seen") != (char *)NULL);
51     } while
52         (tag[0] != '\0' && strncmp(buf, tag, strlen(tag)));
53
54     if (tag[0] == '\0')
55     {
56         strcpy(argbuf, buf);
57         return(0); 
58     }
59     else
60     {
61         char    *cp;
62
63         /* skip the tag */
64         for (cp = buf; !isspace(*cp); cp++)
65             continue;
66         while (isspace(*cp))
67             cp++;
68
69         if (strncmp(cp, "OK", 2) == 0)
70         {
71             strcpy(argbuf, cp);
72             return(0);
73         }
74         else if (strncmp(cp, "BAD", 2) == 0)
75             return(PS_ERROR);
76         else
77             return(PS_PROTOCOL);
78     }
79 }
80
81 int imap_getauth(socket, queryctl, buf)
82 /* apply for connection authorization */
83 int socket;
84 struct hostrec *queryctl;
85 char *buf;
86 {
87     /* try to get authorized */
88     return(gen_transact(socket,
89                   "LOGIN %s %s",
90                   queryctl->remotename, queryctl->password));
91 }
92
93 static imap_getrange(socket, queryctl, countp)
94 /* get range of messages to be fetched */
95 int socket;
96 struct hostrec *queryctl;
97 int *countp;
98 {
99     int ok;
100
101     /* find out how many messages are waiting */
102     ok = gen_transact(socket,
103                   "SELECT %s",
104                   queryctl->mailbox[0] ? queryctl->mailbox : "INBOX");
105     if (ok != 0)
106         return(ok);
107
108     *countp = count;
109
110     return(0);
111 }
112
113 static imap_is_old(socket, queryctl, num)
114 int socket;
115 struct hostrec *queryctl;
116 int num;
117 {
118     char buf [POPBUFSIZE+1];
119     int ok;
120
121     if ((ok = gen_transact(socket, "FETCH %d FLAGS", num)) != 0)
122         exit(PS_ERROR);
123
124     return(seen);
125 }
126
127 static int imap_fetch(socket, number, lenp)
128 /* request nth message */
129 int socket;
130 int number;
131 int *lenp; 
132 {
133     char buf [POPBUFSIZE+1];
134     int num;
135
136     gen_send(socket, "FETCH %d RFC822", number);
137
138     /* looking for FETCH response */
139     do {
140         if (SockGets(socket, buf,sizeof(buf)) < 0)
141             return(PS_SOCKET);
142     } while
143             (sscanf(buf+2, "%d FETCH (RFC822 {%d}", &num, lenp) != 2);
144
145     if (num != number)
146         return(PS_ERROR);
147     else
148         return(0);
149 }
150
151 static imap_trail(socket, queryctl, number)
152 /* discard tail of FETCH response */
153 int socket;
154 struct hostrec *queryctl;
155 int number;
156 {
157     char buf [POPBUFSIZE+1];
158
159     if (SockGets(socket, buf,sizeof(buf)) < 0)
160         return(PS_SOCKET);
161     else
162         return(0);
163 }
164
165 static imap_delete(socket, queryctl, number)
166 /* set delete flag for given message */
167 int socket;
168 struct hostrec *queryctl;
169 int number;
170 {
171     return(gen_transact(socket, "STORE %d +FLAGS (\\Deleted)", number));
172 }
173
174 const static struct method imap =
175 {
176     "IMAP",             /* Internet Message Access Protocol */
177     143,                /* standard IMAP2bis/IMAP4 port */
178     1,                  /* this is a tagged protocol */
179     0,                  /* no message delimiter */
180     imap_ok,            /* parse command response */
181     imap_getauth,       /* get authorization */
182     imap_getrange,      /* query range of messages */
183     imap_is_old,        /* no UID check */
184     imap_fetch,         /* request given message */
185     imap_trail,         /* eat message trailer */
186     imap_delete,        /* set IMAP delete flag */
187     "EXPUNGE",          /* the IMAP expunge command */
188     "LOGOUT",           /* the IMAP exit command */
189 };
190
191 int doIMAP (queryctl)
192 /* retrieve messages using IMAP Version 2bis or Version 4 */
193 struct hostrec *queryctl;
194 {
195     return(do_protocol(queryctl, &imap));
196 }
197
198