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

Contents of /imapfilter/data.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.30.2.1 - (show annotations)
Mon Aug 26 20:18:13 2002 UTC (21 years, 7 months ago) by lefcha
Branch: release-0_8-patches
Changes since 1.30: +20 -6 lines
File MIME type: text/plain
Replace strsep() with POSIX strtok_r().

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 #include <ctype.h>
10 #include <time.h>
11
12 #include "config.h"
13 #include "imapfilter.h"
14 #include "data.h"
15
16
17 extern unsigned int options;
18 extern unsigned int flags;
19
20 account_t *accounts = NULL; /* First node of accounts linked list. */
21 filter_t *filters = NULL; /* First node of filters tree. */
22
23 static mboxgrp_t *mboxgrps = NULL; /* First node of mailbox-groups tree. */
24
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 node->key[0] = node->server[0] = node->username[0] = node->password[0] = 0;
36 node->passwdattr = PASSWORD_NONE;
37 node->port = 143;
38 node->ssl = SSL_DISABLED;
39 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 int n;
62 char p[6];
63 account_t *node;
64
65 node = (account_t *) create_node(sizeof(account_t));
66 node->password = (char *)smalloc(PASSWORD_LEN);
67
68 init_account(node);
69
70 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 } else {
80 strncat(node->username, line + match[5].rm_so,
81 min(match[5].rm_eo - match[5].rm_so, USERNAME_LEN - 1));
82 }
83 if (strchr(node->username, '%'))
84 if (string_decode(node->username))
85 return ERROR_CONFIG_PARSE;
86 #ifdef DEBUG
87 printf("debug: USERNAME: '%s'\n", node->username);
88 #endif
89
90 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 if (strchr(node->password, '%'))
94 if (string_decode(node->password))
95 return ERROR_CONFIG_PARSE;
96 node->passwdattr = PASSWORD_PLAIN;
97 } else
98 flags |= FLAG_BLANK_PASSWORD;
99 #ifdef DEBUG
100 printf("debug: PASSWORD: '%s'\n", node->password);
101 #endif
102
103 strncat(node->server, line + match[6].rm_so,
104 min(match[6].rm_eo - match[6].rm_so, SERVER_LEN - 1));
105 #ifdef DEBUG
106 printf("debug: SERVER: '%s'\n", node->server);
107 #endif
108
109 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 p[n] = 0;
113 node->port = strtoul(p, NULL, 10);
114 #ifdef DEBUG
115 printf("debug: PORT: %d\n", node->port);
116 #endif
117 }
118 if (match[8].rm_so != -1) {
119 if (match[7].rm_so == -1)
120 node->port = 993;
121
122 if (strcasestr(line + match[8].rm_so, "ssl3"))
123 node->ssl = SSL_SSL_V3;
124 else if (strcasestr(line + match[8].rm_so, "tls1"))
125 node->ssl = SSL_TLS_V1;
126 else
127 node->ssl = SSL_SSL_V2;
128 }
129 append_account(node);
130 cur_acct = node;
131
132 return 0;
133 }
134
135
136 #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
153 #endif
154
155 /*
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 node->key[0] = 0;
162 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 mboxs[0] = 0;
189
190 if (!accounts)
191 return ERROR_CONFIG_PARSE;
192
193 node = (mboxgrp_t *) create_node(sizeof(mboxgrp_t));
194
195 init_mboxgrp(node);
196
197 strncat(node->key, line + match[1].rm_so,
198 min(match[1].rm_eo - match[1].rm_so, KEY_LEN - 1));
199
200 #ifdef DEBUG
201 printf("debug: FOLDER: '%s'\n", node->key);
202 #endif
203
204 strncat(mboxs, line + match[2].rm_so,
205 min(match[2].rm_eo - match[2].rm_so, LINE_MAX - 1));
206
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 unsigned int i = 0;
222 char *tok;
223
224 tok = strtok_r(mboxs, ",", &mboxs);
225 while (i < MBOXGRP_MBOXES_MAX - 1 && tok) {
226 node->mboxes[i] = (mbox_t *) set_mbox(tok);
227 node->mboxes[++i] = NULL;
228
229 tok = strtok_r(NULL, ",", &mboxs);
230 }
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 node->name[0] = 0;
254 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 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
286 #ifdef DEBUG
287 printf("debug: MBOX: '%s'\n", node->name);
288 #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 node->key[0] = 0;
303 node->mode = FILTER_MODE_AND;
304 node->action.type = 0;
305 node->action.raccount = NULL;
306 node->action.destmbox[0] = node->action.args[0] = 0;
307 node->masks = NULL;
308 node->masknum = node->masklen = 0;
309 }
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
332 if (cur_fltr && !cur_fltr->action.type)
333 return ERROR_CONFIG_PARSE;
334
335 node = (filter_t *) create_node(sizeof(filter_t));
336
337 init_filter(node);
338
339 strncat(node->key, line + match[1].rm_so,
340 min(match[1].rm_eo - match[1].rm_so, KEY_LEN - 1));
341
342 if (match[2].rm_so != -1) {
343 if (!strncasecmp(line + match[2].rm_so + 1, "or", 2))
344 node->mode = FILTER_MODE_OR;
345 else
346 node->mode = FILTER_MODE_AND;
347 }
348 #ifdef DEBUG
349 printf("debug: FILTER: '%s' %s\n", node->key,
350 (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 * Assign an action to the last declared filter.
375 */
376 int set_action(char *line, regmatch_t * match)
377 {
378 char *c, *cp, *t;
379 account_t *a;
380
381 if (!cur_fltr)
382 return ERROR_CONFIG_PARSE;
383
384 if (!strncasecmp(line + match[1].rm_so, "delete", 6))
385 cur_fltr->action.type = FILTER_ACTION_DELETE;
386 else if (!strncasecmp(line + match[1].rm_so, "copy", 4)) {
387 cur_fltr->action.type = FILTER_ACTION_COPY;
388 if (*(line + match[2].rm_so) == '"' && *(line + match[2].rm_eo - 1) == '"')
389 strncat(cur_fltr->action.destmbox, line + match[2].rm_so + 1,
390 min(match[2].rm_eo - match[2].rm_so - 2, MBOX_NAME_LEN - 1));
391 else
392 strncat(cur_fltr->action.destmbox, line + match[2].rm_so,
393 min(match[2].rm_eo - match[2].rm_so, MBOX_NAME_LEN - 1));
394 } else if (!strncasecmp(line + match[1].rm_so, "move", 4)) {
395 cur_fltr->action.type = FILTER_ACTION_MOVE;
396 if (*(line + match[3].rm_so) == '"' && *(line + match[3].rm_eo - 1) == '"')
397 strncat(cur_fltr->action.destmbox, line + match[3].rm_so + 1,
398 min(match[3].rm_eo - match[3].rm_so - 2, MBOX_NAME_LEN - 1));
399 else
400 strncat(cur_fltr->action.destmbox, line + match[3].rm_so,
401 min(match[3].rm_eo - match[3].rm_so, MBOX_NAME_LEN - 1));
402 } else if (!strncasecmp(line + match[1].rm_so, "rcopy", 5)) {
403 cur_fltr->action.type = FILTER_ACTION_RCOPY;
404 for (a = accounts; a; a = a->next)
405 if (!strncasecmp(line + match[4].rm_so, a->key, strlen(a->key)))
406 cur_fltr->action.raccount = a;
407 if (!cur_fltr->action.raccount)
408 return ERROR_CONFIG_PARSE;
409
410 if (*(line + match[5].rm_so) == '"' && *(line + match[5].rm_eo - 1) == '"')
411 strncat(cur_fltr->action.destmbox, line + match[5].rm_so + 1,
412 min(match[5].rm_eo - match[5].rm_so - 2, MBOX_NAME_LEN - 1));
413 else
414 strncat(cur_fltr->action.destmbox, line + match[5].rm_so,
415 min(match[5].rm_eo - match[5].rm_so, MBOX_NAME_LEN - 1));
416 } else if (!strncasecmp(line + match[1].rm_so, "rmove", 5)) {
417 cur_fltr->action.type = FILTER_ACTION_RMOVE;
418 for (a = accounts; a; a = a->next)
419 if (!strncasecmp(line + match[6].rm_so, a->key, strlen(a->key)))
420 cur_fltr->action.raccount = a;
421 if (!cur_fltr->action.raccount)
422 return ERROR_CONFIG_PARSE;
423
424 if (*(line + match[7].rm_so) == '"' && *(line + match[7].rm_eo - 1) == '"')
425 strncat(cur_fltr->action.destmbox, line + match[7].rm_so + 1,
426 min(match[7].rm_eo - match[7].rm_so - 2, MBOX_NAME_LEN - 1));
427 else
428 strncat(cur_fltr->action.destmbox, line + match[7].rm_so,
429 min(match[7].rm_eo - match[7].rm_so, MBOX_NAME_LEN - 1));
430 } else if (!strncasecmp(line + match[1].rm_so, "flag", 4)) {
431 if (!strncasecmp(line + match[8].rm_so, "replace", 7))
432 cur_fltr->action.type = FILTER_ACTION_FLAG_REPLACE;
433 else if (!strncasecmp(line + match[8].rm_so, "add", 3))
434 cur_fltr->action.type = FILTER_ACTION_FLAG_ADD;
435 else
436 cur_fltr->action.type = FILTER_ACTION_FLAG_REMOVE;
437
438 c = cp = (char *)malloc(match[9].rm_eo - match[9].rm_so + 1);
439 xstrncpy(c, line + match[9].rm_so, match[9].rm_eo - match[9].rm_so);
440
441 t = strtok_r(c, ",", &c);
442 while (t) {
443 if (!strcasecmp(t, "none")) {
444 if (match[9].rm_eo - match[9].rm_so != strlen("none"))
445 return ERROR_CONFIG_PARSE;
446 } else if (!strcasecmp(t, "seen"))
447 cur_fltr->action.msgflags |= MESSAGE_FLAG_SEEN;
448 else if (!strcasecmp(t, "answered"))
449 cur_fltr->action.msgflags |= MESSAGE_FLAG_ANSWERED;
450 else if (!strcasecmp(t, "flagged"))
451 cur_fltr->action.msgflags |= MESSAGE_FLAG_FLAGGED;
452 else if (!strcasecmp(t, "deleted"))
453 cur_fltr->action.msgflags |= MESSAGE_FLAG_DELETED;
454 else if (!strcasecmp(t, "draft"))
455 cur_fltr->action.msgflags |= MESSAGE_FLAG_DRAFT;
456 else
457 return ERROR_CONFIG_PARSE;
458
459 t = strtok_r(NULL, ",", &c);
460 }
461 xfree(cp);
462 } else if (!strncasecmp(line + match[1].rm_so, "list", 4)) {
463 cur_fltr->action.type = FILTER_ACTION_LIST;
464 }
465 if (match[10].rm_so != -1) {
466 strncat(cur_fltr->action.args, line + match[10].rm_so,
467 min(match[10].rm_eo - match[10].rm_so, ARGS_LEN - 2));
468 while ((c = strchr(cur_fltr->action.args, ',')))
469 *c = ' ';
470 }
471 #ifdef DEBUG
472 printf("debug: ACTION: %d '%s' '%s' %d '%s'\n", cur_fltr->action.type,
473 cur_fltr->action.raccount->key, cur_fltr->action.destmbox,
474 cur_fltr->action.msgflags, cur_fltr->action.args);
475 #endif
476 return 0;
477
478 }
479
480
481 /*
482 * Set new mask's variables to safe values.
483 */
484 void init_mask(mask_t * node)
485 {
486 node->next = NULL;
487 node->body[0] = 0;
488 node->type = 0;
489 }
490
491
492 /*
493 * Append mask node to linked list.
494 */
495 void append_mask(mask_t * node)
496 {
497 mask_t *pos;
498 mask_t **app;
499
500 APPEND_LINKED_LIST(cur_fltr->masks, node, pos, app);
501 }
502
503
504 /*
505 * A new mask entry was declared, create it and set it's
506 * variables accordingly.
507 */
508 int set_mask(char *line, regmatch_t * match, int mmt)
509 {
510 int n;
511 mask_t *node;
512 char *bp;
513
514 if (!cur_fltr)
515 return ERROR_CONFIG_PARSE;
516
517 node = (mask_t *) create_node(sizeof(mask_t));
518
519 init_mask(node);
520
521 bp = node->body;
522
523 /* If specified set mask's type. */
524 if (match[2].rm_so != -1 && cur_fltr->masks) {
525 if (!strncasecmp(line + match[2].rm_so, "or", 2)) {
526 node->type = MASK_TYPE_OR;
527 } else
528 node->type = MASK_TYPE_AND;
529 }
530 /* Add NOT if specified. */
531 if (match[3].rm_so != -1) {
532 n = min(match[3].rm_eo - match[3].rm_so,
533 MASK_BODY_LEN - (bp - node->body) - 1);
534 xstrncpy(bp, line + match[3].rm_so, n);
535 string_upper(bp, n);
536 *(bp + n - 1) = ' '; /* In case it's '\t'. */
537 *(bp + n) = 0;
538 bp += n;
539 }
540 /* Keyword of the search key. */
541 n = min(match[4].rm_eo - match[4].rm_so,
542 MASK_BODY_LEN - (bp - node->body) - 3);
543 xstrncpy(bp, line + match[4].rm_so, n);
544 string_upper(bp, n);
545 *(bp + n) = 0;
546 bp += n;
547
548 if (mmt != MASK_MATCH_1) {
549 *(bp++) = ' ';
550
551 if (mmt != MASK_MATCH_4 && *(line + match[5].rm_so) != '"')
552 *(bp++) = '"';
553 *bp = 0;
554
555 n = min(match[5].rm_eo - match[5].rm_so,
556 MASK_BODY_LEN - (bp - node->body) - 2);
557 xstrncpy(bp, line + match[5].rm_so, n);
558 *(bp + n) = 0;
559 bp += n;
560
561 if (mmt != MASK_MATCH_4 && *(line + match[5].rm_so) != '"')
562 *(bp++) = '"';
563 *bp = 0;
564
565 if (mmt == MASK_MATCH_3) {
566 *(bp++) = ' ';
567
568 if (*(line + match[6].rm_so) != '"')
569 *(bp++) = '"';
570 *bp = 0;
571
572 n = min(match[6].rm_eo - match[6].rm_so,
573 MASK_BODY_LEN - (bp - node->body) - 2);
574 xstrncpy(bp, line + match[6].rm_so, n);
575 *(bp + n) = 0;
576 bp += n;
577
578 if (*(line + match[6].rm_so) != '"')
579 *(bp++) = '"';
580 *bp = 0;
581 }
582 if (mmt == MASK_MATCH_4 && (strstr(node->body, "OLDER") ||
583 strstr(node->body, "NEWER"))) {
584 convert_date(node);
585 bp = node->body + strlen(node->body);
586 }
587 }
588 /* for (i = 5; i <= 6; i++)
589 if (match[i].rm_so != -1) {
590 *(bp++) = ' ';
591
592 if (match[6].rm_so == -1 &&
593 (strstr(node->body, "LARGER") ||
594 strstr(node->body, "SMALLER") ||
595 strstr(node->body, "OLDER") ||
596 strstr(node->body, "NEWER")))
597 f = 1;
598 else if (*(line + match[i].rm_so) != '"')
599 *(bp++) = '"';
600
601 *bp = 0;
602
603 n = min(match[i].rm_eo - match[i].rm_so,
604 MASK_BODY_LEN - (bp - node->body) - 2);
605 xstrncpy(bp, line + match[i].rm_so, n);
606 *(bp + n) = 0;
607 bp += n;
608
609 if (*(line + match[i].rm_so) != '"' && !f)
610 *(bp++) = '"';
611 *bp = 0;
612 }
613 if (f && (strstr(node->body, "OLDER") || strstr(node->body, "NEWER"))) {
614 convert_date(node);
615 bp = node->body + strlen(node->body);
616 }*/
617
618 append_mask(node);
619
620 cur_fltr->masknum++;
621 cur_fltr->masklen += (bp - node->body);
622
623
624 #ifdef DEBUG
625 printf("debug: MASK: '%s'\n", node->body);
626 #endif
627
628 return 0;
629 }
630
631
632 /*
633 * Converts masks related to date filtering, because IMAP servers do not
634 * understand for example "OLDER 3", but "BEFORE 18-Oct-2001" (if
635 * hypothetically current date was 21-Oct-2001).
636 */
637 void convert_date(mask_t * node)
638 {
639 char *cp, *c;
640 char s[16];
641 time_t t;
642 struct tm *bt;
643
644 cp = xstrdup(node->body);
645 node->body[0] = 0;
646
647 if (strstr(cp, "NOT"))
648 strncat(node->body, "NOT ", 4);
649
650 if ((c = strstr(cp, "OLDER")))
651 strncat(node->body, "BEFORE ", 7);
652 else if ((c = strstr(cp, "NEWER")))
653 strncat(node->body, "SINCE ", 6);
654
655 c += 6;
656
657 t = time(NULL) - (time_t) (strtoul(c, NULL, 10) * 24 * 60 * 60);
658 bt = localtime(&t);
659
660 if (strftime(s, 15, "%d-%b-%Y", bt))
661 strncat(node->body, s, 15);
662
663 xfree(cp);
664 }
665
666
667 /*
668 * A new job was declared, link filters with mailbox-groups.
669 */
670 int set_job(char *line, regmatch_t * match)
671 {
672 int n;
673 char *ftok, *gtok, *fltr, *mbgrp, *f, *g;
674 filter_t *cf;
675 mboxgrp_t *cg;
676
677 if (!accounts || !filters || !cur_fltr->action.type)
678 return ERROR_CONFIG_PARSE;
679
680 n = match[1].rm_eo - match[1].rm_so;
681 fltr = (char *)xmalloc(n + 1);
682
683 f = xstrncpy(fltr, line + match[1].rm_so, n);
684 f[n] = 0;
685
686 n = match[2].rm_eo - match[2].rm_so;
687 mbgrp = (char *)xmalloc(n + 1);
688
689 /* Go through filters. */
690 ftok = strtok_r(f, ",", &f);
691 while (ftok) {
692 cf = (filter_t *) find_filter(ftok);
693 if (!cf)
694 return ERROR_CONFIG_PARSE;
695
696 g = xstrncpy(mbgrp, line + match[2].rm_so, n);
697 g[n] = 0;
698
699 /* Go through mailbox groups. */
700 gtok = strtok_r(g, ",", &g);
701 while (gtok) {
702 cg = (mboxgrp_t *) find_mboxgrp(gtok);
703 if (!cg)
704 return ERROR_CONFIG_PARSE;
705 link_mbox_filter(cf, cg);
706
707 gtok = strtok_r(NULL, ",", &g);
708 }
709
710 ftok = strtok_r(NULL, ",", &f);
711 }
712
713 xfree(fltr);
714 xfree(mbgrp);
715
716 return 0;
717 }
718
719
720 /*
721 * Link a filter with a mailbox.
722 */
723 void link_mbox_filter(filter_t * cf, mboxgrp_t * cg)
724 {
725 int i, j, f;
726
727 for (i = 0; cg->mboxes[i]; i++) {
728 for (f = j = 0; cg->mboxes[i]->filters[j]; j++)
729 if (j == MBOX_FILTERS_MAX - 1 ||
730 !strcmp(cf->key, cg->mboxes[i]->filters[j]->key))
731 f = 1;
732
733 if (f)
734 continue;
735
736 cg->mboxes[i]->filters[j] = cf;
737 cg->mboxes[i]->filters[j + 1] = NULL;
738
739 }
740
741 #ifdef DEBUG
742 printf("debug: JOB: '%s' '%s'\n", cf->key, cg->key);
743 #endif
744 }
745
746
747 /*
748 * Free allocated memory of data structures that are not needed anymore.
749 */
750 void destroy_data(void)
751 {
752 destroy_mboxgrp(mboxgrps);
753 }
754
755
756 /*
757 * Go through the mailbox-group tree, and free the allocated memory of
758 * each node.
759 */
760 void destroy_mboxgrp(mboxgrp_t * node)
761 {
762 if (node->left) {
763 destroy_mboxgrp(node->left);
764 node->left = NULL;
765 }
766 if (node->right) {
767 destroy_mboxgrp(node->right);
768 node->right = NULL;
769 }
770 #ifdef DEBUG
771 printf("debug: deleting FOLDER: '%s'\n", node->key);
772 #endif
773
774 xfree(node);
775 }
776
777
778 /*
779 * Convert a string of specified size to upper case.
780 */
781 void string_upper(char *str, size_t size)
782 {
783 unsigned int i;
784
785 for (i = 0; i < size; i++, str++)
786 *str = toupper(*str);
787 }
788
789
790 /*
791 * Decode the character triplet, consisting of the character '%'
792 * followed by two hexadecimal digits to its corresponding ASCII
793 * character (described in Section 2.2 of RFC 1738).
794 */
795 int string_decode(char *str)
796 {
797 char *c;
798 char hex[3];
799
800 c = str;
801
802 while (*c) {
803 if (*c == '%') {
804 if (!isxdigit((unsigned char)(*(c + 1))) ||
805 !isxdigit((unsigned char)(*(c + 2))))
806 return ERROR_CONFIG_PARSE;
807
808 xstrncpy(hex, ++c, 2);
809 hex[2] = 0;
810
811 if (!isprint((unsigned char)(*str = (char)strtoul(hex, NULL, 16))))
812 return ERROR_CONFIG_PARSE;
813
814 str++;
815 c += 2;
816 } else
817 *(str++) = *(c++);
818 }
819 *str = 0;
820
821 return 0;
822 }
823
824
825 /*
826 * Convert the names of personal mailboxes using the namespace specified
827 * by the mail server.
828 */
829 char *apply_namespace(char *mbox, char *prefix, char delim)
830 {
831 static char m[MBOX_NAME_LEN];
832 char *c;
833
834 if ((!prefix[0] && !delim) || (!prefix[0] && delim == '/')
835 || !strcasecmp(mbox, "INBOX"))
836 return mbox;
837
838 m[0] = 0;
839 strncat(m, prefix, MBOX_NAME_LEN - 1);
840 strncat(m, mbox, MBOX_NAME_LEN - strlen(m) - 1);
841
842 c = m;
843 while ((c = strchr(c, '/')))
844 *(c++) = delim;
845
846 #ifdef DEBUG
847 printf("debug: MAILBOX: '%s'\n", m);
848 #endif
849
850 return m;
851 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26