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

Annotation of /imapfilter/response.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.15 - (hide annotations)
Fri Nov 9 15:52:20 2001 UTC (22 years, 4 months ago) by lefcha
Branch: MAIN
Changes since 1.14: +20 -9 lines
File MIME type: text/plain
Headers fetching bug fixes.

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

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26