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

Annotation of /imapfilter/response.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.14 - (hide annotations)
Thu Nov 8 17:52:06 2001 UTC (22 years, 5 months ago) by lefcha
Branch: MAIN
Changes since 1.13: +139 -164 lines
File MIME type: text/plain
New improved data fetching from server facility.

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.14 unsigned long f, blen, mlen;
148 lefcha 1.13
149 lefcha 1.14 f = blen = mlen = 0;
150 lefcha 1.1
151 lefcha 1.13 do {
152 lefcha 1.14 receive_response(buf);
153     if (!f && (c = strcasestr(buf, "* SEARCH "))) {
154     f = 1;
155    
156     blen = strlen(buf);
157    
158     m = *mesgs = (char *) xmalloc(blen + 1);
159     c += 9;
160    
161     while (*c && (isdigit(*c) || *c == ' '))
162     *(m++) = *(c++);
163     *m = 0;
164     } else {
165     c = buf;
166     blen = strlen(buf);
167     mlen = strlen(*mesgs);
168    
169     *mesgs = (char *) xrealloc(*mesgs, mlen + blen + 1);
170     m = *mesgs + mlen;
171    
172     while (*c && (isdigit(*c) || *c == ' '))
173     *(m++) = *(c++);
174     *m = 0;
175     }
176     } while (!strcasestr(buf, ultostr(tag, 16)));
177 lefcha 1.1
178 lefcha 1.14 return analyze_response(buf);
179 lefcha 1.1 }
180    
181    
182     /*
183 lefcha 1.3 * Process the data that server sent due to IMAP FETCH client request.
184 lefcha 1.1 */
185 lefcha 1.9 int fetch_response(unsigned int tag)
186 lefcha 1.1 {
187 lefcha 1.14 int sa, sb, n, i, f;
188     char s[6];
189     char *b;
190     char buf[RESPONSE_BUF];
191     char hdrs[HEADERS_BUF];
192    
193     hdrs[0] = 0;
194     sa = sb = i = f = 0;
195     s[0] = 0;
196 lefcha 1.6
197 lefcha 1.13 do {
198 lefcha 1.14 receive_response(buf);
199 lefcha 1.13
200 lefcha 1.14 b = buf;
201 lefcha 1.6
202 lefcha 1.14 while (f || (b = strchr(b, '{'))) {
203     if (f) {
204     f = 0;
205     for (; i < HEADERS_BUF - 1 && i < sa - 2; i++) {
206     if (!*b) {
207     f = 1;
208     break;
209     }
210     hdrs[i] = *(b++);
211     }
212     } else {
213     if (b == buf + RESPONSE_BUF - 1) {
214     receive_response(buf);
215     b = buf;
216     }
217     sa = atoi(++b);
218    
219     if (!(b = strchr(b, '}'))) {
220     receive_response(buf);
221     if (buf != (b = strchr(buf, '}'))) {
222     sb = atoi(buf);
223     snprintf(s, 6, "%d%d", sa, sb);
224     sa = atoi(s);
225     }
226     b += 3;
227     } else if ((n = RESPONSE_BUF - 1 - (b - buf)) < 3) {
228     receive_response(buf);
229     b = buf + 3 - n;
230     } else {
231     b += 3;
232     }
233    
234     for (i = 0; i < HEADERS_BUF - 1 && i < sa - 2; i++) {
235     if (!*b) {
236     f = 1;
237     break;
238     }
239     hdrs[i] = *(b++);
240     }
241     }
242    
243     if (!f) {
244     hdrs[i] = 0;
245    
246     if (*hdrs) {
247     if (options & OPTION_HEADERS)
248     info("%s\n", hdrs);
249     log_info(LOG_WRITE, hdrs);
250     } else {
251     log_info(LOG_WRITE, NULL);
252     }
253     } else {
254     break;
255     }
256     }
257     } while (!strcasestr(buf, ultostr(tag, 16)));
258 lefcha 1.6
259 lefcha 1.14 return analyze_response(buf);
260 lefcha 1.1 }
261    
262    
263     /*
264 lefcha 1.3 * Process the data that server sent due to IMAP COPY client request.
265 lefcha 1.1 */
266 lefcha 1.9 int copy_response(unsigned int tag)
267 lefcha 1.1 {
268 lefcha 1.14 char buf[RESPONSE_BUF];
269 lefcha 1.1
270     do
271 lefcha 1.14 receive_response(buf);
272     while (!strcasestr(buf, ultostr(tag, 16)));
273 lefcha 1.1
274 lefcha 1.14 if (analyze_response(buf) == RESPONSE_NO && strcasestr(buf, "[TRYCREATE]"))
275 lefcha 1.9 return RESPONSE_TRYCREATE;
276 lefcha 1.1
277 lefcha 1.9 return RESPONSE_OK;
278 lefcha 1.1 }
279    
280    
281     /*
282 lefcha 1.3 * Check if response of server to client's request was succesfully
283 lefcha 1.1 * delivered or there was some kind of error.
284     */
285 lefcha 1.14 int analyze_response(char *buf)
286 lefcha 1.1 {
287 lefcha 1.9 int r = RESPONSE_OK;
288 lefcha 1.1 regex_t creg;
289     regmatch_t match[3];
290 lefcha 1.9 const char *reg = "[[:xdigit:]]{6,6} ((OK|NO|BAD)[[:print:]]*)\r\n";
291 lefcha 1.14 char result[RESULT_BUF];
292 lefcha 1.1
293 lefcha 1.4 result[0] = 0;
294    
295 lefcha 1.9 regcomp(&creg, reg, REG_EXTENDED | REG_ICASE);
296 lefcha 1.6
297 lefcha 1.14 if (!regexec(&creg, buf, 3, match, 0)) {
298     strncat(result, buf + match[1].rm_so,
299     min(match[1].rm_eo - match[1].rm_so, RESULT_BUF - 1));
300 lefcha 1.1
301 lefcha 1.14 if (!strncasecmp(buf + match[2].rm_so, "NO", 2))
302 lefcha 1.9 r = RESPONSE_NO;
303 lefcha 1.14 else if (!strncasecmp(buf + match[2].rm_so, "BAD", 3))
304 lefcha 1.9 r = RESPONSE_BAD;
305 lefcha 1.6
306 lefcha 1.1 verbose("Server response: %s\n", result);
307     }
308 lefcha 1.6 regfree(&creg);
309 lefcha 1.1
310     return r;
311     }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26