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

Contents of /imapfilter/response.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.10 - (show annotations)
Wed Oct 17 14:06:20 2001 UTC (22 years, 6 months ago) by lefcha
Branch: MAIN
Changes since 1.9: +4 -31 lines
File MIME type: text/plain
Added SSL/TLS support.

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 data the server sent.
20 */
21 int receive_response(char *buf)
22 {
23 socket_read(buf);
24
25 #ifdef DEBUG
26 printf("\n%s\n", buf);
27 #endif
28
29 return analyze_response(buf);
30 }
31
32
33 /*
34 * Get server response to client's request.
35 */
36 int server_response(unsigned int tag)
37 {
38 int r;
39 char buf[RESPONSE_BUF];
40
41 do
42 r = receive_response(buf);
43 while (tag && !strcasestr(buf, ultostr(tag, 16)));
44
45 return r;
46 }
47
48
49 /*
50 * Process the greeting that server sends during connection.
51 */
52 int greeting_response(void)
53 {
54 char buf[RESPONSE_BUF];
55
56 receive_response(buf);
57
58 if (strcasestr(buf, "BYE"))
59 return RESPONSE_BYE;
60
61 return RESPONSE_OK;
62 }
63
64 /*
65 * Process the data that server sent due to IMAP CAPABILITY client request.
66 */
67 int capability_response(unsigned int tag)
68 {
69 int r;
70 char buf[RESPONSE_BUF];
71
72 do
73 r = 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 r;
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)
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 r = receive_response(buf);
98 while (!strcasestr(buf, ultostr(tag, 16)));
99
100 if ((c = strcasestr(buf, "MESSAGES"))) {
101 c += 9;
102 exist = strtoul(c, NULL, 10);
103 }
104 if ((c = strcasestr(buf, "RECENT"))) {
105 c += 7;
106 recent = strtoul(c, NULL, 10);
107 }
108 if ((c = strcasestr(buf, "UNSEEN"))) {
109 c += 7;
110 unseen = strtoul(c, NULL, 10);
111 }
112 if (!exist) {
113 info("No messages ");
114 return -2;
115 }
116 info("%d message%s, %d recent, %d unseen, ", exist, plural(exist),
117 recent, unseen);
118
119 return r;
120 }
121
122
123 /*
124 * Process the data that server sent due to IMAP SELECT client request.
125 */
126 int select_response(unsigned int tag)
127 {
128 int r;
129 char buf[RESPONSE_BUF];
130
131 do
132 r = receive_response(buf);
133 while (!strcasestr(buf, ultostr(tag, 16)));
134
135 if (strcasestr(buf, "[READ-ONLY]"))
136 return RESPONSE_READONLY;
137
138 return r;
139 }
140
141
142 /*
143 * Process the data that server sent due to IMAP SEARCH client request.
144 */
145 int search_response(unsigned int tag, char *mesgs)
146 {
147 int r;
148 char buf[RESPONSE_BUF];
149 char *c, *m = mesgs;
150
151 do
152 r = receive_response(buf);
153 while (!strcasestr(buf, ultostr(tag, 16)));
154
155 if ((c = strcasestr(buf, "SEARCH "))) {
156 c += 7;
157 while (mesgs - m < 512 && (isdigit(*c) || *c == ' '))
158 *(m++) = *(c++);
159 *m = 0;
160 }
161
162 return r;
163 }
164
165
166 /*
167 * Process the data that server sent due to IMAP FETCH client request.
168 */
169 int fetch_response(unsigned int tag)
170 {
171 int r, s, i;
172 char buf[RESPONSE_BUF];
173 char *pos;
174 char headers[HEADERS_BUF];
175
176 headers[0] = 0;
177
178 do
179 r = receive_response(buf);
180 while (!strcasestr(buf, ultostr(tag, 16)));
181
182 pos = buf;
183
184 while ((pos = strchr(pos, '{'))) {
185 s = atoi(pos + 1);
186 pos = strchr(pos, '}');
187
188 for (i = 0; i < HEADERS_BUF - 1 && i < s - 2; i++)
189 headers[i] = *(pos + 3 + i);
190
191 headers[i] = 0;
192 pos += i;
193
194 if (*headers) {
195 if (options & OPTION_HEADERS)
196 info("%s\n", headers);
197 log_info(LOG_WRITE, headers);
198 } else
199 log_info(LOG_WRITE, NULL);
200 }
201
202 return r;
203 }
204
205
206 /*
207 * Process the data that server sent due to IMAP COPY client request.
208 */
209 int copy_response(unsigned int tag)
210 {
211 int r;
212 char buf[RESPONSE_BUF];
213
214 do
215 r = receive_response(buf);
216 while (!strcasestr(buf, ultostr(tag, 16)));
217
218 if (r == RESPONSE_NO && strcasestr(buf, "[TRYCREATE]"))
219 return RESPONSE_TRYCREATE;
220
221 return RESPONSE_OK;
222 }
223
224
225 /*
226 * Check if response of server to client's request was succesfully
227 * delivered or there was some kind of error.
228 */
229 int analyze_response(char *buf)
230 {
231 int r = RESPONSE_OK;
232 regex_t creg;
233 regmatch_t match[3];
234 const char *reg = "[[:xdigit:]]{6,6} ((OK|NO|BAD)[[:print:]]*)\r\n";
235 char result[RESULT_BUF];
236
237 result[0] = 0;
238
239 regcomp(&creg, reg, REG_EXTENDED | REG_ICASE);
240
241 if (!regexec(&creg, buf, 3, match, 0)) {
242 strncat(result, buf + match[1].rm_so,
243 min(match[1].rm_eo - match[1].rm_so, RESULT_BUF - 1));
244
245 if (!strncasecmp(buf + match[2].rm_so, "NO", 2))
246 r = RESPONSE_NO;
247 else if (!strncasecmp(buf + match[2].rm_so, "BAD", 3))
248 r = RESPONSE_BAD;
249
250 verbose("Server response: %s\n", result);
251 }
252 regfree(&creg);
253
254 return r;
255 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26