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

Annotation of /imapfilter/data.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.28 - (hide annotations)
Sat Jul 13 23:03:28 2002 UTC (21 years, 8 months ago) by lefcha
Branch: MAIN
Changes since 1.27: +14 -13 lines
File MIME type: text/plain
Correction on strncasecmp.

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.28 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.28 if (!strncasecmp(line + match[1].rm_so, "delete", 6))
382 lefcha 1.4 cur_fltr->action.type = FILTER_ACTION_DELETE;
383 lefcha 1.28 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.28 } 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.28 } else if (!strncasecmp(line + match[1].rm_so, "rcopy", 5)) {
400 lefcha 1.25 cur_fltr->action.type = FILTER_ACTION_RCOPY;
401     for (a = accounts; a; a = a->next)
402 lefcha 1.28 if (!strncasecmp(line + match[4].rm_so, a->key, strlen(a->key)))
403 lefcha 1.25 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 lefcha 1.28 } else if (!strncasecmp(line + match[1].rm_so, "rmove", 5)) {
414 lefcha 1.25 cur_fltr->action.type = FILTER_ACTION_RMOVE;
415     for (a = accounts; a; a = a->next)
416 lefcha 1.28 if (!strncasecmp(line + match[6].rm_so, a->key, strlen(a->key)))
417 lefcha 1.25 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.28 } else if (!strncasecmp(line + match[1].rm_so, "flag", 4)) {
428     if (!strncasecmp(line + match[8].rm_so, "replace", 7))
429 lefcha 1.26 cur_fltr->action.type = FILTER_ACTION_FLAG_REPLACE;
430 lefcha 1.28 else if (!strncasecmp(line + match[8].rm_so, "add", 3))
431 lefcha 1.26 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.28 } else if (!strncasecmp(line + match[1].rm_so, "list", 4)){
456 lefcha 1.4 cur_fltr->action.type = FILTER_ACTION_LIST;
457 lefcha 1.28 }
458 lefcha 1.7
459 lefcha 1.26 if (match[10].rm_so != -1) {
460     strncat(cur_fltr->action.args, line + match[10].rm_so,
461     min(match[10].rm_eo - match[10].rm_so, ARGS_LEN - 2));
462 lefcha 1.25 while ((c = strchr(cur_fltr->action.args, ',')))
463     *c = ' ';
464     }
465     #ifdef DEBUG
466 lefcha 1.26 printf("debug: ACTION: %d '%s' '%s' %d '%s'\n", cur_fltr->action.type,
467 lefcha 1.25 cur_fltr->action.raccount->key, cur_fltr->action.destmbox,
468 lefcha 1.26 cur_fltr->action.msgflags, cur_fltr->action.args);
469 lefcha 1.25 #endif
470 lefcha 1.4 return 0;
471 lefcha 1.5
472 lefcha 1.1 }
473    
474    
475     /*
476     * Set new mask's variables to safe values.
477     */
478     void init_mask(mask_t * node)
479     {
480     node->next = NULL;
481     node->body[0] = 0;
482     node->type = 0;
483     }
484    
485    
486     /*
487     * Append mask node to linked list.
488     */
489     void append_mask(mask_t * node)
490     {
491     mask_t *pos;
492     mask_t **app;
493    
494     APPEND_LINKED_LIST(cur_fltr->masks, node, pos, app);
495     }
496    
497    
498     /*
499     * A new mask entry was declared, create it and set it's
500     * variables accordingly.
501     */
502     int set_mask(char *line, regmatch_t * match)
503     {
504 lefcha 1.17 int n, i, f = 0;
505 lefcha 1.1 mask_t *node;
506 lefcha 1.4 char *bp;
507 lefcha 1.5
508 lefcha 1.4 if (!cur_fltr)
509     return ERROR_CONFIG_PARSE;
510 lefcha 1.1
511     node = (mask_t *) create_node(sizeof(mask_t));
512    
513     init_mask(node);
514 lefcha 1.5
515 lefcha 1.4 bp = node->body;
516 lefcha 1.5
517 lefcha 1.4 /* If specified set mask's type. */
518     if (match[2].rm_so != -1 && cur_fltr->masks) {
519 lefcha 1.28 if (!strncasecmp(line + match[2].rm_so, "or", 2)) {
520 lefcha 1.1 node->type = MASK_TYPE_OR;
521 lefcha 1.25 if ((cur_fltr->mode = FILTER_MODE_OR))
522     cur_fltr->ormasknum++;
523     } else
524 lefcha 1.1 node->type = MASK_TYPE_AND;
525     }
526 lefcha 1.4 /* Add NOT if specified. */
527     if (match[3].rm_so != -1) {
528 lefcha 1.16 n = min(match[3].rm_eo - match[3].rm_so,
529 lefcha 1.4 MASK_BODY_LEN - (bp - node->body) - 1);
530 lefcha 1.16 xstrncpy(bp, line + match[3].rm_so, n);
531     string_upper(bp, n);
532     *(bp + n - 1) = ' '; /* In case it's '\t'. */
533     *(bp + n) = 0;
534     bp += n;
535 lefcha 1.1 }
536 lefcha 1.4 /* Keyword of the search key. */
537 lefcha 1.16 n = min(match[4].rm_eo - match[4].rm_so,
538 lefcha 1.4 MASK_BODY_LEN - (bp - node->body) - 3);
539 lefcha 1.16 xstrncpy(bp, line + match[4].rm_so, n);
540     string_upper(bp, n);
541     *(bp + n) = 0;
542     bp += n;
543 lefcha 1.5
544 lefcha 1.4 /* Body of the search key (string/number). */
545     for (i = 5; i <= 6; i++)
546     if (match[i].rm_so != -1) {
547     *(bp++) = ' ';
548 lefcha 1.5
549 lefcha 1.4 /* Add '"' if not supplied and search key not a number. */
550     if (match[6].rm_so == -1 &&
551     (strstr(node->body, "LARGER") ||
552 lefcha 1.13 strstr(node->body, "SMALLER") ||
553     strstr(node->body, "OLDER") ||
554     strstr(node->body, "NEWER")))
555 lefcha 1.4 f = 1;
556     else if (*(line + match[i].rm_so) != '"')
557     *(bp++) = '"';
558 lefcha 1.5
559 lefcha 1.4 *bp = 0;
560 lefcha 1.5
561 lefcha 1.16 n = min(match[i].rm_eo - match[i].rm_so,
562 lefcha 1.4 MASK_BODY_LEN - (bp - node->body) - 2);
563 lefcha 1.16 xstrncpy(bp, line + match[i].rm_so, n);
564     *(bp + n) = 0;
565     bp += n;
566 lefcha 1.5
567     if (*(line + match[i].rm_so) != '"' && !f)
568 lefcha 1.4 *(bp++) = '"';
569 lefcha 1.5 *bp = 0;
570 lefcha 1.4 }
571 lefcha 1.18 if (f && (strstr(node->body, "OLDER") || strstr(node->body, "NEWER"))) {
572 lefcha 1.13 convert_date(node);
573 lefcha 1.18 bp = node->body + strlen(node->body);
574     }
575 lefcha 1.1 append_mask(node);
576    
577 lefcha 1.4 cur_fltr->masknum++;
578     cur_fltr->masklen += (bp - node->body);
579 lefcha 1.5
580    
581 lefcha 1.1 #ifdef DEBUG
582     printf("debug: MASK: '%s'\n", node->body);
583     #endif
584    
585     return 0;
586     }
587    
588    
589     /*
590 lefcha 1.13 * Converts masks related to date filtering, because IMAP servers do not
591     * understand for example "OLDER 3", but "BEFORE 18-Oct-2001" (if
592     * hypothetically current date was 21-Oct-2001).
593     */
594     void convert_date(mask_t * node)
595     {
596     char *cp, *c;
597     char s[16];
598     time_t t;
599     struct tm *bt;
600    
601     cp = xstrdup(node->body);
602     node->body[0] = 0;
603    
604 lefcha 1.18 if (strstr(cp, "NOT"))
605     strncat(node->body, "NOT ", 4);
606    
607     if ((c = strstr(cp, "OLDER")))
608 lefcha 1.13 strncat(node->body, "BEFORE ", 7);
609 lefcha 1.18 else if ((c = strstr(cp, "NEWER")))
610 lefcha 1.13 strncat(node->body, "SINCE ", 6);
611    
612 lefcha 1.18 c += 6;
613    
614 lefcha 1.13 t = time(NULL) - (time_t) (strtoul(c, NULL, 10) * 24 * 60 * 60);
615     bt = localtime(&t);
616    
617     if (strftime(s, 15, "%d-%b-%Y", bt))
618 lefcha 1.18 strncat(node->body, s, 15);
619 lefcha 1.13
620 lefcha 1.20 xfree(cp);
621 lefcha 1.13 }
622    
623    
624     /*
625 lefcha 1.1 * A new job was declared, link filters with mailbox-groups.
626     */
627     int set_job(char *line, regmatch_t * match)
628     {
629 lefcha 1.16 int n;
630 lefcha 1.4 char *ftok, *gtok, *fltr, *mbgrp, *f, *g;
631 lefcha 1.1 filter_t *cf;
632 lefcha 1.4 mboxgrp_t *cg;
633 lefcha 1.5
634 lefcha 1.10 if (!accounts || !filters || !cur_fltr->action.type)
635 lefcha 1.4 return ERROR_CONFIG_PARSE;
636 lefcha 1.1
637 lefcha 1.16 n = match[1].rm_eo - match[1].rm_so;
638 lefcha 1.26 fltr = (char *)xmalloc(n + 1);
639 lefcha 1.5
640 lefcha 1.16 f = xstrncpy(fltr, line + match[1].rm_so, n);
641     f[n] = 0;
642 lefcha 1.1
643 lefcha 1.16 n = match[2].rm_eo - match[2].rm_so;
644 lefcha 1.26 mbgrp = (char *)xmalloc(n + 1);
645 lefcha 1.5
646 lefcha 1.4 /* Go through filters. */
647 lefcha 1.25 while ((ftok = strsep(&f, ","))) {
648 lefcha 1.1 cf = (filter_t *) find_filter(ftok);
649     if (!cf)
650 lefcha 1.4 return ERROR_CONFIG_PARSE;
651 lefcha 1.5
652 lefcha 1.16 g = xstrncpy(mbgrp, line + match[2].rm_so, n);
653     g[n] = 0;
654 lefcha 1.5
655 lefcha 1.4 /* Go through mailbox groups. */
656 lefcha 1.25 while ((gtok = strsep(&g, ","))) {
657 lefcha 1.4 cg = (mboxgrp_t *) find_mboxgrp(gtok);
658     if (!cg)
659     return ERROR_CONFIG_PARSE;
660     link_mbox_filter(cf, cg);
661 lefcha 1.1 }
662     }
663 lefcha 1.5
664 lefcha 1.20 xfree(fltr);
665     xfree(mbgrp);
666 lefcha 1.1
667 lefcha 1.4 return 0;
668 lefcha 1.1 }
669    
670    
671     /*
672     * Link a filter with a mailbox.
673     */
674 lefcha 1.4 void link_mbox_filter(filter_t * cf, mboxgrp_t * cg)
675 lefcha 1.1 {
676 lefcha 1.17 int i, j, f;
677 lefcha 1.5
678     for (i = 0; cg->mboxes[i]; i++) {
679 lefcha 1.4 for (f = j = 0; cg->mboxes[i]->filters[j]; j++)
680     if (j == MBOX_FILTERS_MAX - 1 ||
681 lefcha 1.20 !strcmp(cf->key, cg->mboxes[i]->filters[j]->key))
682 lefcha 1.4 f = 1;
683 lefcha 1.5
684 lefcha 1.4 if (f)
685     continue;
686 lefcha 1.5
687 lefcha 1.4 cg->mboxes[i]->filters[j] = cf;
688     cg->mboxes[i]->filters[j + 1] = NULL;
689 lefcha 1.1
690     }
691    
692     #ifdef DEBUG
693 lefcha 1.4 printf("debug: JOB: '%s' '%s'\n", cf->key, cg->key);
694 lefcha 1.1 #endif
695     }
696    
697    
698     /*
699 lefcha 1.3 * Free allocated memory of data structures that are not needed anymore.
700     */
701     void destroy_data(void)
702     {
703     destroy_mboxgrp(mboxgrps);
704     }
705    
706    
707     /*
708 lefcha 1.12 * Go through the mailbox-group tree, and free the allocated memory of
709     * each node.
710 lefcha 1.1 */
711     void destroy_mboxgrp(mboxgrp_t * node)
712     {
713 lefcha 1.7 if (node->left) {
714 lefcha 1.1 destroy_mboxgrp(node->left);
715 lefcha 1.7 node->left = NULL;
716     }
717     if (node->right) {
718 lefcha 1.1 destroy_mboxgrp(node->right);
719 lefcha 1.7 node->right = NULL;
720     }
721 lefcha 1.1 #ifdef DEBUG
722     printf("debug: deleting FOLDER: '%s'\n", node->key);
723     #endif
724 lefcha 1.5
725 lefcha 1.20 xfree(node);
726 lefcha 1.14 }
727    
728    
729     /*
730 lefcha 1.2 * Convert a string of specified size to upper case.
731     */
732 lefcha 1.4 void string_upper(char *str, size_t size)
733 lefcha 1.2 {
734 lefcha 1.11 unsigned int i;
735 lefcha 1.2
736 lefcha 1.8 for (i = 0; i < size; i++, str++)
737 lefcha 1.13 *str = toupper(*str);
738 lefcha 1.8 }
739    
740    
741     /*
742     * Decode the character triplet, consisting of the character '%'
743     * followed by two hexadecimal digits to its corresponding ASCII
744     * character (described in Section 2.2 of RFC 1738).
745     */
746     int string_decode(char *str)
747     {
748     char *c;
749     char hex[3];
750    
751     c = str;
752    
753     while (*c) {
754     if (*c == '%') {
755     if (!isxdigit(*(c + 1)) || !isxdigit(*(c + 2)))
756     return ERROR_CONFIG_PARSE;
757    
758 lefcha 1.15 xstrncpy(hex, ++c, 2);
759 lefcha 1.8 hex[2] = 0;
760    
761 lefcha 1.26 if (!isprint(*str = (char)strtoul(hex, NULL, 16)))
762 lefcha 1.8 return ERROR_CONFIG_PARSE;
763    
764     str++;
765     c += 2;
766     } else
767     *(str++) = *(c++);
768     }
769     *str = 0;
770    
771     return 0;
772 lefcha 1.19 }
773    
774    
775     /*
776     * Convert the names of personal mailboxes using the namespace specified
777     * by the mail server.
778     */
779     char *apply_namespace(char *mbox, char *prefix, char delim)
780     {
781     static char m[MBOX_NAME_LEN];
782     char *c;
783    
784     if ((!prefix[0] && !delim) || (!prefix[0] && delim == '/')
785     || !strcasecmp(mbox, "INBOX"))
786     return mbox;
787    
788     m[0] = 0;
789     strncat(m, prefix, MBOX_NAME_LEN - 1);
790     strncat(m, mbox, MBOX_NAME_LEN - strlen(m) - 1);
791    
792     c = m;
793     while ((c = strchr(c, '/')))
794     *(c++) = delim;
795    
796     #ifdef DEBUG
797     printf("debug: MAILBOX: '%s'\n", m);
798     #endif
799    
800     return m;
801 lefcha 1.1 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26