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

Annotation of /imapfilter/response.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.13 - (hide annotations)
Tue Nov 6 17:41:27 2001 UTC (22 years, 4 months ago) by lefcha
Branch: MAIN
Changes since 1.12: +147 -69 lines
File MIME type: text/plain
Dynamically allocate response buffer.

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

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26