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

Annotation of /imapfilter/data.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.11 - (hide annotations)
Mon Oct 8 08:47:48 2001 UTC (22 years, 5 months ago) by lefcha
Branch: MAIN
CVS Tags: release-0_6_2
Branch point for: release-0_6_2-patches
Changes since 1.10: +3 -5 lines
File MIME type: text/plain
Small changes.

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

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26