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

Annotation of /imapfilter/request.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations)
Mon Sep 10 23:43:29 2001 UTC (22 years, 6 months ago) by lefcha
Branch: MAIN
File MIME type: text/plain
New imapfilter.

1 lefcha 1.1 #include <stdio.h>
2     #include <stdlib.h>
3     #include <string.h>
4    
5     #include "config.h"
6     #include "imapfilter.h"
7     #include "data.h"
8    
9    
10     extern unsigned int options;
11    
12    
13     /*
14     * Test/ping server.
15     */
16     int test(void)
17     {
18     imap_noop();
19     return server_response();
20     }
21    
22    
23     /*
24     * Login to server.
25     */
26     int login(char *user, char *pass)
27     {
28     imap_login(user, pass);
29     return server_response();
30     }
31    
32    
33     /*
34     * Open mailbox in read-only mode and print information about it's status.
35     */
36     int examine_mailbox(char *mbox)
37     {
38     int r;
39    
40     imap_examine(mbox);
41     r = server_response();
42    
43     if (!(options & OPTION_DETAILS_QUITE) && !r) {
44     imap_status(mbox, "MESSAGES RECENT UNSEEN");
45     info(" Mailbox's %s status: ", mbox);
46     status_response();
47     }
48    
49     return r;
50     }
51    
52    
53     /*
54     * Open mailbox in read-write mode.
55     */
56     int select_mailbox(char *mbox)
57     {
58     imap_select(mbox);
59     return server_response();
60     }
61    
62    
63     /*
64     * Close examined/selected mailbox.
65     */
66     int close_mailbox(void)
67     {
68     imap_close();
69     return server_response();
70     }
71    
72    
73     /*
74     * Logout from server.
75     */
76     int logout(void)
77     {
78     imap_logout();
79     return server_response();
80     }
81    
82    
83     /*
84     * Match and apply filters assigned to a mailbox.
85     */
86     int apply_filters(filter_t ** filters, char *mbox)
87     {
88     int i, ro;
89     char mesgs[SEARCH_MESSAGES_BUF];
90    
91     ro = 1;
92    
93     for (i = 0; filters[i]; i++) {
94    
95     mesgs[0] = 0;
96    
97     if (match_filter(filters[i], mesgs))
98     continue;
99    
100     if (ro) {
101     close_mailbox();
102     select_mailbox(mbox);
103     } else
104     ro = 0;
105    
106     apply_action(mesgs, filters[i]->action.type, filters[i]->action.args);
107     }
108    
109     return 0;
110     }
111    
112    
113     /*
114     * Generate the search request by the masks of the filter and try to
115     * match the generated filter.
116     */
117     int match_filter(filter_t * filter, char *mesgs)
118     {
119     char search[SEARCH_BUF]; /* Search string generated. */
120    
121     search[0] = 0;
122    
123     if (filter->mode == FILTER_MODE_OR)
124     generate_filter_or(search, filter->masks);
125     else
126     generate_filter_and(search, filter->masks);
127    
128     if (imap_search(search) || search_response(mesgs) || !mesgs[0])
129     return 1;
130    
131     return 0;
132     }
133    
134    
135     /*
136     * Empty the FIFO inventory.
137     */
138     void empty_fifo(mask_t ** mfifo)
139     {
140     mfifo[0] = NULL;
141    
142     to_fifo(NULL, NULL);
143     from_fifo(NULL);
144     }
145    
146    
147     /*
148     * Add item to FIFO inventory.
149     */
150     void to_fifo(mask_t ** mfifo, mask_t * mask)
151     {
152     static int i;
153    
154     if (!mfifo) {
155     i = 0;
156     return;
157     }
158    
159     mfifo[i++] = mask;
160     mfifo[i] = NULL;
161     }
162    
163    
164     /*
165     * Get next item from FIFO inventory.
166     */
167     mask_t *from_fifo(mask_t ** mfifo)
168     {
169     static int j;
170    
171     if (!mfifo) {
172     j = 0;
173     return NULL;
174     }
175    
176     return mfifo[j++];
177     }
178    
179    
180     /*
181     * Generate the filter search command from the masks, assuming that
182     * masks are AND-ed.
183     */
184     void generate_filter_and(char *search, mask_t * mask)
185     {
186     int len = 0;
187     mask_t *mfifo[FIFO_MAX]; /* Mailbox FIFO queue. */
188     mask_t *mf; /* Mask returned from FIFO. */
189    
190     empty_fifo(mfifo);
191    
192     strncat(search, "ALL ", SEARCH_BUF - len - 1);
193     len += 5;
194    
195     while (mask) {
196     if (mask->type == MASK_TYPE_OR) {
197    
198     if (len == 5 && strstr(search, "ALL ")) {
199     search[0] = 0;
200     len = 0;
201     }
202    
203     strncat(search, "OR (", SEARCH_BUF - len - 1);
204     len += 4;
205    
206     while ((mf = from_fifo(mfifo))) {
207     strncat(search, mf->body, SEARCH_BUF - len - 1);
208     len = strlen(search);
209     search[len++] = ' ';
210     search[len] = 0;
211     }
212    
213     empty_fifo(mfifo);
214    
215     strncpy(search + len - 1, ") ", SEARCH_BUF - len - 1);
216     len += 2;
217     }
218    
219     to_fifo(mfifo, mask);
220    
221     mask = mask->next;
222     }
223    
224     search[len - 1] = '(';
225     search[len] = 0;
226    
227     while ((mf = from_fifo(mfifo))) {
228     strncat(search, mf->body, SEARCH_BUF - len - 1);
229     len = strlen(search);
230     search[len++] = ' ';
231     search[len] = 0;
232     }
233    
234     if (strchr(search, '(')) {
235     search[len - 1] = ')';
236     search[len] = 0;
237     }
238     }
239    
240    
241     /*
242     * Generate the filter search command from the masks, assuming that
243     * masks are OR-ed
244     */
245     void generate_filter_or(char *search, mask_t * mask)
246     {
247     int len = 0;
248     mask_t *mfifo[FIFO_MAX]; /* Mailbox FIFO queue. */
249     mask_t *mf; /* Mask returned from FIFO. */
250    
251     empty_fifo(mfifo);
252    
253     strncat(search, "ALL ", SEARCH_BUF - len - 1);
254     len += 4;
255    
256     while (mask) {
257     to_fifo(mfifo, mask);
258     mask = mask->next;
259    
260     while (mask && mask->type == MASK_TYPE_AND) {
261     to_fifo(mfifo, mask);
262     mask = mask->next;
263     }
264    
265     if (mask) {
266     if (len == 4 && strstr(search, "ALL ")) {
267     search[0] = 0;
268     len = 0;
269     }
270     strncat(search, "OR ", SEARCH_BUF - len - 1);
271     len += 3;
272     }
273    
274     search[len++] = '(';
275     search[len] = 0;
276    
277     while ((mf = from_fifo(mfifo))) {
278     strncat(search, mf->body, SEARCH_BUF - len - 1);
279     len = strlen(search);
280     search[len++] = ' ';
281     search[len] = 0;
282     }
283    
284     strncpy(search + len - 1, ") ", SEARCH_BUF - len - 1);
285     len++;
286    
287     empty_fifo(mfifo);
288     }
289    
290     search[len - 1] = 0;
291     }
292    
293    
294     /*
295     * Apply the appropriate action.
296     */
297     int apply_action(char *mesgs, unsigned int type, char *args)
298     {
299     unsigned int num;
300    
301     if (!mesgs[0])
302     return 0;
303    
304     num = convert_messages(mesgs);
305    
306     switch (type) {
307     case FILTER_ACTION_DELETE:
308     action_delete(mesgs, args);
309     info(" %d messages deleted.\n", num);
310     break;
311     case FILTER_ACTION_COPY:
312     action_copy(mesgs, args);
313     info(" %d messages copied to mailbox %s.\n", num, args);
314     break;
315     case FILTER_ACTION_MOVE:
316     action_move(mesgs, args);
317     info(" %d messages moved to mailbox %s.\n", num, args);
318     break;
319     case FILTER_ACTION_LIST:
320     action_list(mesgs, args);
321     break;
322     }
323    
324     return 0;
325     }
326    
327    
328     /*
329     * Delete messages and optionally list some of their headers.
330     */
331     int action_delete(char *mesgs, char *args)
332     {
333     const char *delim = " ";
334     char *tok, *cp;
335     char headers[HEADERS_BUF];
336    
337     cp = strdup(mesgs);
338    
339     while ((tok = strsep(&cp, delim))) {
340     if (*args) {
341     imap_fetch(tok, args);
342     fetch_response(headers);
343     log_info(headers);
344     }
345     imap_store(tok, "\\Deleted");
346     server_response();
347     }
348    
349     free(cp);
350    
351     return 0;
352     }
353    
354    
355     /*
356     * Copy messages to specified mailbox.
357     */
358     int action_copy(char *mesgs, char *mbox)
359     {
360     const char *delim = " ";
361     char *tok, *cp;
362    
363     cp = strdup(mesgs);
364    
365     while ((tok = strsep(&cp, delim))) {
366     imap_copy(tok, mbox);
367     if (copy_response() == 1) {
368     imap_create(mbox);
369     if (!server_response()) {
370     imap_copy(tok, mbox);
371     copy_response();
372     }
373     }
374     }
375    
376     free(cp);
377    
378     return 0;
379     }
380    
381    
382     /*
383     * Move messages to specified mailbox.
384     */
385     int action_move(char *mesgs, char *mbox)
386     {
387     action_copy(mesgs, mbox);
388     action_delete(mesgs, "\0");
389     imap_expunge();
390     server_response();
391    
392     return 0;
393     }
394    
395    
396     /*
397     * List user selected headers of messages.
398     */
399     int action_list(char *mesgs, char *args)
400     {
401     const char *delim = " ";
402     char *tok, *cp, *occur;
403     char headers[HEADERS_BUF];
404    
405     while ((occur = strchr(args, ',')))
406     *occur = ' ';
407    
408     cp = strdup(mesgs);
409    
410     while ((tok = strsep(&cp, delim))) {
411     imap_fetch(tok, args);
412     fetch_response(headers);
413     info(headers);
414     }
415    
416     free(cp);
417    
418     return 0;
419     }
420    
421    
422     /*
423     * Convert messages with contiguous sequense number to the corresponding
424     * number range, eg. 5 6 7 => 5:7
425     */
426     unsigned int convert_messages(char *mesgs)
427     {
428     unsigned int num, len;
429     unsigned int start, end, tmp;
430     char *cp, *tail = NULL;
431    
432     num = len = start = end = tmp = 0;
433    
434     cp = strdup(mesgs);
435    
436     start = (unsigned int) strtoul(cp, &tail, 0);
437     num++;
438     end = start;
439    
440     do {
441     if (tail) {
442     tmp = (unsigned int) strtoul(tail, &tail, 0);
443     if (tmp)
444     num++;
445     }
446    
447     if (tmp == end + 1)
448     end++;
449     else {
450     if (start == end)
451     snprintf(mesgs + len, SEARCH_MESSAGES_BUF - len - 1, "%d ",
452     start);
453     else
454     snprintf(mesgs + len, SEARCH_MESSAGES_BUF - len - 1,
455     "%d:%d ", start, end);
456    
457     len = strlen(mesgs);
458     start = end = tmp;
459     }
460     } while (tmp);
461    
462     mesgs[len - 1] = 0;
463    
464     free(cp);
465    
466     return num;
467     }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26