/[imapfilter]/imapfilter/response.c
ViewVC logotype

Contents of /imapfilter/response.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.17 - (show annotations)
Sat Nov 10 15:31:59 2001 UTC (22 years, 4 months ago) by lefcha
Branch: MAIN
CVS Tags: release-0_7
Branch point for: release-0_7-patches
Changes since 1.16: +9 -3 lines
File MIME type: text/plain
Stop if mbox doesn't exist.

1 #include <stdio.h>
2 #include <unistd.h>
3 #include <stdlib.h>
4 #include <ctype.h>
5 #include <errno.h>
6 #include <string.h>
7 #include <sys/time.h>
8 #include <sys/types.h>
9 #include <regex.h>
10
11 #include "config.h"
12 #include "imapfilter.h"
13
14
15 extern unsigned int options;
16
17
18 /*
19 * Read one packet of data that the server sent.
20 */
21 void receive_response(char *buf)
22 {
23 socket_read(buf);
24
25 #ifdef DEBUG
26 printf("\n%s\n", buf);
27 #endif
28
29 }
30
31
32 /*
33 * Get server response to client's request.
34 */
35 int server_response(unsigned int tag)
36 {
37 char buf[RESPONSE_BUF];
38
39 do
40 receive_response(buf);
41 while (tag && !strcasestr(buf, ultostr(tag, 16)));
42
43 return analyze_response(buf);
44 }
45
46
47 /*
48 * Process the greeting that server sends during connection.
49 */
50 int greeting_response(void)
51 {
52 char buf[RESPONSE_BUF];
53
54 receive_response(buf);
55
56 if (strcasestr(buf, "BYE"))
57 return RESPONSE_BYE;
58 else if (strcasestr(buf, "PREAUTH"))
59 return RESPONSE_PREAUTH;
60
61 return RESPONSE_OK;
62 }
63
64
65 /*
66 * Process the data that server sent due to IMAP CAPABILITY client request.
67 */
68 int capability_response(unsigned int tag)
69 {
70 char buf[RESPONSE_BUF];
71
72 do
73 receive_response(buf);
74 while (!strcasestr(buf, ultostr(tag, 16)));
75
76 if (!strcasestr(buf, "IMAP4rev1")) {
77 error("imapfilter: server does not support IMAP4rev1 protocol\n");
78 return -2;
79 }
80 return analyze_response(buf);
81 }
82
83
84 /*
85 * Process the data that server sent due to IMAP STATUS client request.
86 */
87 int status_response(unsigned int tag, char *mbox)
88 {
89 int r;
90 char buf[RESPONSE_BUF];
91 unsigned int exist, recent, unseen;
92 char *c;
93
94 exist = recent = unseen = 0;
95
96 do
97 receive_response(buf);
98 while (!strcasestr(buf, ultostr(tag, 16)));
99
100 r = analyze_response(buf);
101
102 if (r == RESPONSE_NO)
103 return -2;
104
105 if ((c = strcasestr(buf, "MESSAGES"))) {
106 c += 9;
107 exist = strtoul(c, NULL, 10);
108 }
109 if ((c = strcasestr(buf, "RECENT"))) {
110 c += 7;
111 recent = strtoul(c, NULL, 10);
112 }
113 if ((c = strcasestr(buf, "UNSEEN"))) {
114 c += 7;
115 unseen = strtoul(c, NULL, 10);
116 }
117 if (!exist) {
118 info("No messages in mailbox %s.\n", mbox);
119 return -2;
120 }
121 info("%d message%s, %d recent, %d unseen, in mailbox %s.\n", exist, plural(exist),
122 recent, unseen, mbox);
123
124 return r;
125 }
126
127
128 /*
129 * Process the data that server sent due to IMAP SELECT client request.
130 */
131 int select_response(unsigned int tag)
132 {
133 char buf[RESPONSE_BUF];
134
135 do
136 receive_response(buf);
137 while (!strcasestr(buf, ultostr(tag, 16)));
138
139 if (strcasestr(buf, "[READ-ONLY]"))
140 return RESPONSE_READONLY;
141
142 return analyze_response(buf);
143 }
144
145
146 /*
147 * Process the data that server sent due to IMAP SEARCH client request.
148 */
149 int search_response(unsigned int tag, char **mesgs)
150 {
151 char buf[RESPONSE_BUF];
152 char *c, *m;
153 int f;
154 unsigned int blen, mlen;
155
156 f = blen = mlen = 0;
157
158 do {
159 receive_response(buf);
160
161 if (f) { /* Search results are continued from
162 previous packet. */
163 c = buf;
164 blen = strlen(buf);
165 mlen = strlen(*mesgs);
166
167 *mesgs = (char *) xrealloc(*mesgs, mlen + blen + 1);
168 m = *mesgs + mlen;
169
170 while (*c && (isdigit(*c) || *c == ' '))
171 *(m++) = *(c++);
172 *m = 0;
173 } else if ((c = strcasestr(buf, "* SEARCH "))) {
174 f = 1;
175 blen = strlen(buf);
176
177 m = *mesgs = (char *) xmalloc(blen + 1);
178 c += 9;
179
180 while (*c && (isdigit(*c) || *c == ' '))
181 *(m++) = *(c++);
182 *m = 0;
183 }
184 } while (!strcasestr(buf, ultostr(tag, 16)));
185
186 return analyze_response(buf);
187 }
188
189
190 /*
191 * Process the data that server sent due to IMAP FETCH client request.
192 */
193 int fetch_response(unsigned int tag)
194 {
195 char buf[RESPONSE_BUF];
196 char hdrs[HEADERS_BUF];
197 int f;
198 unsigned int sa, sb, i, n;
199 char s[8];
200 char *b;
201
202 hdrs[0] = 0;
203 sa = sb = i = f = 0;
204 s[0] = 0;
205
206 do {
207 receive_response(buf);
208
209 b = buf;
210
211 while (f || (b = strchr(b, '{'))) {
212 /* Headers are continued from previous packet. */
213 if (f) {
214 f = 0;
215 for (; i < HEADERS_BUF - 1 && i < sa - 2; i++) {
216 /* Continued in next packet. */
217 if (!*b) {
218 f = 1;
219 break;
220 }
221 hdrs[i] = *(b++);
222 }
223 } else {
224 /* Left bracket is last byte of buffer. */
225 if (b == buf + RESPONSE_BUF - 2) {
226 receive_response(buf);
227 b = buf;
228 } else
229 b++;
230
231 sa = atoi(b);
232
233 /* Headers length may be continued in next packet. */
234 if (!(b = strchr(b, '}'))) {
235 receive_response(buf);
236 if (buf != (b = strchr(buf, '}'))) {
237 sb = atoi(buf);
238 strncat(s, ultostr(sa, 10), 7);
239 strncat(s, ultostr(sb, 10), 7);
240 sa = atoi(s);
241 s[0] = 0;
242 }
243 b += 3;
244 } else if ((n = RESPONSE_BUF - 1 - (b - buf)) < 3) {
245 receive_response(buf);
246 b = buf + 3 - n;
247 } else {
248 b += 3;
249 }
250
251 for (i = 0; i < HEADERS_BUF - 1 && i < sa - 2; i++) {
252 if (!*b) {
253 f = 1;
254 break;
255 }
256 hdrs[i] = *(b++);
257 }
258 }
259
260 if (!f) {
261 hdrs[i] = 0;
262
263 if (*hdrs) {
264 if (options & OPTION_HEADERS)
265 info("%s\n", hdrs);
266 log_info(LOG_WRITE, hdrs);
267 } else {
268 log_info(LOG_WRITE, NULL);
269 }
270 } else {
271 break;
272 }
273 }
274 } while (!strcasestr(buf, ultostr(tag, 16)));
275
276 return analyze_response(buf);
277 }
278
279
280 /*
281 * Process the data that server sent due to IMAP COPY client request.
282 */
283 int copy_response(unsigned int tag)
284 {
285 char buf[RESPONSE_BUF];
286
287 do
288 receive_response(buf);
289 while (!strcasestr(buf, ultostr(tag, 16)));
290
291 if (analyze_response(buf) == RESPONSE_NO && strcasestr(buf, "[TRYCREATE]"))
292 return RESPONSE_TRYCREATE;
293
294 return RESPONSE_OK;
295 }
296
297
298 /*
299 * Check if response of server to client's request was succesfully
300 * delivered or there was some kind of error.
301 */
302 int analyze_response(char *buf)
303 {
304 int r = RESPONSE_OK;
305 regex_t creg;
306 regmatch_t match[3];
307 const char *reg = "[[:xdigit:]]{6,6} ((OK|NO|BAD)[[:print:]]*)\r\n";
308 char result[RESULT_BUF];
309
310 result[0] = 0;
311
312 regcomp(&creg, reg, REG_EXTENDED | REG_ICASE);
313
314 if (!regexec(&creg, buf, 3, match, 0)) {
315 strncat(result, buf + match[1].rm_so,
316 min(match[1].rm_eo - match[1].rm_so, RESULT_BUF - 1));
317
318 if (!strncasecmp(buf + match[2].rm_so, "NO", 2))
319 r = RESPONSE_NO;
320 else if (!strncasecmp(buf + match[2].rm_so, "BAD", 3))
321 r = RESPONSE_BAD;
322
323 verbose("Server response: %s\n", result);
324 }
325 regfree(&creg);
326
327 return r;
328 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26