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

Annotation of /imapfilter/response.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.9.2.2 - (hide annotations)
Wed Oct 31 20:54:20 2001 UTC (22 years, 5 months ago) by lefcha
Branch: release-0_6_2-patches
Changes since 1.9.2.1: +5 -2 lines
File MIME type: text/plain
A small correction.

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 <fcntl.h>
8     #include <sys/time.h>
9     #include <sys/types.h>
10     #include <regex.h>
11    
12    
13     #include "config.h"
14     #include "imapfilter.h"
15    
16    
17     extern int sock;
18     extern unsigned int options;
19    
20    
21     /*
22 lefcha 1.3 * Read data the server sent.
23 lefcha 1.1 */
24     int receive_response(char *buf)
25     {
26     int flags;
27     fd_set fds;
28     struct timeval tv;
29    
30     memset(buf, 0, RESPONSE_BUF);
31    
32 lefcha 1.2 tv.tv_sec = 20;
33 lefcha 1.1 tv.tv_usec = 0;
34    
35     flags = fcntl(sock, F_GETFL, 0);
36     fcntl(sock, F_SETFL, flags | O_NONBLOCK);
37    
38     FD_ZERO(&fds);
39     FD_SET(sock, &fds);
40    
41     if ((select(sock + 1, &fds, NULL, NULL, &tv) > 0)
42     && FD_ISSET(sock, &fds)) {
43     if (read(sock, buf, RESPONSE_BUF - 1) != -1) {
44     #ifdef DEBUG
45     printf("\n%s\n", buf);
46     #endif
47     fcntl(sock, F_SETFL, flags);
48    
49     return analyze_response(buf);
50     }
51     }
52 lefcha 1.6 fcntl(sock, F_SETFL, flags);
53 lefcha 1.1
54 lefcha 1.4 fatal(ERROR_NETWORK, "imapfilter: waiting input from socket; %s\n",
55     strerror(errno));
56 lefcha 1.6
57 lefcha 1.4 return ERROR_NETWORK;
58 lefcha 1.1 }
59    
60    
61     /*
62     * Get server response to client's request.
63     */
64 lefcha 1.9 int server_response(unsigned int tag)
65 lefcha 1.1 {
66 lefcha 1.4 int r;
67 lefcha 1.1 char buf[RESPONSE_BUF];
68 lefcha 1.6
69 lefcha 1.4 do
70     r = receive_response(buf);
71 lefcha 1.9 while (tag && !strcasestr(buf, ultostr(tag, 16)));
72 lefcha 1.6
73 lefcha 1.4 return r;
74 lefcha 1.1 }
75    
76    
77     /*
78 lefcha 1.9 * Process the greeting that server sends during connection.
79     */
80     int greeting_response(void)
81     {
82     char buf[RESPONSE_BUF];
83    
84     receive_response(buf);
85    
86     if (strcasestr(buf, "BYE"))
87     return RESPONSE_BYE;
88    
89     return RESPONSE_OK;
90     }
91    
92     /*
93     * Process the data that server sent due to IMAP CAPABILITY client request.
94     */
95     int capability_response(unsigned int tag)
96     {
97     int r;
98     char buf[RESPONSE_BUF];
99    
100     do
101     r = receive_response(buf);
102     while (!strcasestr(buf, ultostr(tag, 16)));
103    
104     if (!strcasestr(buf, "IMAP4rev1")) {
105     error("imapfilter: server does not support IMAP4rev1 protocol\n");
106     return -2;
107     }
108     return r;
109     }
110    
111    
112     /*
113 lefcha 1.3 * Process the data that server sent due to IMAP STATUS client request.
114 lefcha 1.1 */
115 lefcha 1.9 int status_response(unsigned int tag)
116 lefcha 1.1 {
117     int r;
118     char buf[RESPONSE_BUF];
119     unsigned int exist, recent, unseen;
120 lefcha 1.9 char *c;
121 lefcha 1.1
122     exist = recent = unseen = 0;
123    
124     do
125     r = receive_response(buf);
126 lefcha 1.9 while (!strcasestr(buf, ultostr(tag, 16)));
127 lefcha 1.1
128 lefcha 1.9 if ((c = strcasestr(buf, "MESSAGES"))) {
129     c += 9;
130     exist = strtoul(c, NULL, 10);
131     }
132     if ((c = strcasestr(buf, "RECENT"))) {
133     c += 7;
134     recent = strtoul(c, NULL, 10);
135     }
136     if ((c = strcasestr(buf, "UNSEEN"))) {
137     c += 7;
138     unseen = strtoul(c, NULL, 10);
139     }
140 lefcha 1.8 if (!exist) {
141     info("No messages ");
142     return -2;
143     }
144 lefcha 1.9 info("%d message%s, %d recent, %d unseen, ", exist, plural(exist),
145     recent, unseen);
146    
147     return r;
148     }
149    
150    
151     /*
152     * Process the data that server sent due to IMAP SELECT client request.
153     */
154     int select_response(unsigned int tag)
155     {
156     int r;
157     char buf[RESPONSE_BUF];
158    
159     do
160     r = receive_response(buf);
161     while (!strcasestr(buf, ultostr(tag, 16)));
162    
163     if (strcasestr(buf, "[READ-ONLY]"))
164     return RESPONSE_READONLY;
165 lefcha 1.1
166     return r;
167     }
168    
169    
170     /*
171 lefcha 1.3 * Process the data that server sent due to IMAP SEARCH client request.
172 lefcha 1.1 */
173 lefcha 1.9 int search_response(unsigned int tag, char *mesgs)
174 lefcha 1.1 {
175     int r;
176     char buf[RESPONSE_BUF];
177 lefcha 1.9 char *c, *m = mesgs;
178 lefcha 1.1
179     do
180     r = receive_response(buf);
181 lefcha 1.9 while (!strcasestr(buf, ultostr(tag, 16)));
182 lefcha 1.1
183 lefcha 1.9 if ((c = strcasestr(buf, "SEARCH "))) {
184     c += 7;
185 lefcha 1.9.2.1 while (m - mesgs < SEARCH_MESSAGES_BUF && (isdigit(*c) || *c == ' '))
186 lefcha 1.9 *(m++) = *(c++);
187 lefcha 1.9.2.2 if (m - mesgs == SEARCH_MESSAGES_BUF)
188     *(strrchr(mesgs, ' ')) = 0;
189     else
190     *m = 0;
191 lefcha 1.9 }
192 lefcha 1.9.2.2
193 lefcha 1.1 return r;
194     }
195    
196    
197     /*
198 lefcha 1.3 * Process the data that server sent due to IMAP FETCH client request.
199 lefcha 1.1 */
200 lefcha 1.9 int fetch_response(unsigned int tag)
201 lefcha 1.1 {
202     int r, s, i;
203     char buf[RESPONSE_BUF];
204     char *pos;
205 lefcha 1.4 char headers[HEADERS_BUF];
206 lefcha 1.6
207 lefcha 1.4 headers[0] = 0;
208 lefcha 1.6
209 lefcha 1.1 do
210     r = receive_response(buf);
211 lefcha 1.9 while (!strcasestr(buf, ultostr(tag, 16)));
212 lefcha 1.6
213 lefcha 1.4 pos = buf;
214 lefcha 1.1
215 lefcha 1.6 while ((pos = strchr(pos, '{'))) {
216 lefcha 1.4 s = atoi(pos + 1);
217     pos = strchr(pos, '}');
218 lefcha 1.8
219 lefcha 1.4 for (i = 0; i < HEADERS_BUF - 1 && i < s - 2; i++)
220     headers[i] = *(pos + 3 + i);
221 lefcha 1.6
222 lefcha 1.4 headers[i] = 0;
223 lefcha 1.6
224 lefcha 1.7 if (*headers) {
225     if (options & OPTION_HEADERS)
226     info("%s\n", headers);
227 lefcha 1.6 log_info(LOG_WRITE, headers);
228 lefcha 1.7 } else
229 lefcha 1.6 log_info(LOG_WRITE, NULL);
230 lefcha 1.4 }
231 lefcha 1.6
232 lefcha 1.1 return r;
233     }
234    
235    
236     /*
237 lefcha 1.3 * Process the data that server sent due to IMAP COPY client request.
238 lefcha 1.1 */
239 lefcha 1.9 int copy_response(unsigned int tag)
240 lefcha 1.1 {
241     int r;
242     char buf[RESPONSE_BUF];
243    
244     do
245     r = receive_response(buf);
246 lefcha 1.9 while (!strcasestr(buf, ultostr(tag, 16)));
247 lefcha 1.1
248 lefcha 1.9 if (r == RESPONSE_NO && strcasestr(buf, "[TRYCREATE]"))
249     return RESPONSE_TRYCREATE;
250 lefcha 1.1
251 lefcha 1.9 return RESPONSE_OK;
252 lefcha 1.1 }
253    
254    
255     /*
256 lefcha 1.3 * Check if response of server to client's request was succesfully
257 lefcha 1.1 * delivered or there was some kind of error.
258     */
259     int analyze_response(char *buf)
260     {
261 lefcha 1.9 int r = RESPONSE_OK;
262 lefcha 1.1 regex_t creg;
263     regmatch_t match[3];
264 lefcha 1.9 const char *reg = "[[:xdigit:]]{6,6} ((OK|NO|BAD)[[:print:]]*)\r\n";
265 lefcha 1.1 char result[RESULT_BUF];
266    
267 lefcha 1.4 result[0] = 0;
268    
269 lefcha 1.9 regcomp(&creg, reg, REG_EXTENDED | REG_ICASE);
270 lefcha 1.6
271 lefcha 1.1 if (!regexec(&creg, buf, 3, match, 0)) {
272 lefcha 1.4 strncat(result, buf + match[1].rm_so,
273     min(match[1].rm_eo - match[1].rm_so, RESULT_BUF - 1));
274 lefcha 1.1
275 lefcha 1.9 if (!strncasecmp(buf + match[2].rm_so, "NO", 2))
276     r = RESPONSE_NO;
277     else if (!strncasecmp(buf + match[2].rm_so, "BAD", 3))
278     r = RESPONSE_BAD;
279 lefcha 1.6
280 lefcha 1.1 verbose("Server response: %s\n", result);
281     }
282 lefcha 1.6 regfree(&creg);
283 lefcha 1.1
284     return r;
285     }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26