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

Contents of /imapfilter/match.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (show 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 #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