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

Annotation of /imapfilter/data.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.7 - (hide annotations)
Wed Oct 3 14:20:42 2001 UTC (22 years, 6 months ago) by lefcha
Branch: MAIN
Changes since 1.6: +9 -4 lines
File MIME type: text/plain
Fixed a bug about deleting of nodes.

1 lefcha 1.1 #include <stdio.h>
2     #include <errno.h>
3     #include <sys/types.h>
4     #include <regex.h>
5     #include <string.h>
6     #include <stdlib.h>
7     #include <limits.h>
8     #include <sys/stat.h>
9 lefcha 1.2 #include <ctype.h>
10 lefcha 1.1
11     #include "config.h"
12     #include "imapfilter.h"
13     #include "data.h"
14    
15    
16     account_t *accounts = NULL; /* First node of accounts linked list. */
17     filter_t *filters = NULL; /* First node of filters tree. */
18    
19 lefcha 1.5 static mboxgrp_t *mboxgrps = NULL; /* First node of mailbox-groups
20     tree. */
21 lefcha 1.1
22     static account_t *cur_acct = NULL; /* Current account. */
23     static filter_t *cur_fltr = NULL; /* Current filter. */
24    
25    
26     /*
27     * Set new account's variables to safe values.
28     */
29     void init_account(account_t * node)
30     {
31     node->next = NULL;
32     node->server[0] = node->username[0] = node->password[0] = 0;
33     node->port = 143;
34     node->mboxes = NULL;
35     }
36    
37    
38     /*
39     * Append account node to linked list.
40     */
41     void append_account(account_t * node)
42     {
43     account_t *pos;
44     account_t **app;
45    
46     APPEND_LINKED_LIST(accounts, node, pos, app);
47     }
48    
49    
50     /*
51     * A new account entry was declared. Create it and set it's variables
52     * accordingly.
53     */
54     int set_account(char *line, regmatch_t * match)
55     {
56     int s;
57     char p[6];
58     account_t *node;
59 lefcha 1.5
60 lefcha 1.1 node = (account_t *) create_node(sizeof(account_t));
61    
62     init_account(node);
63    
64 lefcha 1.5 strncat(node->username, line + match[1].rm_so,
65 lefcha 1.4 min(match[1].rm_eo - match[1].rm_so, USERNAME_LEN - 1));
66 lefcha 1.1 #ifdef DEBUG
67     printf("debug: USERNAME: '%s'\n", node->username);
68     #endif
69    
70 lefcha 1.5 strncat(node->password, line + match[2].rm_so,
71     min(match[2].rm_eo - match[2].rm_so, PASSWORD_LEN - 1));
72 lefcha 1.1 #ifdef DEBUG
73     printf("debug: PASSWORD: '%s'\n", node->password);
74     #endif
75    
76 lefcha 1.4 strncat(node->server, line + match[3].rm_so,
77     min(match[3].rm_eo - match[3].rm_so, SERVER_LEN - 1));
78 lefcha 1.1 #ifdef DEBUG
79     printf("debug: SERVER: '%s'\n", node->server);
80     #endif
81    
82 lefcha 1.4 if (match[4].rm_so != -1) {
83     s = min(match[4].rm_eo - match[4].rm_so - 1, 5);
84     strncpy(p, line + match[4].rm_so + 1, s);
85 lefcha 1.1 p[s] = 0;
86     node->port = strtoul(p, NULL, 0);
87     #ifdef DEBUG
88     printf("debug: PORT: %d\n", node->port);
89     #endif
90     }
91     append_account(node);
92     cur_acct = node;
93    
94     return 0;
95     }
96    
97    
98     /*
99     * Set new mailbox-group's variables to safe values.
100     */
101     void init_mboxgrp(mboxgrp_t * node)
102     {
103     node->left = node->right = NULL;
104 lefcha 1.4 node->key[0] = 0;
105 lefcha 1.1 node->mboxes[0] = NULL;
106     }
107    
108    
109     /*
110     * Insert mailbox-group node in tree.
111     */
112     void insert_mboxgrp(mboxgrp_t * node)
113     {
114     int cmp;
115     mboxgrp_t *pos;
116     mboxgrp_t **ins;
117    
118     INSERT_TREE(mboxgrps, node, pos, ins, cmp);
119     }
120    
121    
122     /*
123     * A new mailbox-group entry was declared. Create it and set it's variables
124     * accordingly.
125     */
126     int set_mboxgrp(char *line, regmatch_t * match)
127     {
128     mboxgrp_t *node;
129     char mboxs[LINE_MAX];
130    
131 lefcha 1.4 mboxs[0] = 0;
132    
133 lefcha 1.1 if (!accounts)
134 lefcha 1.4 return ERROR_CONFIG_PARSE;
135 lefcha 1.1
136     node = (mboxgrp_t *) create_node(sizeof(mboxgrp_t));
137    
138     init_mboxgrp(node);
139    
140 lefcha 1.4 strncat(node->key, line + match[1].rm_so,
141     min(match[1].rm_eo - match[1].rm_so, KEY_LEN - 1));
142 lefcha 1.1
143     #ifdef DEBUG
144     printf("debug: FOLDER: '%s'\n", node->key);
145     #endif
146    
147 lefcha 1.4 strncat(mboxs, line + match[2].rm_so,
148     min(match[2].rm_eo - match[2].rm_so, LINE_MAX - 1));
149 lefcha 1.1
150     process_mboxgrp(node, mboxs);
151    
152     insert_mboxgrp(node);
153    
154     return 0;
155     }
156    
157    
158     /*
159     * Calls set_mbox() in order to create mailboxes that are part of
160     * the mailbox-group.
161     */
162     void process_mboxgrp(mboxgrp_t * node, char *mboxs)
163     {
164     int i = 0;
165     const char *delim = ",";
166     char *tok;
167    
168 lefcha 1.4 while (i < MBOXGRP_MBOXES_MAX - 1 && (tok = strsep(&mboxs, delim))) {
169 lefcha 1.1 node->mboxes[i] = (mbox_t *) set_mbox(tok);
170     node->mboxes[++i] = NULL;
171     }
172     }
173    
174    
175     /*
176     * Find in the mailbox-group tree, the node with the specified key,
177     * and return a pointer to it.
178     */
179     mboxgrp_t *find_mboxgrp(char *key)
180     {
181     int cmp;
182     mboxgrp_t *pos;
183    
184     FIND_TREE(mboxgrps, key, pos, cmp);
185     }
186    
187    
188     /*
189     * Set new mailbox's variables to safe values.
190     */
191     void init_mbox(mbox_t * node)
192     {
193     node->next = NULL;
194 lefcha 1.4 node->name[0] = 0;
195 lefcha 1.1 node->filters[0] = NULL;
196     }
197    
198    
199     /*
200     * Append mailbox node to linked list.
201     */
202     void append_mbox(mbox_t * node)
203     {
204     mbox_t *pos;
205     mbox_t **ins;
206    
207     APPEND_LINKED_LIST(cur_acct->mboxes, node, pos, ins);
208     }
209    
210    
211     /*
212     * A new mailbox was declared, create it and set it's variables accordingly.
213     */
214     mbox_t *set_mbox(char *name)
215     {
216     mbox_t *node;
217    
218     node = (mbox_t *) create_node(sizeof(mbox_t));
219    
220     init_mbox(node);
221    
222 lefcha 1.5 strncat(node->name, name,
223 lefcha 1.4 min(strlen(name), MBOX_NAME_LEN - 1));
224 lefcha 1.1
225     #ifdef DEBUG
226     printf("debug: MBOX: '%s'\n", node->name);
227     #endif
228    
229     append_mbox(node);
230    
231     return node;
232     }
233    
234    
235     /*
236     * Set new filter's variables to safe values.
237     */
238     void init_filter(filter_t * node)
239     {
240     node->left = node->right = NULL;
241 lefcha 1.4 node->key[0] = 0;
242 lefcha 1.1 node->mode = FILTER_MODE_AND;
243     node->action.type = 0;
244     node->action.args[0] = 0;
245     node->masks = NULL;
246 lefcha 1.4 node->masknum = node->masklen = 0;
247 lefcha 1.1 }
248    
249    
250     /*
251     * Insert filter node to tree.
252     */
253     void insert_filter(filter_t * node)
254     {
255     int cmp;
256     filter_t *pos;
257     filter_t **ins;
258    
259     INSERT_TREE(filters, node, pos, ins, cmp);
260     }
261    
262    
263     /*
264     * A filter entry was declared, create it and set it's variables accordingly.
265     */
266     int set_filter(char *line, regmatch_t * match)
267     {
268     filter_t *node;
269 lefcha 1.5
270 lefcha 1.4 if (cur_fltr && !cur_fltr->action.type)
271     return ERROR_CONFIG_PARSE;
272 lefcha 1.1
273     node = (filter_t *) create_node(sizeof(filter_t));
274    
275     init_filter(node);
276    
277 lefcha 1.4 strncat(node->key, line + match[1].rm_so,
278     min(match[1].rm_eo - match[1].rm_so, KEY_LEN - 1));
279 lefcha 1.1
280 lefcha 1.4 if (match[2].rm_so != -1) {
281 lefcha 1.5 if (*(line + match[2].rm_so + 1) == 'o' ||
282     *(line + match[2].rm_so + 1) == 'O')
283 lefcha 1.1 node->mode = FILTER_MODE_OR;
284     else
285     node->mode = FILTER_MODE_AND;
286     }
287     #ifdef DEBUG
288     printf("debug: FILTER: '%s' %s\n", node->key,
289     (node->mode == FILTER_MODE_OR ? "OR" : "AND"));
290     #endif
291    
292     insert_filter(node);
293     cur_fltr = node;
294    
295     return 0;
296     }
297    
298    
299     /*
300     * Find in the filter tree, the node with the specified key and
301     * return a pointer to it.
302     */
303     filter_t *find_filter(char *key)
304     {
305     int cmp;
306     filter_t *pos;
307    
308     FIND_TREE(filters, key, pos, cmp);
309     }
310    
311    
312     /*
313 lefcha 1.5 * Assign an action to the last declared filter.
314 lefcha 1.1 */
315 lefcha 1.4 int set_action(char *line, regmatch_t * match)
316 lefcha 1.1 {
317     if (!cur_fltr)
318 lefcha 1.4 return ERROR_CONFIG_PARSE;
319 lefcha 1.7
320 lefcha 1.5 if (!strncasecmp(line + match[1].rm_so, "delete", 6))
321 lefcha 1.4 cur_fltr->action.type = FILTER_ACTION_DELETE;
322 lefcha 1.5 else if (!strncasecmp(line + match[1].rm_so, "copy", 4)) {
323 lefcha 1.4 cur_fltr->action.type = FILTER_ACTION_COPY;
324     strncat(cur_fltr->action.destmbox, line + match[2].rm_so,
325     min(match[2].rm_eo - match[2].rm_so, MBOX_NAME_LEN - 1));
326 lefcha 1.5 } else if (!strncasecmp(line + match[1].rm_so, "move", 4)) {
327 lefcha 1.4 cur_fltr->action.type = FILTER_ACTION_MOVE;
328     strncat(cur_fltr->action.destmbox, line + match[3].rm_so,
329     min(match[3].rm_eo - match[3].rm_so, MBOX_NAME_LEN - 1));
330 lefcha 1.5 } else if (!strncasecmp(line + match[1].rm_so, "list", 4))
331 lefcha 1.4 cur_fltr->action.type = FILTER_ACTION_LIST;
332 lefcha 1.7
333 lefcha 1.4 if (match[4].rm_so != -1)
334     strncat(cur_fltr->action.args, line + match[4].rm_so,
335 lefcha 1.5 min(match[4].rm_eo - match[4].rm_so, ARGS_LEN - 1));
336 lefcha 1.1
337 lefcha 1.4 return 0;
338 lefcha 1.5
339 lefcha 1.1 }
340    
341    
342     /*
343     * Set new mask's variables to safe values.
344     */
345     void init_mask(mask_t * node)
346     {
347     node->next = NULL;
348     node->body[0] = 0;
349     node->type = 0;
350     }
351    
352    
353     /*
354     * Append mask node to linked list.
355     */
356     void append_mask(mask_t * node)
357     {
358     mask_t *pos;
359     mask_t **app;
360    
361     APPEND_LINKED_LIST(cur_fltr->masks, node, pos, app);
362     }
363    
364    
365     /*
366     * A new mask entry was declared, create it and set it's
367     * variables accordingly.
368     */
369     int set_mask(char *line, regmatch_t * match)
370     {
371 lefcha 1.4 int s, i, f = 0;
372 lefcha 1.1 mask_t *node;
373 lefcha 1.4 char *bp;
374 lefcha 1.5
375 lefcha 1.4 if (!cur_fltr)
376     return ERROR_CONFIG_PARSE;
377 lefcha 1.1
378     node = (mask_t *) create_node(sizeof(mask_t));
379    
380     init_mask(node);
381 lefcha 1.5
382 lefcha 1.4 bp = node->body;
383 lefcha 1.5
384 lefcha 1.4 /* If specified set mask's type. */
385     if (match[2].rm_so != -1 && cur_fltr->masks) {
386 lefcha 1.5 if (*(line + match[2].rm_so) == 'o' ||
387     *(line + match[2].rm_so) == 'O')
388 lefcha 1.1 node->type = MASK_TYPE_OR;
389     else
390     node->type = MASK_TYPE_AND;
391     }
392 lefcha 1.4 /* Add NOT if specified. */
393     if (match[3].rm_so != -1) {
394     s = min(match[3].rm_eo - match[3].rm_so,
395     MASK_BODY_LEN - (bp - node->body) - 1);
396     strncpy(bp, line + match[3].rm_so, s);
397     string_upper(bp, s);
398     *(bp + s - 1) = ' '; /* In case it's '\t'. */
399     *(bp + s) = 0;
400     bp += s;
401 lefcha 1.1 }
402 lefcha 1.4 /* Keyword of the search key. */
403     s = min(match[4].rm_eo - match[4].rm_so,
404     MASK_BODY_LEN - (bp - node->body) - 3);
405     strncpy(bp, line + match[4].rm_so, s);
406     string_upper(bp, s);
407     *(bp + s) = 0;
408     bp += s;
409 lefcha 1.5
410 lefcha 1.4 /* Body of the search key (string/number). */
411     for (i = 5; i <= 6; i++)
412     if (match[i].rm_so != -1) {
413     *(bp++) = ' ';
414 lefcha 1.5
415 lefcha 1.4 /* Add '"' if not supplied and search key not a number. */
416     if (match[6].rm_so == -1 &&
417     (strstr(node->body, "LARGER") ||
418 lefcha 1.5 strstr(node->body, "SMALLER")))
419 lefcha 1.4 f = 1;
420     else if (*(line + match[i].rm_so) != '"')
421     *(bp++) = '"';
422 lefcha 1.5
423 lefcha 1.4 *bp = 0;
424 lefcha 1.5
425 lefcha 1.4 s = min(match[i].rm_eo - match[i].rm_so,
426     MASK_BODY_LEN - (bp - node->body) - 2);
427     strncpy(bp, line + match[i].rm_so, s);
428     *(bp + s) = 0;
429     bp += s;
430 lefcha 1.5
431     if (*(line + match[i].rm_so) != '"' && !f)
432 lefcha 1.4 *(bp++) = '"';
433 lefcha 1.5 *bp = 0;
434 lefcha 1.4 }
435 lefcha 1.1 append_mask(node);
436    
437 lefcha 1.4 cur_fltr->masknum++;
438     cur_fltr->masklen += (bp - node->body);
439 lefcha 1.5
440    
441 lefcha 1.1 #ifdef DEBUG
442     printf("debug: MASK: '%s'\n", node->body);
443     #endif
444    
445     return 0;
446     }
447    
448    
449     /*
450     * A new job was declared, link filters with mailbox-groups.
451     */
452     int set_job(char *line, regmatch_t * match)
453     {
454 lefcha 1.4 int s;
455 lefcha 1.1 const char *delim = ",";
456 lefcha 1.4 char *ftok, *gtok, *fltr, *mbgrp, *f, *g;
457 lefcha 1.1 filter_t *cf;
458 lefcha 1.4 mboxgrp_t *cg;
459 lefcha 1.5
460 lefcha 1.4 if (!accounts || !filters)
461     return ERROR_CONFIG_PARSE;
462 lefcha 1.1
463     s = match[1].rm_eo - match[1].rm_so;
464 lefcha 1.6 fltr = (char *) xmalloc(s + 1);
465 lefcha 1.5
466 lefcha 1.4 f = strncpy(fltr, line + match[1].rm_so, s);
467     f[s] = 0;
468 lefcha 1.1
469     s = match[2].rm_eo - match[2].rm_so;
470 lefcha 1.6 mbgrp = (char *) xmalloc(s + 1);
471 lefcha 1.5
472 lefcha 1.4 /* Go through filters. */
473     while ((ftok = strsep(&f, delim))) {
474 lefcha 1.1 cf = (filter_t *) find_filter(ftok);
475     if (!cf)
476 lefcha 1.4 return ERROR_CONFIG_PARSE;
477 lefcha 1.5
478 lefcha 1.4 g = strncpy(mbgrp, line + match[2].rm_so, s);
479     g[s] = 0;
480 lefcha 1.5
481 lefcha 1.4 /* Go through mailbox groups. */
482     while ((gtok = strsep(&g, delim))) {
483     cg = (mboxgrp_t *) find_mboxgrp(gtok);
484     if (!cg)
485     return ERROR_CONFIG_PARSE;
486     link_mbox_filter(cf, cg);
487 lefcha 1.1 }
488     }
489 lefcha 1.5
490 lefcha 1.1 free(fltr);
491     free(mbgrp);
492    
493 lefcha 1.4 return 0;
494 lefcha 1.1 }
495    
496    
497     /*
498     * Link a filter with a mailbox.
499     */
500 lefcha 1.4 void link_mbox_filter(filter_t * cf, mboxgrp_t * cg)
501 lefcha 1.1 {
502     int i, j;
503 lefcha 1.4 int f;
504 lefcha 1.5
505     for (i = 0; cg->mboxes[i]; i++) {
506    
507 lefcha 1.4 for (f = j = 0; cg->mboxes[i]->filters[j]; j++)
508     if (j == MBOX_FILTERS_MAX - 1 ||
509 lefcha 1.5 !strncmp(cf->key, cg->mboxes[i]->filters[j]->key, KEY_LEN))
510 lefcha 1.4 f = 1;
511 lefcha 1.5
512 lefcha 1.4 if (f)
513     continue;
514 lefcha 1.5
515 lefcha 1.4 cg->mboxes[i]->filters[j] = cf;
516     cg->mboxes[i]->filters[j + 1] = NULL;
517 lefcha 1.1
518     }
519    
520     #ifdef DEBUG
521 lefcha 1.4 printf("debug: JOB: '%s' '%s'\n", cf->key, cg->key);
522 lefcha 1.1 #endif
523     }
524    
525    
526     /*
527 lefcha 1.3 * Free allocated memory of data structures that are not needed anymore.
528     */
529     void destroy_data(void)
530     {
531     destroy_mboxgrp(mboxgrps);
532     }
533    
534    
535     /*
536 lefcha 1.4 * Go through the mailbox-group tree, and free the memory of each node.
537 lefcha 1.1 */
538     void destroy_mboxgrp(mboxgrp_t * node)
539     {
540 lefcha 1.7 if (node->left) {
541 lefcha 1.1 destroy_mboxgrp(node->left);
542 lefcha 1.7 node->left = NULL;
543     }
544    
545     if (node->right) {
546 lefcha 1.1 destroy_mboxgrp(node->right);
547 lefcha 1.7 node->right = NULL;
548     }
549 lefcha 1.5
550 lefcha 1.1 #ifdef DEBUG
551     printf("debug: deleting FOLDER: '%s'\n", node->key);
552     #endif
553 lefcha 1.5
554 lefcha 1.4 free(node);
555 lefcha 1.2 }
556    
557    
558     /*
559     * Convert a string of specified size to upper case.
560     */
561 lefcha 1.4 void string_upper(char *str, size_t size)
562 lefcha 1.2 {
563     int i;
564    
565     for (i = 0; i < size; i++)
566 lefcha 1.6 if (islower(*(str + i)))
567     *(str + i) = toupper(*(str + i));
568 lefcha 1.1 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26