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

Contents of /imapfilter/imap.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.9 - (show annotations)
Sun Aug 26 01:18:24 2001 UTC (22 years, 7 months ago) by lefcha
Branch: MAIN
Changes since 1.8: +114 -124 lines
File MIME type: text/plain
Structural changes

1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <unistd.h>
5 #include <errno.h>
6
7 #include "config.h"
8 #include "imapfilter.h"
9 #include "imap.h"
10 #include "connect.h"
11 #include "log.h"
12
13
14 extern int sock;
15 extern account_t *accounts;
16 extern filter_t *dfilters, *afilters;
17 extern int options;
18 extern unsigned int dlimit, alimit;
19
20 static int tag = 0xA000; /* Every IMAP command is prefixed with a
21 unique [:alnum:] string. */
22
23
24 /*
25 * Sends to server data; a command.
26 */
27 int send_command(char *cmd)
28 {
29
30 #ifdef DEBUG
31 printf("debug: sending command: %s", cmd);
32 #endif
33
34 if (write(sock, cmd, strlen(cmd)) == -1) {
35 error("imapfilter: error while sending command; %s",
36 strerror(errno));
37 return 1;
38 }
39
40 return 0;
41 }
42
43
44 /*
45 * Calls send_command() and get_response().
46 */
47 int send_command_get_response(char *cmd)
48 {
49 char buf[RESPONSE_BUF];
50
51 if (!send_command(cmd) && !get_response(buf))
52 return 0;
53 else
54 return 1;
55 }
56
57
58 #ifdef DEBUG
59 /*
60 * IMAP NOOP: does nothing always succeeds.
61 */
62 int imap_noop(void)
63 {
64 char cmd[SMALL_CMD];
65
66 verbose("Client request: NOOP\n");
67
68 snprintf(cmd, SMALL_CMD, "%X NOOP\r\n", tag++);
69
70 return send_command_get_response(cmd);
71
72 }
73 #endif
74
75
76 /*
77 * IMAP LOGOUT: informs server that client is done.
78 */
79 int imap_logout(void)
80 {
81 char cmd[SMALL_CMD];
82
83 verbose("Client request: LOGOUT\n");
84
85 snprintf(cmd, SMALL_CMD, "%X LOGOUT\r\n", tag++);
86
87 return send_command_get_response(cmd);
88 }
89
90
91 /*
92 * IMAP LOGIN: identifies client to server.
93 */
94 int imap_login(account_t * ca)
95 {
96 char cmd[MEDIUM_CMD];
97
98 verbose("Client request: LOGIN\n");
99
100 snprintf(cmd, MEDIUM_CMD, "%X LOGIN \"%s\" \"%s\"\r\n",
101 tag++, ca->userid, ca->passwd);
102
103 return send_command_get_response(cmd);
104 }
105
106
107 /*
108 * IMAP SELECT: selects a mailbox in which messages can be accessed.
109 */
110 int imap_select(void)
111 {
112 char cmd[SMALL_CMD];
113
114 verbose("Client request: SELECT\n");
115
116 snprintf(cmd, SMALL_CMD, "%X SELECT INBOX\r\n", tag++);
117
118 if (!send_command(cmd) && !select_response())
119 return 0;
120 else
121 return 1;
122 }
123
124 /*
125 * IMAP SEARCH: searches the mailbox for messages that match certain criteria.
126 */
127 int imap_search(char *res)
128 {
129 char cmd[BIG_CMD];
130
131 verbose("Client request: SEARCH\n");
132
133 generate_search_filters(cmd);
134 if (send_command(cmd))
135 return 1;
136 search_response(res);
137
138 verbose("Client request: SEARCH\n");
139
140 if (alimit && afilters) {
141 generate_search_limits(cmd);
142 if (send_command(cmd))
143 return 1;
144 search_response(res);
145 }
146
147 return 0;
148 }
149
150
151 /*
152 * IMAP FETCH: retrieves data associated with a message.
153 */
154 int imap_fetch(unsigned int msg, char *res)
155 {
156 char cmd[MEDIUM_CMD];
157
158 verbose("Client request: FETCH\n");
159
160 snprintf(cmd, MEDIUM_CMD,
161 "%X FETCH %d BODY[HEADER.FIELDS (\"DATE\" \"FROM\" \"SUBJECT\")]\r\n",
162 tag++, msg);
163
164 if (!send_command(cmd) && !fetch_response(res))
165 return 0;
166 else
167 return 1;
168 }
169
170
171 /*
172 * IMAP STORE: alters data associated with a message.
173 */
174 int imap_store(unsigned int msg)
175 {
176 char cmd[MEDIUM_CMD];
177
178 verbose("Client request: STORE\n");
179
180 snprintf(cmd, MEDIUM_CMD,
181 "%X STORE %d +FLAGS \\Deleted\r\n", tag++, msg);
182
183 return send_command_get_response(cmd);
184 }
185
186
187 /*
188 * IMAP EXPUNGE: premanently removes any messages with the \Deleted flag set.
189 */
190 int imap_expunge(void)
191 {
192 char cmd[SMALL_CMD];
193
194 verbose("Client request: EXPUNGE\n");
195
196 snprintf(cmd, SMALL_CMD, "%X EXPUNGE\r\n", tag++);
197
198 return send_command_get_response(cmd);
199 }
200
201
202 /*
203 * Prepares according to the filters defined by the user the IMAP SEARCH
204 * command that will be sent. This command will search for DENY, ALLOW,
205 * and DENY_LIMIT filters.
206 */
207 void generate_search_filters(char *cmd)
208 {
209 int len;
210
211 snprintf(cmd, BIG_CMD, "%X SEARCH", tag++);
212
213 deny_filters(cmd);
214
215 if (dlimit) {
216 len = strlen(cmd);
217 snprintf(cmd + len, BIG_CMD - len, " LARGER %d", dlimit);
218 } else if (!dfilters) { /* If no DENY filters were defined, then
219 deny all except the ALLOW filters. */
220 len = strlen(cmd);
221 snprintf(cmd + len, BIG_CMD - len, " ALL");
222 }
223
224 allow_filters(cmd, "NOT");
225
226 len = strlen(cmd);
227 snprintf(cmd + len, BIG_CMD - len, "\r\n");
228 }
229
230
231 /*
232 * Prepares according to the filters defined by the user the IMAP SEARCH
233 * command that will be sent. This command will search for the ALLOW_LIMIT
234 * filter.
235 */
236 void generate_search_limits(char *cmd)
237 {
238 int len;
239
240 snprintf(cmd, BIG_CMD, "%X SEARCH", tag++);
241
242 allow_filters(cmd, "OR");
243
244 len = strlen(cmd);
245 snprintf(cmd + len, BIG_CMD - len, " LARGER %d", alimit);
246
247 len = strlen(cmd);
248 snprintf(cmd + len, BIG_CMD - len, "\r\n");
249
250 }
251
252
253 /*
254 * Adds to the IMAP SEARCH command all the DENY type filters.
255 */
256 void deny_filters(char *cmd)
257 {
258 int len;
259 filter_t *cdf;
260
261 if (dfilters) {
262 for (cdf = dfilters; cdf->next; cdf = cdf->next) {
263 len = strlen(cmd);
264 snprintf(cmd + len, BIG_CMD - len,
265 " OR %s%s \"%s\"",
266 custom_header(cdf->custom), cdf->name, cdf->body);
267 }
268
269 len = strlen(cmd);
270 snprintf(cmd + len, BIG_CMD - len, " %s%s%s \"%s\"",
271 (dlimit ? "OR " : ""),
272 custom_header(cdf->custom), cdf->name, cdf->body);
273 }
274 }
275
276
277 /*
278 * Adds to IMAP SEARCH command all the ALLOW type filters.
279 */
280 void allow_filters(char *cmd, char *key)
281 {
282 int len;
283 filter_t *caf;
284
285 if (afilters) {
286 for (caf = afilters; caf->next; caf = caf->next) {
287 len = strlen(cmd);
288 snprintf(cmd + len, BIG_CMD - len,
289 " %s %s%s \"%s\"", key,
290 custom_header(caf->custom), caf->name, caf->body);
291 }
292
293 len = strlen(cmd);
294 snprintf(cmd + len, BIG_CMD - len, " %s%s%s \"%s\"",
295 (!strncmp(key, "NOT", 3) ? "NOT " : ""),
296 custom_header(caf->custom), caf->name, caf->body);
297 }
298 }
299
300
301 /*
302 * Converts the string with the UID's of the messages to be deleted to
303 * integers, sends the appropriate command and optionally prints some
304 * headers of the "to be deleted" messages.
305 */
306 void delete_messages(char *msgs)
307 {
308 unsigned long int m;
309 char hdr[HEADERS_MAX];
310
311 do {
312 m = strtoul(msgs, &msgs, 0);
313
314 if (options & OPT_SHOW_HEADERS) {
315 imap_fetch(m, hdr);
316
317 if (!(options & OPT_DETAILS_QUITE))
318 printf("Deleting message:\n%s", hdr);
319
320 if (!(options & OPT_TEST_MODE))
321 log_info("%s", hdr);
322 }
323
324 if (!(options & OPT_TEST_MODE))
325 imap_store(m);
326
327 } while (*msgs);
328 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26