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

Annotation of /imapfilter/data.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.35 - (hide annotations)
Fri Feb 21 18:31:29 2003 UTC (21 years, 2 months ago) by lefcha
Branch: MAIN
Changes since 1.34: +13 -13 lines
File MIME type: text/plain
DEBUG messages go to stderr.

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.13 #include <time.h>
11 lefcha 1.1
12     #include "config.h"
13     #include "imapfilter.h"
14     #include "data.h"
15    
16    
17 lefcha 1.23 extern unsigned int options;
18     extern unsigned int flags;
19    
20 lefcha 1.1 account_t *accounts = NULL; /* First node of accounts linked list. */
21     filter_t *filters = NULL; /* First node of filters tree. */
22    
23 lefcha 1.26 static mboxgrp_t *mboxgrps = NULL; /* First node of mailbox-groups tree. */
24 lefcha 1.1
25     static account_t *cur_acct = NULL; /* Current account. */
26     static filter_t *cur_fltr = NULL; /* Current filter. */
27    
28    
29     /*
30     * Set new account's variables to safe values.
31     */
32     void init_account(account_t * node)
33     {
34     node->next = NULL;
35 lefcha 1.25 node->key[0] = node->server[0] = node->username[0] = node->password[0] = 0;
36 lefcha 1.20 node->passwdattr = PASSWORD_NONE;
37 lefcha 1.1 node->port = 143;
38 lefcha 1.12 node->ssl = SSL_DISABLED;
39 lefcha 1.1 node->mboxes = NULL;
40     }
41    
42    
43     /*
44     * Append account node to linked list.
45     */
46     void append_account(account_t * node)
47     {
48     account_t *pos;
49     account_t **app;
50    
51     APPEND_LINKED_LIST(accounts, node, pos, app);
52     }
53    
54    
55     /*
56     * A new account entry was declared. Create it and set it's variables
57     * accordingly.
58     */
59     int set_account(char *line, regmatch_t * match)
60     {
61 lefcha 1.16 int n;
62 lefcha 1.1 char p[6];
63     account_t *node;
64 lefcha 1.5
65 lefcha 1.1 node = (account_t *) create_node(sizeof(account_t));
66 lefcha 1.26 node->password = (char *)smalloc(PASSWORD_LEN);
67 lefcha 1.1
68     init_account(node);
69 lefcha 1.20
70 lefcha 1.25 strncat(node->key, line + match[1].rm_so,
71     min(match[1].rm_eo - match[1].rm_so, KEY_LEN - 1));
72     #ifdef DEBUG
73 lefcha 1.35 fprintf(stderr, "debug: ACCOUNT: '%s'\n", node->key);
74 lefcha 1.25 #endif
75    
76     if (match[3].rm_so != -1) {
77     strncat(node->username, line + match[3].rm_so,
78     min(match[3].rm_eo - match[3].rm_so, USERNAME_LEN - 1));
79 lefcha 1.19 } else {
80 lefcha 1.25 strncat(node->username, line + match[5].rm_so,
81     min(match[5].rm_eo - match[5].rm_so, USERNAME_LEN - 1));
82 lefcha 1.19 }
83 lefcha 1.8 if (strchr(node->username, '%'))
84     if (string_decode(node->username))
85     return ERROR_CONFIG_PARSE;
86 lefcha 1.1 #ifdef DEBUG
87 lefcha 1.35 fprintf(stderr, "debug: USERNAME: '%s'\n", node->username);
88 lefcha 1.1 #endif
89 lefcha 1.20
90 lefcha 1.25 if (match[4].rm_so != -1) {
91     strncat(node->password, line + match[4].rm_so,
92     min(match[4].rm_eo - match[4].rm_so, PASSWORD_LEN - 1));
93 lefcha 1.19 if (strchr(node->password, '%'))
94     if (string_decode(node->password))
95     return ERROR_CONFIG_PARSE;
96 lefcha 1.20 node->passwdattr = PASSWORD_PLAIN;
97 lefcha 1.23 } else
98     flags |= FLAG_BLANK_PASSWORD;
99 lefcha 1.1 #ifdef DEBUG
100 lefcha 1.35 fprintf(stderr, "debug: PASSWORD: '%s'\n", node->password);
101 lefcha 1.1 #endif
102    
103 lefcha 1.25 strncat(node->server, line + match[6].rm_so,
104     min(match[6].rm_eo - match[6].rm_so, SERVER_LEN - 1));
105 lefcha 1.1 #ifdef DEBUG
106 lefcha 1.35 fprintf(stderr, "debug: SERVER: '%s'\n", node->server);
107 lefcha 1.1 #endif
108    
109 lefcha 1.25 if (match[7].rm_so != -1) {
110     n = min(match[7].rm_eo - match[7].rm_so - 1, 5);
111     xstrncpy(p, line + match[7].rm_so + 1, n);
112 lefcha 1.16 p[n] = 0;
113 lefcha 1.11 node->port = strtoul(p, NULL, 10);
114 lefcha 1.1 #ifdef DEBUG
115 lefcha 1.35 fprintf(stderr, "debug: PORT: %d\n", node->port);
116 lefcha 1.1 #endif
117     }
118 lefcha 1.25 if (match[8].rm_so != -1) {
119     if (match[7].rm_so == -1)
120 lefcha 1.12 node->port = 993;
121    
122 lefcha 1.25 if (strcasestr(line + match[8].rm_so, "ssl3"))
123 lefcha 1.12 node->ssl = SSL_SSL_V3;
124 lefcha 1.25 else if (strcasestr(line + match[8].rm_so, "tls1"))
125 lefcha 1.12 node->ssl = SSL_TLS_V1;
126     else
127     node->ssl = SSL_SSL_V2;
128     }
129 lefcha 1.1 append_account(node);
130     cur_acct = node;
131    
132     return 0;
133     }
134    
135    
136 lefcha 1.20 #ifdef ENCRYPTED_PASSWORDS
137     /*
138     * Find accounts without a password (candicates for password encryption).
139     */
140     char *find_password(char *user, char *serv)
141     {
142     account_t *a;
143    
144     for (a = accounts; a; a = a->next)
145     if (a->passwdattr == PASSWORD_NONE && !strcmp(a->server, serv) &&
146     !strcmp(a->username, user)) {
147     a->passwdattr = PASSWORD_ENCRYPTED;
148     return a->password;
149     }
150     return NULL;
151     }
152 lefcha 1.26
153 lefcha 1.20 #endif
154    
155 lefcha 1.1 /*
156     * Set new mailbox-group's variables to safe values.
157     */
158     void init_mboxgrp(mboxgrp_t * node)
159     {
160     node->left = node->right = NULL;
161 lefcha 1.4 node->key[0] = 0;
162 lefcha 1.1 node->mboxes[0] = NULL;
163     }
164    
165    
166     /*
167     * Insert mailbox-group node in tree.
168     */
169     void insert_mboxgrp(mboxgrp_t * node)
170     {
171     int cmp;
172     mboxgrp_t *pos;
173     mboxgrp_t **ins;
174    
175     INSERT_TREE(mboxgrps, node, pos, ins, cmp);
176     }
177    
178    
179     /*
180     * A new mailbox-group entry was declared. Create it and set it's variables
181     * accordingly.
182     */
183     int set_mboxgrp(char *line, regmatch_t * match)
184     {
185     mboxgrp_t *node;
186     char mboxs[LINE_MAX];
187    
188 lefcha 1.4 mboxs[0] = 0;
189    
190 lefcha 1.1 if (!accounts)
191 lefcha 1.4 return ERROR_CONFIG_PARSE;
192 lefcha 1.1
193     node = (mboxgrp_t *) create_node(sizeof(mboxgrp_t));
194    
195     init_mboxgrp(node);
196    
197 lefcha 1.4 strncat(node->key, line + match[1].rm_so,
198     min(match[1].rm_eo - match[1].rm_so, KEY_LEN - 1));
199 lefcha 1.1
200     #ifdef DEBUG
201 lefcha 1.35 fprintf(stderr, "debug: FOLDER: '%s'\n", node->key);
202 lefcha 1.1 #endif
203    
204 lefcha 1.4 strncat(mboxs, line + match[2].rm_so,
205     min(match[2].rm_eo - match[2].rm_so, LINE_MAX - 1));
206 lefcha 1.1
207     process_mboxgrp(node, mboxs);
208    
209     insert_mboxgrp(node);
210    
211     return 0;
212     }
213    
214    
215     /*
216     * Calls set_mbox() in order to create mailboxes that are part of
217     * the mailbox-group.
218     */
219     void process_mboxgrp(mboxgrp_t * node, char *mboxs)
220     {
221 lefcha 1.16 unsigned int i = 0;
222 lefcha 1.1 char *tok;
223    
224 lefcha 1.31 tok = strtok_r(mboxs, ",", &mboxs);
225     while (i < MBOXGRP_MBOXES_MAX - 1 && tok) {
226 lefcha 1.1 node->mboxes[i] = (mbox_t *) set_mbox(tok);
227     node->mboxes[++i] = NULL;
228 lefcha 1.31
229     tok = strtok_r(NULL, ",", &mboxs);
230 lefcha 1.1 }
231     }
232    
233    
234     /*
235     * Find in the mailbox-group tree, the node with the specified key,
236     * and return a pointer to it.
237     */
238     mboxgrp_t *find_mboxgrp(char *key)
239     {
240     int cmp;
241     mboxgrp_t *pos;
242    
243     FIND_TREE(mboxgrps, key, pos, cmp);
244     }
245    
246    
247     /*
248     * Set new mailbox's variables to safe values.
249     */
250     void init_mbox(mbox_t * node)
251     {
252     node->next = NULL;
253 lefcha 1.4 node->name[0] = 0;
254 lefcha 1.1 node->filters[0] = NULL;
255     }
256    
257    
258     /*
259     * Append mailbox node to linked list.
260     */
261     void append_mbox(mbox_t * node)
262     {
263     mbox_t *pos;
264     mbox_t **ins;
265    
266     APPEND_LINKED_LIST(cur_acct->mboxes, node, pos, ins);
267     }
268    
269    
270     /*
271     * A new mailbox was declared, create it and set it's variables accordingly.
272     */
273     mbox_t *set_mbox(char *name)
274     {
275     mbox_t *node;
276    
277     node = (mbox_t *) create_node(sizeof(mbox_t));
278    
279     init_mbox(node);
280    
281 lefcha 1.21 if (*name == '"' && *(name + strlen(name) - 1) == '"')
282     strncat(node->name, name + 1, min(strlen(name) - 2, MBOX_NAME_LEN - 1));
283     else
284     strncat(node->name, name, min(strlen(name), MBOX_NAME_LEN - 1));
285 lefcha 1.1
286     #ifdef DEBUG
287 lefcha 1.35 fprintf(stderr, "debug: MBOX: '%s'\n", node->name);
288 lefcha 1.1 #endif
289    
290     append_mbox(node);
291    
292     return node;
293     }
294    
295    
296     /*
297     * Set new filter's variables to safe values.
298     */
299     void init_filter(filter_t * node)
300     {
301     node->left = node->right = NULL;
302 lefcha 1.4 node->key[0] = 0;
303 lefcha 1.1 node->mode = FILTER_MODE_AND;
304     node->action.type = 0;
305 lefcha 1.25 node->action.raccount = NULL;
306 lefcha 1.9 node->action.destmbox[0] = node->action.args[0] = 0;
307 lefcha 1.1 node->masks = NULL;
308 lefcha 1.30 node->masknum = node->masklen = 0;
309 lefcha 1.1 }
310    
311    
312     /*
313     * Insert filter node to tree.
314     */
315     void insert_filter(filter_t * node)
316     {
317     int cmp;
318     filter_t *pos;
319     filter_t **ins;
320    
321     INSERT_TREE(filters, node, pos, ins, cmp);
322     }
323    
324    
325     /*
326     * A filter entry was declared, create it and set it's variables accordingly.
327     */
328     int set_filter(char *line, regmatch_t * match)
329     {
330     filter_t *node;
331 lefcha 1.5
332 lefcha 1.4 if (cur_fltr && !cur_fltr->action.type)
333     return ERROR_CONFIG_PARSE;
334 lefcha 1.1
335     node = (filter_t *) create_node(sizeof(filter_t));
336    
337     init_filter(node);
338    
339 lefcha 1.4 strncat(node->key, line + match[1].rm_so,
340     min(match[1].rm_eo - match[1].rm_so, KEY_LEN - 1));
341 lefcha 1.1
342 lefcha 1.4 if (match[2].rm_so != -1) {
343 lefcha 1.28 if (!strncasecmp(line + match[2].rm_so + 1, "or", 2))
344 lefcha 1.1 node->mode = FILTER_MODE_OR;
345     else
346     node->mode = FILTER_MODE_AND;
347     }
348     #ifdef DEBUG
349 lefcha 1.35 fprintf(stderr, "debug: FILTER: '%s' %s\n", node->key,
350 lefcha 1.1 (node->mode == FILTER_MODE_OR ? "OR" : "AND"));
351     #endif
352    
353     insert_filter(node);
354     cur_fltr = node;
355    
356     return 0;
357     }
358    
359    
360     /*
361     * Find in the filter tree, the node with the specified key and
362     * return a pointer to it.
363     */
364     filter_t *find_filter(char *key)
365     {
366     int cmp;
367     filter_t *pos;
368    
369     FIND_TREE(filters, key, pos, cmp);
370     }
371    
372    
373     /*
374 lefcha 1.5 * Assign an action to the last declared filter.
375 lefcha 1.1 */
376 lefcha 1.4 int set_action(char *line, regmatch_t * match)
377 lefcha 1.1 {
378 lefcha 1.26 char *c, *cp, *t;
379 lefcha 1.25 account_t *a;
380 lefcha 1.34 char s[MBOX_NAME_LEN];
381     time_t te;
382     struct tm *tl;
383 lefcha 1.26
384 lefcha 1.1 if (!cur_fltr)
385 lefcha 1.4 return ERROR_CONFIG_PARSE;
386 lefcha 1.7
387 lefcha 1.28 if (!strncasecmp(line + match[1].rm_so, "delete", 6))
388 lefcha 1.4 cur_fltr->action.type = FILTER_ACTION_DELETE;
389 lefcha 1.28 else if (!strncasecmp(line + match[1].rm_so, "copy", 4)) {
390 lefcha 1.4 cur_fltr->action.type = FILTER_ACTION_COPY;
391 lefcha 1.21 if (*(line + match[2].rm_so) == '"' && *(line + match[2].rm_eo - 1) == '"')
392     strncat(cur_fltr->action.destmbox, line + match[2].rm_so + 1,
393 lefcha 1.26 min(match[2].rm_eo - match[2].rm_so - 2, MBOX_NAME_LEN - 1));
394 lefcha 1.21 else
395     strncat(cur_fltr->action.destmbox, line + match[2].rm_so,
396     min(match[2].rm_eo - match[2].rm_so, MBOX_NAME_LEN - 1));
397 lefcha 1.28 } else if (!strncasecmp(line + match[1].rm_so, "move", 4)) {
398 lefcha 1.4 cur_fltr->action.type = FILTER_ACTION_MOVE;
399 lefcha 1.21 if (*(line + match[3].rm_so) == '"' && *(line + match[3].rm_eo - 1) == '"')
400     strncat(cur_fltr->action.destmbox, line + match[3].rm_so + 1,
401 lefcha 1.26 min(match[3].rm_eo - match[3].rm_so - 2, MBOX_NAME_LEN - 1));
402 lefcha 1.21 else
403     strncat(cur_fltr->action.destmbox, line + match[3].rm_so,
404     min(match[3].rm_eo - match[3].rm_so, MBOX_NAME_LEN - 1));
405 lefcha 1.28 } else if (!strncasecmp(line + match[1].rm_so, "rcopy", 5)) {
406 lefcha 1.25 cur_fltr->action.type = FILTER_ACTION_RCOPY;
407     for (a = accounts; a; a = a->next)
408 lefcha 1.28 if (!strncasecmp(line + match[4].rm_so, a->key, strlen(a->key)))
409 lefcha 1.25 cur_fltr->action.raccount = a;
410     if (!cur_fltr->action.raccount)
411 lefcha 1.26 return ERROR_CONFIG_PARSE;
412 lefcha 1.25
413     if (*(line + match[5].rm_so) == '"' && *(line + match[5].rm_eo - 1) == '"')
414     strncat(cur_fltr->action.destmbox, line + match[5].rm_so + 1,
415 lefcha 1.26 min(match[5].rm_eo - match[5].rm_so - 2, MBOX_NAME_LEN - 1));
416 lefcha 1.25 else
417     strncat(cur_fltr->action.destmbox, line + match[5].rm_so,
418     min(match[5].rm_eo - match[5].rm_so, MBOX_NAME_LEN - 1));
419 lefcha 1.28 } else if (!strncasecmp(line + match[1].rm_so, "rmove", 5)) {
420 lefcha 1.25 cur_fltr->action.type = FILTER_ACTION_RMOVE;
421     for (a = accounts; a; a = a->next)
422 lefcha 1.28 if (!strncasecmp(line + match[6].rm_so, a->key, strlen(a->key)))
423 lefcha 1.25 cur_fltr->action.raccount = a;
424     if (!cur_fltr->action.raccount)
425 lefcha 1.26 return ERROR_CONFIG_PARSE;
426 lefcha 1.25
427     if (*(line + match[7].rm_so) == '"' && *(line + match[7].rm_eo - 1) == '"')
428     strncat(cur_fltr->action.destmbox, line + match[7].rm_so + 1,
429 lefcha 1.26 min(match[7].rm_eo - match[7].rm_so - 2, MBOX_NAME_LEN - 1));
430 lefcha 1.25 else
431     strncat(cur_fltr->action.destmbox, line + match[7].rm_so,
432     min(match[7].rm_eo - match[7].rm_so, MBOX_NAME_LEN - 1));
433 lefcha 1.28 } else if (!strncasecmp(line + match[1].rm_so, "flag", 4)) {
434     if (!strncasecmp(line + match[8].rm_so, "replace", 7))
435 lefcha 1.26 cur_fltr->action.type = FILTER_ACTION_FLAG_REPLACE;
436 lefcha 1.28 else if (!strncasecmp(line + match[8].rm_so, "add", 3))
437 lefcha 1.26 cur_fltr->action.type = FILTER_ACTION_FLAG_ADD;
438     else
439     cur_fltr->action.type = FILTER_ACTION_FLAG_REMOVE;
440    
441     c = cp = (char *)malloc(match[9].rm_eo - match[9].rm_so + 1);
442     xstrncpy(c, line + match[9].rm_so, match[9].rm_eo - match[9].rm_so);
443 lefcha 1.31
444     t = strtok_r(c, ",", &c);
445     while (t) {
446 lefcha 1.26 if (!strcasecmp(t, "none")) {
447     if (match[9].rm_eo - match[9].rm_so != strlen("none"))
448     return ERROR_CONFIG_PARSE;
449     } else if (!strcasecmp(t, "seen"))
450     cur_fltr->action.msgflags |= MESSAGE_FLAG_SEEN;
451     else if (!strcasecmp(t, "answered"))
452     cur_fltr->action.msgflags |= MESSAGE_FLAG_ANSWERED;
453     else if (!strcasecmp(t, "flagged"))
454     cur_fltr->action.msgflags |= MESSAGE_FLAG_FLAGGED;
455     else if (!strcasecmp(t, "deleted"))
456     cur_fltr->action.msgflags |= MESSAGE_FLAG_DELETED;
457     else if (!strcasecmp(t, "draft"))
458     cur_fltr->action.msgflags |= MESSAGE_FLAG_DRAFT;
459     else
460     return ERROR_CONFIG_PARSE;
461 lefcha 1.31
462     t = strtok_r(NULL, ",", &c);
463 lefcha 1.26 }
464     xfree(cp);
465 lefcha 1.29 } else if (!strncasecmp(line + match[1].rm_so, "list", 4)) {
466 lefcha 1.4 cur_fltr->action.type = FILTER_ACTION_LIST;
467 lefcha 1.28 }
468 lefcha 1.26 if (match[10].rm_so != -1) {
469     strncat(cur_fltr->action.args, line + match[10].rm_so,
470     min(match[10].rm_eo - match[10].rm_so, ARGS_LEN - 2));
471 lefcha 1.25 while ((c = strchr(cur_fltr->action.args, ',')))
472     *c = ' ';
473     }
474 lefcha 1.34 if (cur_fltr->action.destmbox && strchr(cur_fltr->action.destmbox, '%')) {
475     te = time(NULL);
476     tl = localtime(&te);
477     if (strftime(s, MBOX_NAME_LEN - 1, cur_fltr->action.destmbox, tl))
478     xstrncpy(cur_fltr->action.destmbox, s, MBOX_NAME_LEN - 1);
479     }
480 lefcha 1.25 #ifdef DEBUG
481 lefcha 1.35 fprintf(stderr, "debug: ACTION: %d '%s' '%s' %d '%s'\n", cur_fltr->action.type,
482 lefcha 1.32 (cur_fltr->action.raccount ? cur_fltr->action.raccount->key : ""),
483     cur_fltr->action.destmbox, cur_fltr->action.msgflags,
484     cur_fltr->action.args);
485 lefcha 1.25 #endif
486 lefcha 1.4 return 0;
487 lefcha 1.1 }
488    
489    
490     /*
491     * Set new mask's variables to safe values.
492     */
493     void init_mask(mask_t * node)
494     {
495     node->next = NULL;
496     node->body[0] = 0;
497     node->type = 0;
498     }
499    
500    
501     /*
502     * Append mask node to linked list.
503     */
504     void append_mask(mask_t * node)
505     {
506     mask_t *pos;
507     mask_t **app;
508    
509     APPEND_LINKED_LIST(cur_fltr->masks, node, pos, app);
510     }
511    
512    
513     /*
514     * A new mask entry was declared, create it and set it's
515     * variables accordingly.
516     */
517 lefcha 1.29 int set_mask(char *line, regmatch_t * match, int mmt)
518 lefcha 1.1 {
519 lefcha 1.29 int n;
520 lefcha 1.1 mask_t *node;
521 lefcha 1.4 char *bp;
522 lefcha 1.5
523 lefcha 1.4 if (!cur_fltr)
524     return ERROR_CONFIG_PARSE;
525 lefcha 1.1
526     node = (mask_t *) create_node(sizeof(mask_t));
527    
528     init_mask(node);
529 lefcha 1.5
530 lefcha 1.4 bp = node->body;
531 lefcha 1.5
532 lefcha 1.4 /* If specified set mask's type. */
533     if (match[2].rm_so != -1 && cur_fltr->masks) {
534 lefcha 1.28 if (!strncasecmp(line + match[2].rm_so, "or", 2)) {
535 lefcha 1.1 node->type = MASK_TYPE_OR;
536 lefcha 1.25 } else
537 lefcha 1.1 node->type = MASK_TYPE_AND;
538     }
539 lefcha 1.4 /* Add NOT if specified. */
540     if (match[3].rm_so != -1) {
541 lefcha 1.16 n = min(match[3].rm_eo - match[3].rm_so,
542 lefcha 1.4 MASK_BODY_LEN - (bp - node->body) - 1);
543 lefcha 1.16 xstrncpy(bp, line + match[3].rm_so, n);
544     string_upper(bp, n);
545     *(bp + n - 1) = ' '; /* In case it's '\t'. */
546     *(bp + n) = 0;
547     bp += n;
548 lefcha 1.1 }
549 lefcha 1.4 /* Keyword of the search key. */
550 lefcha 1.16 n = min(match[4].rm_eo - match[4].rm_so,
551 lefcha 1.4 MASK_BODY_LEN - (bp - node->body) - 3);
552 lefcha 1.16 xstrncpy(bp, line + match[4].rm_so, n);
553     string_upper(bp, n);
554     *(bp + n) = 0;
555     bp += n;
556 lefcha 1.5
557 lefcha 1.29 if (mmt != MASK_MATCH_1) {
558     *(bp++) = ' ';
559    
560     if (mmt != MASK_MATCH_4 && *(line + match[5].rm_so) != '"')
561     *(bp++) = '"';
562     *bp = 0;
563    
564     n = min(match[5].rm_eo - match[5].rm_so,
565     MASK_BODY_LEN - (bp - node->body) - 2);
566     xstrncpy(bp, line + match[5].rm_so, n);
567     *(bp + n) = 0;
568     bp += n;
569    
570     if (mmt != MASK_MATCH_4 && *(line + match[5].rm_so) != '"')
571     *(bp++) = '"';
572     *bp = 0;
573    
574     if (mmt == MASK_MATCH_3) {
575     *(bp++) = ' ';
576    
577     if (*(line + match[6].rm_so) != '"')
578     *(bp++) = '"';
579     *bp = 0;
580    
581     n = min(match[6].rm_eo - match[6].rm_so,
582     MASK_BODY_LEN - (bp - node->body) - 2);
583     xstrncpy(bp, line + match[6].rm_so, n);
584     *(bp + n) = 0;
585     bp += n;
586    
587     if (*(line + match[6].rm_so) != '"')
588     *(bp++) = '"';
589     *bp = 0;
590     }
591     if (mmt == MASK_MATCH_4 && (strstr(node->body, "OLDER") ||
592     strstr(node->body, "NEWER"))) {
593     convert_date(node);
594     bp = node->body + strlen(node->body);
595     }
596     }
597 lefcha 1.1 append_mask(node);
598    
599 lefcha 1.4 cur_fltr->masknum++;
600     cur_fltr->masklen += (bp - node->body);
601 lefcha 1.5
602    
603 lefcha 1.1 #ifdef DEBUG
604 lefcha 1.35 fprintf(stderr, "debug: MASK: '%s'\n", node->body);
605 lefcha 1.1 #endif
606    
607     return 0;
608     }
609    
610    
611     /*
612 lefcha 1.13 * Converts masks related to date filtering, because IMAP servers do not
613     * understand for example "OLDER 3", but "BEFORE 18-Oct-2001" (if
614     * hypothetically current date was 21-Oct-2001).
615     */
616     void convert_date(mask_t * node)
617     {
618     char *cp, *c;
619     char s[16];
620 lefcha 1.34 time_t te;
621     struct tm *tl;
622 lefcha 1.13
623     cp = xstrdup(node->body);
624     node->body[0] = 0;
625    
626 lefcha 1.18 if (strstr(cp, "NOT"))
627     strncat(node->body, "NOT ", 4);
628    
629     if ((c = strstr(cp, "OLDER")))
630 lefcha 1.13 strncat(node->body, "BEFORE ", 7);
631 lefcha 1.18 else if ((c = strstr(cp, "NEWER")))
632 lefcha 1.13 strncat(node->body, "SINCE ", 6);
633    
634 lefcha 1.18 c += 6;
635    
636 lefcha 1.34 te = time(NULL) - (time_t) (strtoul(c, NULL, 10) * 24 * 60 * 60);
637     tl = localtime(&te);
638 lefcha 1.13
639 lefcha 1.34 if (strftime(s, 15, "%d-%b-%Y", tl))
640 lefcha 1.18 strncat(node->body, s, 15);
641 lefcha 1.13
642 lefcha 1.20 xfree(cp);
643 lefcha 1.13 }
644    
645    
646     /*
647 lefcha 1.1 * A new job was declared, link filters with mailbox-groups.
648     */
649     int set_job(char *line, regmatch_t * match)
650     {
651 lefcha 1.16 int n;
652 lefcha 1.4 char *ftok, *gtok, *fltr, *mbgrp, *f, *g;
653 lefcha 1.1 filter_t *cf;
654 lefcha 1.4 mboxgrp_t *cg;
655 lefcha 1.5
656 lefcha 1.10 if (!accounts || !filters || !cur_fltr->action.type)
657 lefcha 1.4 return ERROR_CONFIG_PARSE;
658 lefcha 1.1
659 lefcha 1.16 n = match[1].rm_eo - match[1].rm_so;
660 lefcha 1.26 fltr = (char *)xmalloc(n + 1);
661 lefcha 1.5
662 lefcha 1.16 f = xstrncpy(fltr, line + match[1].rm_so, n);
663     f[n] = 0;
664 lefcha 1.1
665 lefcha 1.16 n = match[2].rm_eo - match[2].rm_so;
666 lefcha 1.26 mbgrp = (char *)xmalloc(n + 1);
667 lefcha 1.5
668 lefcha 1.4 /* Go through filters. */
669 lefcha 1.31 ftok = strtok_r(f, ",", &f);
670     while (ftok) {
671 lefcha 1.1 cf = (filter_t *) find_filter(ftok);
672     if (!cf)
673 lefcha 1.4 return ERROR_CONFIG_PARSE;
674 lefcha 1.5
675 lefcha 1.16 g = xstrncpy(mbgrp, line + match[2].rm_so, n);
676     g[n] = 0;
677 lefcha 1.5
678 lefcha 1.4 /* Go through mailbox groups. */
679 lefcha 1.31 gtok = strtok_r(g, ",", &g);
680     while (gtok) {
681 lefcha 1.4 cg = (mboxgrp_t *) find_mboxgrp(gtok);
682     if (!cg)
683     return ERROR_CONFIG_PARSE;
684     link_mbox_filter(cf, cg);
685 lefcha 1.31
686     gtok = strtok_r(NULL, ",", &g);
687 lefcha 1.1 }
688 lefcha 1.31
689     ftok = strtok_r(NULL, ",", &f);
690 lefcha 1.1 }
691 lefcha 1.5
692 lefcha 1.20 xfree(fltr);
693     xfree(mbgrp);
694 lefcha 1.1
695 lefcha 1.4 return 0;
696 lefcha 1.1 }
697    
698    
699     /*
700     * Link a filter with a mailbox.
701     */
702 lefcha 1.4 void link_mbox_filter(filter_t * cf, mboxgrp_t * cg)
703 lefcha 1.1 {
704 lefcha 1.17 int i, j, f;
705 lefcha 1.5
706     for (i = 0; cg->mboxes[i]; i++) {
707 lefcha 1.4 for (f = j = 0; cg->mboxes[i]->filters[j]; j++)
708     if (j == MBOX_FILTERS_MAX - 1 ||
709 lefcha 1.20 !strcmp(cf->key, cg->mboxes[i]->filters[j]->key))
710 lefcha 1.4 f = 1;
711 lefcha 1.5
712 lefcha 1.4 if (f)
713     continue;
714 lefcha 1.5
715 lefcha 1.4 cg->mboxes[i]->filters[j] = cf;
716     cg->mboxes[i]->filters[j + 1] = NULL;
717 lefcha 1.1
718     }
719    
720     #ifdef DEBUG
721 lefcha 1.35 fprintf(stderr, "debug: JOB: '%s' '%s'\n", cf->key, cg->key);
722 lefcha 1.1 #endif
723     }
724    
725    
726     /*
727 lefcha 1.3 * Free allocated memory of data structures that are not needed anymore.
728     */
729     void destroy_data(void)
730     {
731     destroy_mboxgrp(mboxgrps);
732     }
733    
734    
735     /*
736 lefcha 1.12 * Go through the mailbox-group tree, and free the allocated memory of
737     * each node.
738 lefcha 1.1 */
739     void destroy_mboxgrp(mboxgrp_t * node)
740     {
741 lefcha 1.33 if (!node)
742     return;
743    
744 lefcha 1.7 if (node->left) {
745 lefcha 1.1 destroy_mboxgrp(node->left);
746 lefcha 1.7 node->left = NULL;
747     }
748     if (node->right) {
749 lefcha 1.1 destroy_mboxgrp(node->right);
750 lefcha 1.7 node->right = NULL;
751     }
752 lefcha 1.1 #ifdef DEBUG
753 lefcha 1.35 fprintf(stderr, "debug: deleting FOLDER: '%s'\n", node->key);
754 lefcha 1.1 #endif
755 lefcha 1.5
756 lefcha 1.20 xfree(node);
757 lefcha 1.14 }
758    
759    
760     /*
761 lefcha 1.2 * Convert a string of specified size to upper case.
762     */
763 lefcha 1.4 void string_upper(char *str, size_t size)
764 lefcha 1.2 {
765 lefcha 1.11 unsigned int i;
766 lefcha 1.2
767 lefcha 1.8 for (i = 0; i < size; i++, str++)
768 lefcha 1.13 *str = toupper(*str);
769 lefcha 1.8 }
770    
771    
772     /*
773     * Decode the character triplet, consisting of the character '%'
774     * followed by two hexadecimal digits to its corresponding ASCII
775     * character (described in Section 2.2 of RFC 1738).
776     */
777     int string_decode(char *str)
778     {
779     char *c;
780     char hex[3];
781    
782     c = str;
783    
784     while (*c) {
785     if (*c == '%') {
786 lefcha 1.31 if (!isxdigit((unsigned char)(*(c + 1))) ||
787     !isxdigit((unsigned char)(*(c + 2))))
788 lefcha 1.8 return ERROR_CONFIG_PARSE;
789    
790 lefcha 1.15 xstrncpy(hex, ++c, 2);
791 lefcha 1.8 hex[2] = 0;
792    
793 lefcha 1.31 if (!isprint((unsigned char)(*str = (char)strtoul(hex, NULL, 16))))
794 lefcha 1.8 return ERROR_CONFIG_PARSE;
795    
796     str++;
797     c += 2;
798     } else
799     *(str++) = *(c++);
800     }
801     *str = 0;
802    
803     return 0;
804 lefcha 1.19 }
805    
806    
807     /*
808     * Convert the names of personal mailboxes using the namespace specified
809     * by the mail server.
810     */
811     char *apply_namespace(char *mbox, char *prefix, char delim)
812     {
813     static char m[MBOX_NAME_LEN];
814     char *c;
815    
816     if ((!prefix[0] && !delim) || (!prefix[0] && delim == '/')
817     || !strcasecmp(mbox, "INBOX"))
818     return mbox;
819    
820     m[0] = 0;
821     strncat(m, prefix, MBOX_NAME_LEN - 1);
822     strncat(m, mbox, MBOX_NAME_LEN - strlen(m) - 1);
823    
824     c = m;
825     while ((c = strchr(c, '/')))
826     *(c++) = delim;
827    
828     #ifdef DEBUG
829 lefcha 1.35 fprintf(stderr, "debug: MAILBOX: '%s'\n", m);
830 lefcha 1.19 #endif
831    
832     return m;
833 lefcha 1.1 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26