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

Annotation of /imapfilter/data.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.26 - (hide annotations)
Sat Jul 13 21:19:52 2002 UTC (21 years, 8 months ago) by lefcha
Branch: MAIN
Changes since 1.25: +47 -20 lines
File MIME type: text/plain
Added action flag.

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     printf("debug: ACCOUNT: '%s'\n", node->key);
74     #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     printf("debug: USERNAME: '%s'\n", node->username);
88     #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     printf("debug: PASSWORD: '%s'\n", node->password);
101     #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     printf("debug: SERVER: '%s'\n", node->server);
107     #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     printf("debug: PORT: %d\n", node->port);
116     #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     printf("debug: FOLDER: '%s'\n", node->key);
202     #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.25 while (i < MBOXGRP_MBOXES_MAX - 1 && (tok = strsep(&mboxs, ","))) {
225 lefcha 1.1 node->mboxes[i] = (mbox_t *) set_mbox(tok);
226     node->mboxes[++i] = NULL;
227     }
228     }
229    
230    
231     /*
232     * Find in the mailbox-group tree, the node with the specified key,
233     * and return a pointer to it.
234     */
235     mboxgrp_t *find_mboxgrp(char *key)
236     {
237     int cmp;
238     mboxgrp_t *pos;
239    
240     FIND_TREE(mboxgrps, key, pos, cmp);
241     }
242    
243    
244     /*
245     * Set new mailbox's variables to safe values.
246     */
247     void init_mbox(mbox_t * node)
248     {
249     node->next = NULL;
250 lefcha 1.4 node->name[0] = 0;
251 lefcha 1.1 node->filters[0] = NULL;
252     }
253    
254    
255     /*
256     * Append mailbox node to linked list.
257     */
258     void append_mbox(mbox_t * node)
259     {
260     mbox_t *pos;
261     mbox_t **ins;
262    
263     APPEND_LINKED_LIST(cur_acct->mboxes, node, pos, ins);
264     }
265    
266    
267     /*
268     * A new mailbox was declared, create it and set it's variables accordingly.
269     */
270     mbox_t *set_mbox(char *name)
271     {
272     mbox_t *node;
273    
274     node = (mbox_t *) create_node(sizeof(mbox_t));
275    
276     init_mbox(node);
277    
278 lefcha 1.21 if (*name == '"' && *(name + strlen(name) - 1) == '"')
279     strncat(node->name, name + 1, min(strlen(name) - 2, MBOX_NAME_LEN - 1));
280     else
281     strncat(node->name, name, min(strlen(name), MBOX_NAME_LEN - 1));
282 lefcha 1.1
283     #ifdef DEBUG
284     printf("debug: MBOX: '%s'\n", node->name);
285     #endif
286    
287     append_mbox(node);
288    
289     return node;
290     }
291    
292    
293     /*
294     * Set new filter's variables to safe values.
295     */
296     void init_filter(filter_t * node)
297     {
298     node->left = node->right = NULL;
299 lefcha 1.4 node->key[0] = 0;
300 lefcha 1.1 node->mode = FILTER_MODE_AND;
301     node->action.type = 0;
302 lefcha 1.25 node->action.raccount = NULL;
303 lefcha 1.9 node->action.destmbox[0] = node->action.args[0] = 0;
304 lefcha 1.1 node->masks = NULL;
305 lefcha 1.25 node->masknum = node->ormasknum = node->masklen = 0;
306 lefcha 1.1 }
307    
308    
309     /*
310     * Insert filter node to tree.
311     */
312     void insert_filter(filter_t * node)
313     {
314     int cmp;
315     filter_t *pos;
316     filter_t **ins;
317    
318     INSERT_TREE(filters, node, pos, ins, cmp);
319     }
320    
321    
322     /*
323     * A filter entry was declared, create it and set it's variables accordingly.
324     */
325     int set_filter(char *line, regmatch_t * match)
326     {
327     filter_t *node;
328 lefcha 1.5
329 lefcha 1.4 if (cur_fltr && !cur_fltr->action.type)
330     return ERROR_CONFIG_PARSE;
331 lefcha 1.1
332     node = (filter_t *) create_node(sizeof(filter_t));
333    
334     init_filter(node);
335    
336 lefcha 1.4 strncat(node->key, line + match[1].rm_so,
337     min(match[1].rm_eo - match[1].rm_so, KEY_LEN - 1));
338 lefcha 1.1
339 lefcha 1.4 if (match[2].rm_so != -1) {
340 lefcha 1.9 if (!strncasecmp(line + match[2].rm_so + 1, "or", 2))
341 lefcha 1.1 node->mode = FILTER_MODE_OR;
342     else
343     node->mode = FILTER_MODE_AND;
344     }
345     #ifdef DEBUG
346     printf("debug: FILTER: '%s' %s\n", node->key,
347     (node->mode == FILTER_MODE_OR ? "OR" : "AND"));
348     #endif
349    
350     insert_filter(node);
351     cur_fltr = node;
352    
353     return 0;
354     }
355    
356    
357     /*
358     * Find in the filter tree, the node with the specified key and
359     * return a pointer to it.
360     */
361     filter_t *find_filter(char *key)
362     {
363     int cmp;
364     filter_t *pos;
365    
366     FIND_TREE(filters, key, pos, cmp);
367     }
368    
369    
370     /*
371 lefcha 1.5 * Assign an action to the last declared filter.
372 lefcha 1.1 */
373 lefcha 1.4 int set_action(char *line, regmatch_t * match)
374 lefcha 1.1 {
375 lefcha 1.26 char *c, *cp, *t;
376 lefcha 1.25 account_t *a;
377 lefcha 1.26
378 lefcha 1.1 if (!cur_fltr)
379 lefcha 1.4 return ERROR_CONFIG_PARSE;
380 lefcha 1.7
381 lefcha 1.5 if (!strncasecmp(line + match[1].rm_so, "delete", 6))
382 lefcha 1.4 cur_fltr->action.type = FILTER_ACTION_DELETE;
383 lefcha 1.5 else if (!strncasecmp(line + match[1].rm_so, "copy", 4)) {
384 lefcha 1.4 cur_fltr->action.type = FILTER_ACTION_COPY;
385 lefcha 1.21 if (*(line + match[2].rm_so) == '"' && *(line + match[2].rm_eo - 1) == '"')
386     strncat(cur_fltr->action.destmbox, line + match[2].rm_so + 1,
387 lefcha 1.26 min(match[2].rm_eo - match[2].rm_so - 2, MBOX_NAME_LEN - 1));
388 lefcha 1.21 else
389     strncat(cur_fltr->action.destmbox, line + match[2].rm_so,
390     min(match[2].rm_eo - match[2].rm_so, MBOX_NAME_LEN - 1));
391 lefcha 1.5 } else if (!strncasecmp(line + match[1].rm_so, "move", 4)) {
392 lefcha 1.4 cur_fltr->action.type = FILTER_ACTION_MOVE;
393 lefcha 1.21 if (*(line + match[3].rm_so) == '"' && *(line + match[3].rm_eo - 1) == '"')
394     strncat(cur_fltr->action.destmbox, line + match[3].rm_so + 1,
395 lefcha 1.26 min(match[3].rm_eo - match[3].rm_so - 2, MBOX_NAME_LEN - 1));
396 lefcha 1.21 else
397     strncat(cur_fltr->action.destmbox, line + match[3].rm_so,
398     min(match[3].rm_eo - match[3].rm_so, MBOX_NAME_LEN - 1));
399 lefcha 1.25 } else if (!strncasecmp(line + match[1].rm_so, "rcopy", 5)) {
400     cur_fltr->action.type = FILTER_ACTION_RCOPY;
401     for (a = accounts; a; a = a->next)
402     if (!strncasecmp(line + match[4].rm_so, a->key, strlen(a->key)))
403     cur_fltr->action.raccount = a;
404     if (!cur_fltr->action.raccount)
405 lefcha 1.26 return ERROR_CONFIG_PARSE;
406 lefcha 1.25
407     if (*(line + match[5].rm_so) == '"' && *(line + match[5].rm_eo - 1) == '"')
408     strncat(cur_fltr->action.destmbox, line + match[5].rm_so + 1,
409 lefcha 1.26 min(match[5].rm_eo - match[5].rm_so - 2, MBOX_NAME_LEN - 1));
410 lefcha 1.25 else
411     strncat(cur_fltr->action.destmbox, line + match[5].rm_so,
412     min(match[5].rm_eo - match[5].rm_so, MBOX_NAME_LEN - 1));
413     } else if (!strncasecmp(line + match[1].rm_so, "rmove", 5)) {
414     cur_fltr->action.type = FILTER_ACTION_RMOVE;
415     for (a = accounts; a; a = a->next)
416     if (!strncasecmp(line + match[6].rm_so, a->key, strlen(a->key)))
417     cur_fltr->action.raccount = a;
418     if (!cur_fltr->action.raccount)
419 lefcha 1.26 return ERROR_CONFIG_PARSE;
420 lefcha 1.25
421     if (*(line + match[7].rm_so) == '"' && *(line + match[7].rm_eo - 1) == '"')
422     strncat(cur_fltr->action.destmbox, line + match[7].rm_so + 1,
423 lefcha 1.26 min(match[7].rm_eo - match[7].rm_so - 2, MBOX_NAME_LEN - 1));
424 lefcha 1.25 else
425     strncat(cur_fltr->action.destmbox, line + match[7].rm_so,
426     min(match[7].rm_eo - match[7].rm_so, MBOX_NAME_LEN - 1));
427 lefcha 1.26 } else if (!strncasecmp(line + match[1].rm_so, "flag", 4)) {
428     if (!strncasecmp(line + match[8].rm_so, "replace", 7))
429     cur_fltr->action.type = FILTER_ACTION_FLAG_REPLACE;
430     else if (!strncasecmp(line + match[8].rm_so, "add", 3))
431     cur_fltr->action.type = FILTER_ACTION_FLAG_ADD;
432     else
433     cur_fltr->action.type = FILTER_ACTION_FLAG_REMOVE;
434    
435     c = cp = (char *)malloc(match[9].rm_eo - match[9].rm_so + 1);
436     xstrncpy(c, line + match[9].rm_so, match[9].rm_eo - match[9].rm_so);
437     while ((t = strsep(&c, ","))) {
438     if (!strcasecmp(t, "none")) {
439     if (match[9].rm_eo - match[9].rm_so != strlen("none"))
440     return ERROR_CONFIG_PARSE;
441     } else if (!strcasecmp(t, "seen"))
442     cur_fltr->action.msgflags |= MESSAGE_FLAG_SEEN;
443     else if (!strcasecmp(t, "answered"))
444     cur_fltr->action.msgflags |= MESSAGE_FLAG_ANSWERED;
445     else if (!strcasecmp(t, "flagged"))
446     cur_fltr->action.msgflags |= MESSAGE_FLAG_FLAGGED;
447     else if (!strcasecmp(t, "deleted"))
448     cur_fltr->action.msgflags |= MESSAGE_FLAG_DELETED;
449     else if (!strcasecmp(t, "draft"))
450     cur_fltr->action.msgflags |= MESSAGE_FLAG_DRAFT;
451     else
452     return ERROR_CONFIG_PARSE;
453     }
454     xfree(cp);
455 lefcha 1.5 } else if (!strncasecmp(line + match[1].rm_so, "list", 4))
456 lefcha 1.4 cur_fltr->action.type = FILTER_ACTION_LIST;
457 lefcha 1.7
458 lefcha 1.26 if (match[10].rm_so != -1) {
459     strncat(cur_fltr->action.args, line + match[10].rm_so,
460     min(match[10].rm_eo - match[10].rm_so, ARGS_LEN - 2));
461 lefcha 1.25 while ((c = strchr(cur_fltr->action.args, ',')))
462     *c = ' ';
463     }
464     #ifdef DEBUG
465 lefcha 1.26 printf("debug: ACTION: %d '%s' '%s' %d '%s'\n", cur_fltr->action.type,
466 lefcha 1.25 cur_fltr->action.raccount->key, cur_fltr->action.destmbox,
467 lefcha 1.26 cur_fltr->action.msgflags, cur_fltr->action.args);
468 lefcha 1.25 #endif
469 lefcha 1.4 return 0;
470 lefcha 1.5
471 lefcha 1.1 }
472    
473    
474     /*
475     * Set new mask's variables to safe values.
476     */
477     void init_mask(mask_t * node)
478     {
479     node->next = NULL;
480     node->body[0] = 0;
481     node->type = 0;
482     }
483    
484    
485     /*
486     * Append mask node to linked list.
487     */
488     void append_mask(mask_t * node)
489     {
490     mask_t *pos;
491     mask_t **app;
492    
493     APPEND_LINKED_LIST(cur_fltr->masks, node, pos, app);
494     }
495    
496    
497     /*
498     * A new mask entry was declared, create it and set it's
499     * variables accordingly.
500     */
501     int set_mask(char *line, regmatch_t * match)
502     {
503 lefcha 1.17 int n, i, f = 0;
504 lefcha 1.1 mask_t *node;
505 lefcha 1.4 char *bp;
506 lefcha 1.5
507 lefcha 1.4 if (!cur_fltr)
508     return ERROR_CONFIG_PARSE;
509 lefcha 1.1
510     node = (mask_t *) create_node(sizeof(mask_t));
511    
512     init_mask(node);
513 lefcha 1.5
514 lefcha 1.4 bp = node->body;
515 lefcha 1.5
516 lefcha 1.4 /* If specified set mask's type. */
517     if (match[2].rm_so != -1 && cur_fltr->masks) {
518 lefcha 1.25 if (!strncasecmp(line + match[2].rm_so, "or", 2)) {
519 lefcha 1.1 node->type = MASK_TYPE_OR;
520 lefcha 1.25 if ((cur_fltr->mode = FILTER_MODE_OR))
521     cur_fltr->ormasknum++;
522     } else
523 lefcha 1.1 node->type = MASK_TYPE_AND;
524     }
525 lefcha 1.4 /* Add NOT if specified. */
526     if (match[3].rm_so != -1) {
527 lefcha 1.16 n = min(match[3].rm_eo - match[3].rm_so,
528 lefcha 1.4 MASK_BODY_LEN - (bp - node->body) - 1);
529 lefcha 1.16 xstrncpy(bp, line + match[3].rm_so, n);
530     string_upper(bp, n);
531     *(bp + n - 1) = ' '; /* In case it's '\t'. */
532     *(bp + n) = 0;
533     bp += n;
534 lefcha 1.1 }
535 lefcha 1.4 /* Keyword of the search key. */
536 lefcha 1.16 n = min(match[4].rm_eo - match[4].rm_so,
537 lefcha 1.4 MASK_BODY_LEN - (bp - node->body) - 3);
538 lefcha 1.16 xstrncpy(bp, line + match[4].rm_so, n);
539     string_upper(bp, n);
540     *(bp + n) = 0;
541     bp += n;
542 lefcha 1.5
543 lefcha 1.4 /* Body of the search key (string/number). */
544     for (i = 5; i <= 6; i++)
545     if (match[i].rm_so != -1) {
546     *(bp++) = ' ';
547 lefcha 1.5
548 lefcha 1.4 /* Add '"' if not supplied and search key not a number. */
549     if (match[6].rm_so == -1 &&
550     (strstr(node->body, "LARGER") ||
551 lefcha 1.13 strstr(node->body, "SMALLER") ||
552     strstr(node->body, "OLDER") ||
553     strstr(node->body, "NEWER")))
554 lefcha 1.4 f = 1;
555     else if (*(line + match[i].rm_so) != '"')
556     *(bp++) = '"';
557 lefcha 1.5
558 lefcha 1.4 *bp = 0;
559 lefcha 1.5
560 lefcha 1.16 n = min(match[i].rm_eo - match[i].rm_so,
561 lefcha 1.4 MASK_BODY_LEN - (bp - node->body) - 2);
562 lefcha 1.16 xstrncpy(bp, line + match[i].rm_so, n);
563     *(bp + n) = 0;
564     bp += n;
565 lefcha 1.5
566     if (*(line + match[i].rm_so) != '"' && !f)
567 lefcha 1.4 *(bp++) = '"';
568 lefcha 1.5 *bp = 0;
569 lefcha 1.4 }
570 lefcha 1.18 if (f && (strstr(node->body, "OLDER") || strstr(node->body, "NEWER"))) {
571 lefcha 1.13 convert_date(node);
572 lefcha 1.18 bp = node->body + strlen(node->body);
573     }
574 lefcha 1.1 append_mask(node);
575    
576 lefcha 1.4 cur_fltr->masknum++;
577     cur_fltr->masklen += (bp - node->body);
578 lefcha 1.5
579    
580 lefcha 1.1 #ifdef DEBUG
581     printf("debug: MASK: '%s'\n", node->body);
582     #endif
583    
584     return 0;
585     }
586    
587    
588     /*
589 lefcha 1.13 * Converts masks related to date filtering, because IMAP servers do not
590     * understand for example "OLDER 3", but "BEFORE 18-Oct-2001" (if
591     * hypothetically current date was 21-Oct-2001).
592     */
593     void convert_date(mask_t * node)
594     {
595     char *cp, *c;
596     char s[16];
597     time_t t;
598     struct tm *bt;
599    
600     cp = xstrdup(node->body);
601     node->body[0] = 0;
602    
603 lefcha 1.18 if (strstr(cp, "NOT"))
604     strncat(node->body, "NOT ", 4);
605    
606     if ((c = strstr(cp, "OLDER")))
607 lefcha 1.13 strncat(node->body, "BEFORE ", 7);
608 lefcha 1.18 else if ((c = strstr(cp, "NEWER")))
609 lefcha 1.13 strncat(node->body, "SINCE ", 6);
610    
611 lefcha 1.18 c += 6;
612    
613 lefcha 1.13 t = time(NULL) - (time_t) (strtoul(c, NULL, 10) * 24 * 60 * 60);
614     bt = localtime(&t);
615    
616     if (strftime(s, 15, "%d-%b-%Y", bt))
617 lefcha 1.18 strncat(node->body, s, 15);
618 lefcha 1.13
619 lefcha 1.20 xfree(cp);
620 lefcha 1.13 }
621    
622    
623     /*
624 lefcha 1.1 * A new job was declared, link filters with mailbox-groups.
625     */
626     int set_job(char *line, regmatch_t * match)
627     {
628 lefcha 1.16 int n;
629 lefcha 1.4 char *ftok, *gtok, *fltr, *mbgrp, *f, *g;
630 lefcha 1.1 filter_t *cf;
631 lefcha 1.4 mboxgrp_t *cg;
632 lefcha 1.5
633 lefcha 1.10 if (!accounts || !filters || !cur_fltr->action.type)
634 lefcha 1.4 return ERROR_CONFIG_PARSE;
635 lefcha 1.1
636 lefcha 1.16 n = match[1].rm_eo - match[1].rm_so;
637 lefcha 1.26 fltr = (char *)xmalloc(n + 1);
638 lefcha 1.5
639 lefcha 1.16 f = xstrncpy(fltr, line + match[1].rm_so, n);
640     f[n] = 0;
641 lefcha 1.1
642 lefcha 1.16 n = match[2].rm_eo - match[2].rm_so;
643 lefcha 1.26 mbgrp = (char *)xmalloc(n + 1);
644 lefcha 1.5
645 lefcha 1.4 /* Go through filters. */
646 lefcha 1.25 while ((ftok = strsep(&f, ","))) {
647 lefcha 1.1 cf = (filter_t *) find_filter(ftok);
648     if (!cf)
649 lefcha 1.4 return ERROR_CONFIG_PARSE;
650 lefcha 1.5
651 lefcha 1.16 g = xstrncpy(mbgrp, line + match[2].rm_so, n);
652     g[n] = 0;
653 lefcha 1.5
654 lefcha 1.4 /* Go through mailbox groups. */
655 lefcha 1.25 while ((gtok = strsep(&g, ","))) {
656 lefcha 1.4 cg = (mboxgrp_t *) find_mboxgrp(gtok);
657     if (!cg)
658     return ERROR_CONFIG_PARSE;
659     link_mbox_filter(cf, cg);
660 lefcha 1.1 }
661     }
662 lefcha 1.5
663 lefcha 1.20 xfree(fltr);
664     xfree(mbgrp);
665 lefcha 1.1
666 lefcha 1.4 return 0;
667 lefcha 1.1 }
668    
669    
670     /*
671     * Link a filter with a mailbox.
672     */
673 lefcha 1.4 void link_mbox_filter(filter_t * cf, mboxgrp_t * cg)
674 lefcha 1.1 {
675 lefcha 1.17 int i, j, f;
676 lefcha 1.5
677     for (i = 0; cg->mboxes[i]; i++) {
678 lefcha 1.4 for (f = j = 0; cg->mboxes[i]->filters[j]; j++)
679     if (j == MBOX_FILTERS_MAX - 1 ||
680 lefcha 1.20 !strcmp(cf->key, cg->mboxes[i]->filters[j]->key))
681 lefcha 1.4 f = 1;
682 lefcha 1.5
683 lefcha 1.4 if (f)
684     continue;
685 lefcha 1.5
686 lefcha 1.4 cg->mboxes[i]->filters[j] = cf;
687     cg->mboxes[i]->filters[j + 1] = NULL;
688 lefcha 1.1
689     }
690    
691     #ifdef DEBUG
692 lefcha 1.4 printf("debug: JOB: '%s' '%s'\n", cf->key, cg->key);
693 lefcha 1.1 #endif
694     }
695    
696    
697     /*
698 lefcha 1.3 * Free allocated memory of data structures that are not needed anymore.
699     */
700     void destroy_data(void)
701     {
702     destroy_mboxgrp(mboxgrps);
703     }
704    
705    
706     /*
707 lefcha 1.12 * Go through the mailbox-group tree, and free the allocated memory of
708     * each node.
709 lefcha 1.1 */
710     void destroy_mboxgrp(mboxgrp_t * node)
711     {
712 lefcha 1.7 if (node->left) {
713 lefcha 1.1 destroy_mboxgrp(node->left);
714 lefcha 1.7 node->left = NULL;
715     }
716     if (node->right) {
717 lefcha 1.1 destroy_mboxgrp(node->right);
718 lefcha 1.7 node->right = NULL;
719     }
720 lefcha 1.1 #ifdef DEBUG
721     printf("debug: deleting FOLDER: '%s'\n", node->key);
722     #endif
723 lefcha 1.5
724 lefcha 1.20 xfree(node);
725 lefcha 1.14 }
726    
727    
728     /*
729 lefcha 1.2 * Convert a string of specified size to upper case.
730     */
731 lefcha 1.4 void string_upper(char *str, size_t size)
732 lefcha 1.2 {
733 lefcha 1.11 unsigned int i;
734 lefcha 1.2
735 lefcha 1.8 for (i = 0; i < size; i++, str++)
736 lefcha 1.13 *str = toupper(*str);
737 lefcha 1.8 }
738    
739    
740     /*
741     * Decode the character triplet, consisting of the character '%'
742     * followed by two hexadecimal digits to its corresponding ASCII
743     * character (described in Section 2.2 of RFC 1738).
744     */
745     int string_decode(char *str)
746     {
747     char *c;
748     char hex[3];
749    
750     c = str;
751    
752     while (*c) {
753     if (*c == '%') {
754     if (!isxdigit(*(c + 1)) || !isxdigit(*(c + 2)))
755     return ERROR_CONFIG_PARSE;
756    
757 lefcha 1.15 xstrncpy(hex, ++c, 2);
758 lefcha 1.8 hex[2] = 0;
759    
760 lefcha 1.26 if (!isprint(*str = (char)strtoul(hex, NULL, 16)))
761 lefcha 1.8 return ERROR_CONFIG_PARSE;
762    
763     str++;
764     c += 2;
765     } else
766     *(str++) = *(c++);
767     }
768     *str = 0;
769    
770     return 0;
771 lefcha 1.19 }
772    
773    
774     /*
775     * Convert the names of personal mailboxes using the namespace specified
776     * by the mail server.
777     */
778     char *apply_namespace(char *mbox, char *prefix, char delim)
779     {
780     static char m[MBOX_NAME_LEN];
781     char *c;
782    
783     if ((!prefix[0] && !delim) || (!prefix[0] && delim == '/')
784     || !strcasecmp(mbox, "INBOX"))
785     return mbox;
786    
787     m[0] = 0;
788     strncat(m, prefix, MBOX_NAME_LEN - 1);
789     strncat(m, mbox, MBOX_NAME_LEN - strlen(m) - 1);
790    
791     c = m;
792     while ((c = strchr(c, '/')))
793     *(c++) = delim;
794    
795     #ifdef DEBUG
796     printf("debug: MAILBOX: '%s'\n", m);
797     #endif
798    
799     return m;
800 lefcha 1.1 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26