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

Contents of /imapfilter/imap.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.10 - (show annotations)
Sun Aug 26 12:26:59 2001 UTC (22 years, 7 months ago) by lefcha
Branch: MAIN
Changes since 1.9: +18 -1 lines
File MIME type: text/plain
Exist, recent, unseen messages found in mailbox.

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 return send_command_get_response(cmd);
119 }
120
121
122 /*
123 * IMAP STATUS: requests status of the indicated mailbox.
124 */
125 int imap_status(void)
126 {
127 char cmd[MEDIUM_CMD];
128
129 verbose("Client request: STATUS\n");
130
131 snprintf(cmd, MEDIUM_CMD,
132 "%X STATUS INBOX (MESSAGES RECENT UNSEEN)\r\n", tag++);
133
134 if (!send_command(cmd) && !status_response())
135 return 0;
136 else
137 return 1;
138 }
139
140
141 /*
142 * IMAP SEARCH: searches the mailbox for messages that match certain criteria.
143 */
144 int imap_search(char *res)
145 {
146 char cmd[BIG_CMD];
147
148 verbose("Client request: SEARCH\n");
149
150 generate_search_filters(cmd);
151 if (send_command(cmd))
152 return 1;
153 search_response(res);
154
155 verbose("Client request: SEARCH\n");
156
157 if (alimit && afilters) {
158 generate_search_limits(cmd);
159 if (send_command(cmd))
160 return 1;
161 search_response(res);
162 }
163
164 return 0;
165 }
166
167
168 /*
169 * IMAP FETCH: retrieves data associated with a message.
170 */
171 int imap_fetch(unsigned int msg, char *res)
172 {
173 char cmd[MEDIUM_CMD];
174
175 verbose("Client request: FETCH\n");
176
177 snprintf(cmd, MEDIUM_CMD,
178 "%X FETCH %d BODY[HEADER.FIELDS (\"DATE\" \"FROM\" \"SUBJECT\")]\r\n",
179 tag++, msg);
180
181 if (!send_command(cmd) && !fetch_response(res))
182 return 0;
183 else
184 return 1;
185 }
186
187
188 /*
189 * IMAP STORE: alters data associated with a message.
190 */
191 int imap_store(unsigned int msg)
192 {
193 char cmd[MEDIUM_CMD];
194
195 verbose("Client request: STORE\n");
196
197 snprintf(cmd, MEDIUM_CMD,
198 "%X STORE %d +FLAGS \\Deleted\r\n", tag++, msg);
199
200 return send_command_get_response(cmd);
201 }
202
203
204 /*
205 * IMAP EXPUNGE: premanently removes any messages with the \Deleted flag set.
206 */
207 int imap_expunge(void)
208 {
209 char cmd[SMALL_CMD];
210
211 verbose("Client request: EXPUNGE\n");
212
213 snprintf(cmd, SMALL_CMD, "%X EXPUNGE\r\n", tag++);
214
215 return send_command_get_response(cmd);
216 }
217
218
219 /*
220 * Prepares according to the filters defined by the user the IMAP SEARCH
221 * command that will be sent. This command will search for DENY, ALLOW,
222 * and DENY_LIMIT filters.
223 */
224 void generate_search_filters(char *cmd)
225 {
226 int len;
227
228 snprintf(cmd, BIG_CMD, "%X SEARCH", tag++);
229
230 deny_filters(cmd);
231
232 if (dlimit) {
233 len = strlen(cmd);
234 snprintf(cmd + len, BIG_CMD - len, " LARGER %d", dlimit);
235 } else if (!dfilters) { /* If no DENY filters were defined, then
236 deny all except the ALLOW filters. */
237 len = strlen(cmd);
238 snprintf(cmd + len, BIG_CMD - len, " ALL");
239 }
240
241 allow_filters(cmd, "NOT");
242
243 len = strlen(cmd);
244 snprintf(cmd + len, BIG_CMD - len, "\r\n");
245 }
246
247
248 /*
249 * Prepares according to the filters defined by the user the IMAP SEARCH
250 * command that will be sent. This command will search for the ALLOW_LIMIT
251 * filter.
252 */
253 void generate_search_limits(char *cmd)
254 {
255 int len;
256
257 snprintf(cmd, BIG_CMD, "%X SEARCH", tag++);
258
259 allow_filters(cmd, "OR");
260
261 len = strlen(cmd);
262 snprintf(cmd + len, BIG_CMD - len, " LARGER %d", alimit);
263
264 len = strlen(cmd);
265 snprintf(cmd + len, BIG_CMD - len, "\r\n");
266
267 }
268
269
270 /*
271 * Adds to the IMAP SEARCH command all the DENY type filters.
272 */
273 void deny_filters(char *cmd)
274 {
275 int len;
276 filter_t *cdf;
277
278 if (dfilters) {
279 for (cdf = dfilters; cdf->next; cdf = cdf->next) {
280 len = strlen(cmd);
281 snprintf(cmd + len, BIG_CMD - len,
282 " OR %s%s \"%s\"",
283 custom_header(cdf->custom), cdf->name, cdf->body);
284 }
285
286 len = strlen(cmd);
287 snprintf(cmd + len, BIG_CMD - len, " %s%s%s \"%s\"",
288 (dlimit ? "OR " : ""),
289 custom_header(cdf->custom), cdf->name, cdf->body);
290 }
291 }
292
293
294 /*
295 * Adds to IMAP SEARCH command all the ALLOW type filters.
296 */
297 void allow_filters(char *cmd, char *key)
298 {
299 int len;
300 filter_t *caf;
301
302 if (afilters) {
303 for (caf = afilters; caf->next; caf = caf->next) {
304 len = strlen(cmd);
305 snprintf(cmd + len, BIG_CMD - len,
306 " %s %s%s \"%s\"", key,
307 custom_header(caf->custom), caf->name, caf->body);
308 }
309
310 len = strlen(cmd);
311 snprintf(cmd + len, BIG_CMD - len, " %s%s%s \"%s\"",
312 (!strncmp(key, "NOT", 3) ? "NOT " : ""),
313 custom_header(caf->custom), caf->name, caf->body);
314 }
315 }
316
317
318 /*
319 * Converts the string with the UID's of the messages to be deleted to
320 * integers, sends the appropriate command and optionally prints some
321 * headers of the "to be deleted" messages.
322 */
323 void delete_messages(char *msgs)
324 {
325 unsigned long int m;
326 char hdr[HEADERS_MAX];
327
328 do {
329 m = strtoul(msgs, &msgs, 0);
330
331 if (options & OPT_SHOW_HEADERS) {
332 imap_fetch(m, hdr);
333
334 if (!(options & OPT_DETAILS_QUITE))
335 printf("Deleting message:\n%s", hdr);
336
337 if (!(options & OPT_TEST_MODE))
338 log_info("%s", hdr);
339 }
340
341 if (!(options & OPT_TEST_MODE))
342 imap_store(m);
343
344 } while (*msgs);
345 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26