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

Contents of /imapfilter/data.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.43 - (show annotations)
Thu Jul 31 15:47:37 2003 UTC (20 years, 8 months ago) by lefcha
Branch: MAIN
CVS Tags: HEAD
Changes since 1.42: +0 -0 lines
File MIME type: text/plain
FILE REMOVED
Program and header files, data.c and data.h, broken to new smaller files.

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

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26