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

Contents of /imapfilter/data.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.37 - (show annotations)
Thu Mar 6 15:00:46 2003 UTC (21 years, 1 month ago) by lefcha
Branch: MAIN
Changes since 1.36: +0 -12 lines
File MIME type: text/plain
Add support for date conversion specifiers for current and message time in mailbox names.

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, "ssl3"))
127 node->ssl = SSL_SSL_V3;
128 else if (strcasestr(line + m[8].rm_so, "tls1"))
129 node->ssl = SSL_TLS_V1;
130 else
131 node->ssl = SSL_SSL_V2;
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 mbox_t *node;
291
292 node = (mbox_t *) create_node(sizeof(mbox_t));
293
294 init_mbox(node);
295
296 if (*name == '"' && *(name + strlen(name) - 1) == '"')
297 strncat(node->name, name + 1, min(strlen(name) - 2,
298 MBOX_NAME_LEN - 1));
299 else
300 strncat(node->name, name, min(strlen(name),
301 MBOX_NAME_LEN - 1));
302
303 #ifdef DEBUG
304 fprintf(stderr, "debug: MBOX: '%s'\n", node->name);
305 #endif
306
307 append_mbox(node);
308
309 return node;
310 }
311
312
313 /*
314 * Set new filter's variables to safe values.
315 */
316 void
317 init_filter(filter_t * node)
318 {
319 node->left = node->right = NULL;
320 node->key[0] = '\0';
321 node->mode = FILTER_MODE_AND;
322 node->action.type = 0;
323 node->action.raccount = NULL;
324 node->action.destmbox[0] = node->action.args[0] = '\0';
325 node->masks = NULL;
326 node->masknum = node->masklen = 0;
327 }
328
329
330 /*
331 * Insert filter node to tree.
332 */
333 void
334 insert_filter(filter_t * node)
335 {
336 int cmp;
337 filter_t *pos;
338 filter_t **ins;
339
340 INSERT_TREE(filters, node, pos, ins, cmp);
341 }
342
343
344 /*
345 * A filter entry was declared, create it and set it's variables accordingly.
346 */
347 int
348 set_filter(char *line, regmatch_t * m)
349 {
350 filter_t *node;
351
352 if (cur_fltr != NULL && cur_fltr->action.type == 0)
353 return ERROR_CONFIG_PARSE;
354
355 node = (filter_t *) create_node(sizeof(filter_t));
356
357 init_filter(node);
358
359 strncat(node->key, line + m[1].rm_so,
360 min(m[1].rm_eo - m[1].rm_so, KEY_LEN - 1));
361
362 if (m[2].rm_so != -1) {
363 if (!strncasecmp(line + m[2].rm_so + 1, "or", 2))
364 node->mode = FILTER_MODE_OR;
365 else
366 node->mode = FILTER_MODE_AND;
367 }
368 #ifdef DEBUG
369 fprintf(stderr, "debug: FILTER: '%s' %s\n", node->key,
370 (node->mode == FILTER_MODE_OR ? "OR" : "AND"));
371 #endif
372
373 insert_filter(node);
374 cur_fltr = node;
375
376 return 0;
377 }
378
379
380 /*
381 * Find in the filter tree, the node with the specified key and
382 * return a pointer to it.
383 */
384 filter_t *
385 find_filter(char *key)
386 {
387 int cmp;
388 filter_t *pos;
389
390 FIND_TREE(filters, key, pos, cmp);
391 }
392
393
394 /*
395 * Assign an action to the last declared filter.
396 */
397 int
398 set_action(char *line, regmatch_t * m)
399 {
400 char *c, *cp, *t;
401 account_t *a;
402
403 if (cur_fltr == NULL)
404 return ERROR_CONFIG_PARSE;
405
406 if (!strncasecmp(line + m[1].rm_so, "delete", 6))
407 cur_fltr->action.type = FILTER_ACTION_DELETE;
408 else if (!strncasecmp(line + m[1].rm_so, "copy", 4)) {
409 cur_fltr->action.type = FILTER_ACTION_COPY;
410 if (*(line + m[2].rm_so) == '"' &&
411 *(line + m[2].rm_eo - 1) == '"')
412 strncat(cur_fltr->action.destmbox,
413 line + m[2].rm_so + 1,
414 min(m[2].rm_eo - m[2].rm_so - 2,
415 MBOX_NAME_LEN - 1));
416 else
417 strncat(cur_fltr->action.destmbox, line + m[2].rm_so,
418 min(m[2].rm_eo - m[2].rm_so, MBOX_NAME_LEN - 1));
419 } else if (!strncasecmp(line + m[1].rm_so, "move", 4)) {
420 cur_fltr->action.type = FILTER_ACTION_MOVE;
421 if (*(line + m[3].rm_so) == '"' &&
422 *(line + m[3].rm_eo - 1) == '"')
423 strncat(cur_fltr->action.destmbox,
424 line + m[3].rm_so + 1,
425 min(m[3].rm_eo - m[3].rm_so - 2,
426 MBOX_NAME_LEN - 1));
427 else
428 strncat(cur_fltr->action.destmbox, line + m[3].rm_so,
429 min(m[3].rm_eo - m[3].rm_so, MBOX_NAME_LEN - 1));
430 } else if (!strncasecmp(line + m[1].rm_so, "rcopy", 5)) {
431 cur_fltr->action.type = FILTER_ACTION_RCOPY;
432 for (a = accounts; a; a = a->next)
433 if (!strncasecmp(line + m[4].rm_so, a->key,
434 strlen(a->key)))
435 cur_fltr->action.raccount = a;
436 if (!cur_fltr->action.raccount)
437 return ERROR_CONFIG_PARSE;
438
439 if (*(line + m[5].rm_so) == '"' &&
440 *(line + m[5].rm_eo - 1) == '"')
441 strncat(cur_fltr->action.destmbox,
442 line + m[5].rm_so + 1,
443 min(m[5].rm_eo - m[5].rm_so - 2,
444 MBOX_NAME_LEN - 1));
445 else
446 strncat(cur_fltr->action.destmbox, line + m[5].rm_so,
447 min(m[5].rm_eo - m[5].rm_so, MBOX_NAME_LEN - 1));
448 } else if (!strncasecmp(line + m[1].rm_so, "rmove", 5)) {
449 cur_fltr->action.type = FILTER_ACTION_RMOVE;
450 for (a = accounts; a; a = a->next)
451 if (!strncasecmp(line + m[6].rm_so, a->key,
452 strlen(a->key)))
453 cur_fltr->action.raccount = a;
454 if (!cur_fltr->action.raccount)
455 return ERROR_CONFIG_PARSE;
456
457 if (*(line + m[7].rm_so) == '"' &&
458 *(line + m[7].rm_eo - 1) == '"')
459 strncat(cur_fltr->action.destmbox,
460 line + m[7].rm_so + 1,
461 min(m[7].rm_eo - m[7].rm_so - 2,
462 MBOX_NAME_LEN - 1));
463 else
464 strncat(cur_fltr->action.destmbox, line + m[7].rm_so,
465 min(m[7].rm_eo - m[7].rm_so, MBOX_NAME_LEN - 1));
466 } else if (!strncasecmp(line + m[1].rm_so, "flag", 4)) {
467 if (!strncasecmp(line + m[8].rm_so, "replace", 7))
468 cur_fltr->action.type = FILTER_ACTION_FLAG_REPLACE;
469 else if (!strncasecmp(line + m[8].rm_so, "add", 3))
470 cur_fltr->action.type = FILTER_ACTION_FLAG_ADD;
471 else
472 cur_fltr->action.type = FILTER_ACTION_FLAG_REMOVE;
473
474 c = cp = (char *)malloc(m[9].rm_eo - m[9].rm_so + 1);
475 xstrncpy(c, line + m[9].rm_so, m[9].rm_eo - m[9].rm_so);
476
477 t = strtok_r(c, ",", &c);
478 while (t) {
479 if (!strcasecmp(t, "none")) {
480 if (m[9].rm_eo - m[9].rm_so != strlen("none"))
481 return ERROR_CONFIG_PARSE;
482 } else if (!strcasecmp(t, "seen"))
483 cur_fltr->action.msgflags |= MESSAGE_FLAG_SEEN;
484 else if (!strcasecmp(t, "answered"))
485 cur_fltr->action.msgflags |=
486 MESSAGE_FLAG_ANSWERED;
487 else if (!strcasecmp(t, "flagged"))
488 cur_fltr->action.msgflags |=
489 MESSAGE_FLAG_FLAGGED;
490 else if (!strcasecmp(t, "deleted"))
491 cur_fltr->action.msgflags |=
492 MESSAGE_FLAG_DELETED;
493 else if (!strcasecmp(t, "draft"))
494 cur_fltr->action.msgflags |= MESSAGE_FLAG_DRAFT;
495 else
496 return ERROR_CONFIG_PARSE;
497
498 t = strtok_r(NULL, ",", &c);
499 }
500 xfree(cp);
501 } else if (!strncasecmp(line + m[1].rm_so, "list", 4)) {
502 cur_fltr->action.type = FILTER_ACTION_LIST;
503 }
504 if (m[10].rm_so != -1) {
505 strncat(cur_fltr->action.args, line + m[10].rm_so,
506 min(m[10].rm_eo - m[10].rm_so, ARGS_LEN - 2));
507 while ((c = strchr(cur_fltr->action.args, ',')))
508 *c = ' ';
509 }
510 #ifdef DEBUG
511 fprintf(stderr, "debug: ACTION: %d '%s' '%s' %d '%s'\n",
512 cur_fltr->action.type,
513 (cur_fltr->action.raccount ? cur_fltr->action.raccount->key : ""),
514 cur_fltr->action.destmbox,
515 cur_fltr->action.msgflags,
516 cur_fltr->action.args);
517 #endif
518 return 0;
519 }
520
521
522 /*
523 * Set new mask's variables to safe values.
524 */
525 void
526 init_mask(mask_t * node)
527 {
528 node->next = NULL;
529 node->body[0] = '\0';
530 node->type = 0;
531 }
532
533
534 /*
535 * Append mask node to linked list.
536 */
537 void
538 append_mask(mask_t * node)
539 {
540 mask_t *pos;
541 mask_t **app;
542
543 APPEND_LINKED_LIST(cur_fltr->masks, node, pos, app);
544 }
545
546
547 /*
548 * A new mask entry was declared, create it and set it's
549 * variables accordingly.
550 */
551 int
552 set_mask(char *line, regmatch_t * m, int mmt)
553 {
554 int n;
555 mask_t *node;
556 char *bp;
557
558 if (cur_fltr == NULL)
559 return ERROR_CONFIG_PARSE;
560
561 node = (mask_t *) create_node(sizeof(mask_t));
562
563 init_mask(node);
564
565 bp = node->body;
566
567 /* If specified set mask's type. */
568 if (m[2].rm_so != -1 && cur_fltr->masks) {
569 if (!strncasecmp(line + m[2].rm_so, "or", 2)) {
570 node->type = MASK_TYPE_OR;
571 } else
572 node->type = MASK_TYPE_AND;
573 }
574 /* Add NOT if specified. */
575 if (m[3].rm_so != -1) {
576 n = min(m[3].rm_eo - m[3].rm_so,
577 MASK_BODY_LEN - (bp - node->body) - 1);
578 xstrncpy(bp, line + m[3].rm_so, n);
579 string_upper(bp, n);
580 *(bp + n - 1) = ' '; /* In case it's '\t'. */
581 *(bp + n) = '\0';
582 bp += n;
583 }
584 /* Keyword of the search key. */
585 n = min(m[4].rm_eo - m[4].rm_so,
586 MASK_BODY_LEN - (bp - node->body) - 3);
587 xstrncpy(bp, line + m[4].rm_so, n);
588 string_upper(bp, n);
589 *(bp + n) = '\0';
590 bp += n;
591
592 if (mmt != MASK_MATCH_1) {
593 *(bp++) = ' ';
594
595 if (mmt != MASK_MATCH_4 && *(line + m[5].rm_so) != '"')
596 *(bp++) = '"';
597 *bp = '\0';
598
599 n = min(m[5].rm_eo - m[5].rm_so,
600 MASK_BODY_LEN - (bp - node->body) - 2);
601 xstrncpy(bp, line + m[5].rm_so, n);
602 *(bp + n) = '\0';
603 bp += n;
604
605 if (mmt != MASK_MATCH_4 && *(line + m[5].rm_so) != '"')
606 *(bp++) = '"';
607 *bp = '\0';
608
609 if (mmt == MASK_MATCH_3) {
610 *(bp++) = ' ';
611
612 if (*(line + m[6].rm_so) != '"')
613 *(bp++) = '"';
614 *bp = '\0';
615
616 n = min(m[6].rm_eo - m[6].rm_so,
617 MASK_BODY_LEN - (bp - node->body) - 2);
618 xstrncpy(bp, line + m[6].rm_so, n);
619 *(bp + n) = '\0';
620 bp += n;
621
622 if (*(line + m[6].rm_so) != '"')
623 *(bp++) = '"';
624 *bp = '\0';
625 }
626 if (mmt == MASK_MATCH_4 && (strstr(node->body, "OLDER") ||
627 strstr(node->body, "NEWER"))) {
628 convert_date(node);
629 bp = node->body + strlen(node->body);
630 }
631 }
632 append_mask(node);
633
634 cur_fltr->masknum++;
635 cur_fltr->masklen += (bp - node->body);
636
637
638 #ifdef DEBUG
639 fprintf(stderr, "debug: MASK: '%s'\n", node->body);
640 #endif
641
642 return 0;
643 }
644
645
646 /*
647 * Converts masks related to date filtering, because IMAP servers do not
648 * understand for example "OLDER 3", but "BEFORE 18-Oct-2001" (if
649 * hypothetically current date was 21-Oct-2001).
650 */
651 void
652 convert_date(mask_t * node)
653 {
654 char *cp, *c;
655 char s[16];
656 time_t te;
657 struct tm *tl;
658
659 cp = xstrdup(node->body);
660 node->body[0] = '\0';
661
662 if (strstr(cp, "NOT"))
663 strncat(node->body, "NOT ", 4);
664
665 if ((c = strstr(cp, "OLDER")))
666 strncat(node->body, "BEFORE ", 7);
667 else if ((c = strstr(cp, "NEWER")))
668 strncat(node->body, "SINCE ", 6);
669
670 c += 6;
671
672 te = time(NULL) - (time_t) (strtoul(c, NULL, 10) * 24 * 60 * 60);
673 tl = localtime(&te);
674
675 if (strftime(s, 15, "%d-%b-%Y", tl))
676 strncat(node->body, s, 15);
677
678 xfree(cp);
679 }
680
681
682 /*
683 * A new job was declared, link filters with mailbox-groups.
684 */
685 int
686 set_job(char *line, regmatch_t * match)
687 {
688 int n;
689 char *ftok, *gtok, *fltr, *mbgrp, *f, *g;
690 filter_t *cf;
691 mboxgrp_t *cg;
692
693 if (accounts == NULL || filters == NULL || cur_fltr->action.type == 0)
694 return ERROR_CONFIG_PARSE;
695
696 n = match[1].rm_eo - match[1].rm_so;
697 fltr = (char *)xmalloc(n + 1);
698
699 f = xstrncpy(fltr, line + match[1].rm_so, n);
700 f[n] = '\0';
701
702 n = match[2].rm_eo - match[2].rm_so;
703 mbgrp = (char *)xmalloc(n + 1);
704
705 /* Go through filters. */
706 ftok = strtok_r(f, ",", &f);
707 while (ftok != NULL) {
708 cf = (filter_t *) find_filter(ftok);
709 if (cf == NULL)
710 return ERROR_CONFIG_PARSE;
711
712 g = xstrncpy(mbgrp, line + match[2].rm_so, n);
713 g[n] = '\0';
714
715 /* Go through mailbox groups. */
716 gtok = strtok_r(g, ",", &g);
717 while (gtok != NULL) {
718 cg = (mboxgrp_t *) find_mboxgrp(gtok);
719 if (cg == NULL)
720 return ERROR_CONFIG_PARSE;
721 link_mbox_filter(cf, cg);
722
723 gtok = strtok_r(NULL, ",", &g);
724 }
725
726 ftok = strtok_r(NULL, ",", &f);
727 }
728
729 xfree(fltr);
730 xfree(mbgrp);
731
732 return 0;
733 }
734
735
736 /*
737 * Link a filter with a mailbox.
738 */
739 void
740 link_mbox_filter(filter_t * cf, mboxgrp_t * cg)
741 {
742 int i, j, f;
743
744 for (i = 0; cg->mboxes[i] != NULL; i++) {
745 for (f = j = 0; cg->mboxes[i]->filters[j] != NULL; j++)
746 if (j == MBOX_FILTERS_MAX - 1 ||
747 !strcmp(cf->key, cg->mboxes[i]->filters[j]->key))
748 f = 1;
749
750 if (f)
751 continue;
752
753 cg->mboxes[i]->filters[j] = cf;
754 cg->mboxes[i]->filters[j + 1] = NULL;
755
756 }
757
758 #ifdef DEBUG
759 fprintf(stderr, "debug: JOB: '%s' '%s'\n", cf->key, cg->key);
760 #endif
761 }
762
763
764 /*
765 * Free allocated memory of data structures that are not needed anymore.
766 */
767 void
768 destroy_data(void)
769 {
770 destroy_mboxgrp(mboxgrps);
771 }
772
773
774 /*
775 * Go through the mailbox-group tree, and free the allocated memory of
776 * each node.
777 */
778 void
779 destroy_mboxgrp(mboxgrp_t * node)
780 {
781 if (node == NULL)
782 return;
783
784 if (node->left != NULL) {
785 destroy_mboxgrp(node->left);
786 node->left = NULL;
787 }
788 if (node->right != NULL) {
789 destroy_mboxgrp(node->right);
790 node->right = NULL;
791 }
792 #ifdef DEBUG
793 fprintf(stderr, "debug: deleting FOLDER: '%s'\n", node->key);
794 #endif
795
796 xfree(node);
797 }
798
799
800 /*
801 * Convert a string of specified size to upper case.
802 */
803 void
804 string_upper(char *str, size_t size)
805 {
806 unsigned int i;
807
808 for (i = 0; i < size; i++, str++)
809 *str = toupper(*str);
810 }
811
812
813 /*
814 * Decode the character triplet, consisting of the character '%'
815 * followed by two hexadecimal digits to its corresponding ASCII
816 * character (described in Section 2.2 of RFC 1738).
817 */
818 int
819 string_decode(char *str)
820 {
821 char *c;
822 char hex[3];
823
824 c = str;
825
826 while (*c != '\0') {
827 if (*c == '%') {
828 if (!isxdigit((unsigned char)(*(c + 1))) ||
829 !isxdigit((unsigned char)(*(c + 2))))
830 return ERROR_CONFIG_PARSE;
831
832 xstrncpy(hex, ++c, 2);
833 hex[2] = '\0';
834
835 if (!isprint((unsigned char)(*str = (char)strtoul(hex,
836 NULL, 16))))
837 return ERROR_CONFIG_PARSE;
838
839 str++;
840 c += 2;
841 } else
842 *(str++) = *(c++);
843 }
844 *str = '\0';
845
846 return 0;
847 }
848
849
850 /*
851 * Convert the names of personal mailboxes using the namespace specified
852 * by the mail server.
853 */
854 char *
855 apply_namespace(char *mbox, char *prefix, char delim)
856 {
857 static char m[MBOX_NAME_LEN];
858 char *c;
859
860 if ((prefix[0] == '\0' && delim == '\0') ||
861 (prefix[0] == '\0' && delim == '/') ||
862 !strcasecmp(mbox, "INBOX"))
863 return mbox;
864
865 m[0] = '\0';
866 strncat(m, prefix, MBOX_NAME_LEN - 1);
867 strncat(m, mbox, MBOX_NAME_LEN - strlen(m) - 1);
868
869 c = m;
870 while ((c = strchr(c, '/')))
871 *(c++) = delim;
872
873 #ifdef DEBUG
874 fprintf(stderr, "debug: MAILBOX: '%s'\n", m);
875 #endif
876
877 return m;
878 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26