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

Annotation of /imapfilter/match.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations)
Thu Jul 31 15:46:02 2003 UTC (20 years, 8 months ago) by lefcha
Branch: MAIN
CVS Tags: release-0_9
Branch point for: release-0_9-patches
File MIME type: text/plain
Broke up program files and created some new header files.

1 lefcha 1.1 #include <stdio.h>
2     #include <string.h>
3    
4     #include "config.h"
5     #include "imapfilter.h"
6     #include "account.h"
7     #include "filter.h"
8    
9    
10     extern conn_t connpri, connaux;
11     extern char charset[CHARSET_LEN];
12    
13    
14     int match_filter(filter_t * filter, char **mesgs);
15    
16     char *generate_filter_and(mask_t * mask, unsigned int masknum, unsigned int masklen);
17     char *generate_filter_or(mask_t * mask, unsigned int masknum, unsigned int masklen);
18    
19     void empty_fifo(mask_t ** mfifo);
20     void queue_fifo(mask_t ** mfifo, mask_t * mask);
21     mask_t *dequeue_fifo(mask_t ** mfifo);
22    
23    
24     /*
25     * Match and apply filters assigned to a mailbox.
26     */
27     int
28     apply_filters(char *mbox, filter_t ** filters)
29     {
30     int i;
31     char *mesgs;
32    
33     for (i = 0; filters[i] != NULL; i++) {
34     mesgs = NULL;
35    
36     if (match_filter(filters[i], &mesgs))
37     continue;
38    
39     log_info(LOG_FILTER, filters[i]->key);
40    
41     apply_action(mbox, mesgs, &(filters[i]->action.type),
42     filters[i]->action.raccount, filters[i]->action.destmbox,
43     &filters[i]->action.msgflags, filters[i]->action.args);
44    
45     xfree(mesgs);
46     }
47    
48     return 0;
49     }
50    
51    
52     /*
53     * Generate the search request by the masks of the filter and try to
54     * match the generated filter.
55     */
56     int
57     match_filter(filter_t * filter, char **mesgs)
58     {
59     char *search;
60    
61     if (filter->mode == FILTER_MODE_OR)
62     search = generate_filter_or(filter->masks, filter->masknum,
63     filter->masklen);
64     else
65     search = generate_filter_and(filter->masks, filter->masknum,
66     filter->masklen);
67    
68     search_response(&connpri, imap_search(&connpri, charset, search),
69     mesgs);
70    
71     xfree(search);
72    
73     if (*mesgs == '\0')
74     return 1;
75    
76     return 0;
77     }
78    
79    
80     /*
81     * Generate the filter search command from the masks, assuming that
82     * masks are AND-ed.
83     */
84     char *
85     generate_filter_and(mask_t * mask, unsigned int masknum,
86     unsigned int masklen)
87     {
88     const unsigned int searchbuf = masklen + masknum * 6 + 8;
89     unsigned int len;
90     char *search;
91     mask_t *tmp;
92    
93     len = 0;
94    
95     search = (char *)xmalloc(sizeof(char) * searchbuf);
96     search[0] = '\0';
97    
98     tmp = mask;
99     if (tmp == NULL) {
100     strncat(search, "ALL ", searchbuf - len - 1);
101     len += 4;
102     } else
103     while ((tmp = tmp->next) != NULL) {
104     if (tmp->type != MASK_TYPE_OR) {
105     strncat(search, "ALL ", searchbuf - len - 1);
106     len += 4;
107     break;
108     }
109     }
110    
111     tmp = NULL;
112     while (mask != NULL) {
113     tmp = mask;
114     mask = mask->next;
115    
116     if (mask != NULL && mask->type == MASK_TYPE_OR) {
117     strncat(search, "OR (", searchbuf - len - 1);
118     len += 4;
119    
120     strncat(search, tmp->body, searchbuf - len - 1);
121     len = strlen(search);
122     search[len] = ' ';
123     search[++len] = '\0';
124    
125     search[len - 1] = ')';
126     search[len] = ' ';
127     search[++len] = '\0';
128    
129     if (mask->next == NULL ||
130     mask->next->type != MASK_TYPE_OR) {
131     search[len] = '(';
132     search[++len] = '\0';
133     strncat(search, mask->body,
134     searchbuf - len - 1);
135     len = strlen(search);
136     search[len] = ')';
137     search[++len] = ' ';
138     search[++len] = '\0';
139     mask = mask->next;
140     }
141     } else {
142     strncat(search, tmp->body, searchbuf - len - 1);
143     len = strlen(search);
144     search[len] = ' ';
145     search[++len] = '\0';
146     }
147     }
148    
149     search[len - 1] = '\0';
150    
151     return search;
152     }
153    
154    
155     /*
156     * Generate the filter search command from the masks, assuming that
157     * masks are OR-ed.
158     */
159     char *
160     generate_filter_or(mask_t * mask, unsigned int masknum,
161     unsigned int masklen)
162     {
163     const unsigned int searchbuf = masklen + masknum * 6 + 8;
164     unsigned int len;
165     char *search;
166     mask_t **mfifo; /* Mailbox FIFO queue. */
167     mask_t *mf; /* Mask returned from FIFO. */
168    
169     len = 0;
170    
171     search = (char *)xmalloc(sizeof(char) * searchbuf);
172     mfifo = (mask_t **) xmalloc(sizeof(mask_t *) * (masknum + 1));
173    
174     search[0] = '\0';
175     empty_fifo(mfifo);
176    
177     strncat(search, "ALL ", searchbuf - len - 1);
178     len += 4;
179    
180     while (mask != NULL) {
181     queue_fifo(mfifo, mask);
182     mask = mask->next;
183    
184     while (mask != NULL && mask->type == MASK_TYPE_AND) {
185     queue_fifo(mfifo, mask);
186     mask = mask->next;
187     }
188    
189     if (mask != NULL) {
190     if (len == 4 && search[0] == 'A') {
191     search[0] = '\0';
192     len = 0;
193     }
194     strncat(search, "OR ", searchbuf - len - 1);
195     len += 3;
196     }
197     if (search[0] != 'A') {
198     search[len] = '(';
199     search[++len] = '\0';
200     }
201     while ((mf = dequeue_fifo(mfifo)) != NULL) {
202     strncat(search, mf->body, searchbuf - len - 1);
203     len = strlen(search);
204     search[len] = ' ';
205     search[++len] = '\0';
206     }
207    
208     if (strchr(search, '(')) {
209     search[len - 1] = ')';
210     search[len] = ' ';
211     search[++len] = '\0';
212     }
213     empty_fifo(mfifo);
214     }
215    
216     search[len - 1] = '\0';
217    
218     xfree(mfifo);
219    
220     return search;
221     }
222    
223    
224     /*
225     * Empty the FIFO inventory.
226     */
227     void
228     empty_fifo(mask_t ** mfifo)
229     {
230     mfifo[0] = NULL;
231    
232     queue_fifo(NULL, NULL);
233     dequeue_fifo(NULL);
234     }
235    
236    
237     /*
238     * Add item to FIFO inventory.
239     */
240     void
241     queue_fifo(mask_t ** mfifo, mask_t * mask)
242     {
243     static unsigned int i;
244    
245     if (mfifo == NULL) {
246     i = 0;
247     return;
248     }
249     mfifo[i++] = mask;
250     mfifo[i] = NULL;
251     }
252    
253    
254     /*
255     * Get next item from FIFO inventory.
256     */
257     mask_t *
258     dequeue_fifo(mask_t ** mfifo)
259     {
260     static unsigned int j;
261    
262     if (mfifo == NULL) {
263     j = 0;
264     return NULL;
265     }
266     return mfifo[j++];
267     }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26