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

Annotation of /imapfilter/data.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.24 - (hide annotations)
Fri Feb 8 22:15:43 2002 UTC (22 years, 1 month ago) by lefcha
Branch: MAIN
Changes since 1.23: +0 -4 lines
File MIME type: text/plain
Allow ssl appear in config file, but fail with error message.

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.5 static mboxgrp_t *mboxgrps = NULL; /* First node of mailbox-groups
24     tree. */
25 lefcha 1.1
26     static account_t *cur_acct = NULL; /* Current account. */
27     static filter_t *cur_fltr = NULL; /* Current filter. */
28    
29    
30     /*
31     * Set new account's variables to safe values.
32     */
33     void init_account(account_t * node)
34     {
35     node->next = NULL;
36     node->server[0] = node->username[0] = node->password[0] = 0;
37 lefcha 1.20 node->passwdattr = PASSWORD_NONE;
38 lefcha 1.1 node->port = 143;
39 lefcha 1.12 node->ssl = SSL_DISABLED;
40 lefcha 1.1 node->mboxes = NULL;
41     }
42    
43    
44     /*
45     * Append account node to linked list.
46     */
47     void append_account(account_t * node)
48     {
49     account_t *pos;
50     account_t **app;
51    
52     APPEND_LINKED_LIST(accounts, node, pos, app);
53     }
54    
55    
56     /*
57     * A new account entry was declared. Create it and set it's variables
58     * accordingly.
59     */
60     int set_account(char *line, regmatch_t * match)
61     {
62 lefcha 1.16 int n;
63 lefcha 1.1 char p[6];
64     account_t *node;
65 lefcha 1.5
66 lefcha 1.1 node = (account_t *) create_node(sizeof(account_t));
67 lefcha 1.22 node->password = (char *) smalloc(PASSWORD_LEN);
68 lefcha 1.1
69     init_account(node);
70 lefcha 1.20
71 lefcha 1.19 if (match[2].rm_so != -1) {
72     strncat(node->username, line + match[2].rm_so,
73     min(match[2].rm_eo - match[2].rm_so, USERNAME_LEN - 1));
74     } else {
75     strncat(node->username, line + match[4].rm_so,
76     min(match[4].rm_eo - match[4].rm_so, USERNAME_LEN - 1));
77     }
78 lefcha 1.8 if (strchr(node->username, '%'))
79     if (string_decode(node->username))
80     return ERROR_CONFIG_PARSE;
81 lefcha 1.1 #ifdef DEBUG
82     printf("debug: USERNAME: '%s'\n", node->username);
83     #endif
84 lefcha 1.20
85 lefcha 1.19 if (match[3].rm_so != -1) {
86     strncat(node->password, line + match[3].rm_so,
87     min(match[3].rm_eo - match[3].rm_so, PASSWORD_LEN - 1));
88     if (strchr(node->password, '%'))
89     if (string_decode(node->password))
90     return ERROR_CONFIG_PARSE;
91 lefcha 1.20 node->passwdattr = PASSWORD_PLAIN;
92 lefcha 1.23 } else
93     flags |= FLAG_BLANK_PASSWORD;
94 lefcha 1.1 #ifdef DEBUG
95     printf("debug: PASSWORD: '%s'\n", node->password);
96     #endif
97    
98 lefcha 1.19 strncat(node->server, line + match[5].rm_so,
99     min(match[5].rm_eo - match[5].rm_so, SERVER_LEN - 1));
100 lefcha 1.1 #ifdef DEBUG
101     printf("debug: SERVER: '%s'\n", node->server);
102     #endif
103    
104 lefcha 1.19 if (match[6].rm_so != -1) {
105     n = min(match[6].rm_eo - match[6].rm_so - 1, 5);
106     xstrncpy(p, line + match[6].rm_so + 1, n);
107 lefcha 1.16 p[n] = 0;
108 lefcha 1.11 node->port = strtoul(p, NULL, 10);
109 lefcha 1.1 #ifdef DEBUG
110     printf("debug: PORT: %d\n", node->port);
111     #endif
112     }
113 lefcha 1.19 if (match[7].rm_so != -1) {
114     if (match[6].rm_so == -1)
115 lefcha 1.12 node->port = 993;
116    
117 lefcha 1.19 if (strcasestr(line + match[7].rm_so, "ssl3"))
118 lefcha 1.12 node->ssl = SSL_SSL_V3;
119 lefcha 1.19 else if (strcasestr(line + match[7].rm_so, "tls1"))
120 lefcha 1.12 node->ssl = SSL_TLS_V1;
121     else
122     node->ssl = SSL_SSL_V2;
123     }
124 lefcha 1.1 append_account(node);
125     cur_acct = node;
126    
127     return 0;
128     }
129    
130    
131 lefcha 1.20 #ifdef ENCRYPTED_PASSWORDS
132     /*
133     * Find accounts without a password (candicates for password encryption).
134     */
135     char *find_password(char *user, char *serv)
136     {
137     account_t *a;
138    
139     for (a = accounts; a; a = a->next)
140     if (a->passwdattr == PASSWORD_NONE && !strcmp(a->server, serv) &&
141     !strcmp(a->username, user)) {
142     a->passwdattr = PASSWORD_ENCRYPTED;
143     return a->password;
144     }
145     return NULL;
146     }
147     #endif
148    
149 lefcha 1.1 /*
150     * Set new mailbox-group's variables to safe values.
151     */
152     void init_mboxgrp(mboxgrp_t * node)
153     {
154     node->left = node->right = NULL;
155 lefcha 1.4 node->key[0] = 0;
156 lefcha 1.1 node->mboxes[0] = NULL;
157     }
158    
159    
160     /*
161     * Insert mailbox-group node in tree.
162     */
163     void insert_mboxgrp(mboxgrp_t * node)
164     {
165     int cmp;
166     mboxgrp_t *pos;
167     mboxgrp_t **ins;
168    
169     INSERT_TREE(mboxgrps, node, pos, ins, cmp);
170     }
171    
172    
173     /*
174     * A new mailbox-group entry was declared. Create it and set it's variables
175     * accordingly.
176     */
177     int set_mboxgrp(char *line, regmatch_t * match)
178     {
179     mboxgrp_t *node;
180     char mboxs[LINE_MAX];
181    
182 lefcha 1.4 mboxs[0] = 0;
183    
184 lefcha 1.1 if (!accounts)
185 lefcha 1.4 return ERROR_CONFIG_PARSE;
186 lefcha 1.1
187     node = (mboxgrp_t *) create_node(sizeof(mboxgrp_t));
188    
189     init_mboxgrp(node);
190    
191 lefcha 1.4 strncat(node->key, line + match[1].rm_so,
192     min(match[1].rm_eo - match[1].rm_so, KEY_LEN - 1));
193 lefcha 1.1
194     #ifdef DEBUG
195     printf("debug: FOLDER: '%s'\n", node->key);
196     #endif
197    
198 lefcha 1.4 strncat(mboxs, line + match[2].rm_so,
199     min(match[2].rm_eo - match[2].rm_so, LINE_MAX - 1));
200 lefcha 1.1
201     process_mboxgrp(node, mboxs);
202    
203     insert_mboxgrp(node);
204    
205     return 0;
206     }
207    
208    
209     /*
210     * Calls set_mbox() in order to create mailboxes that are part of
211     * the mailbox-group.
212     */
213     void process_mboxgrp(mboxgrp_t * node, char *mboxs)
214     {
215 lefcha 1.16 unsigned int i = 0;
216 lefcha 1.1 const char *delim = ",";
217     char *tok;
218    
219 lefcha 1.4 while (i < MBOXGRP_MBOXES_MAX - 1 && (tok = strsep(&mboxs, delim))) {
220 lefcha 1.1 node->mboxes[i] = (mbox_t *) set_mbox(tok);
221     node->mboxes[++i] = NULL;
222     }
223     }
224    
225    
226     /*
227     * Find in the mailbox-group tree, the node with the specified key,
228     * and return a pointer to it.
229     */
230     mboxgrp_t *find_mboxgrp(char *key)
231     {
232     int cmp;
233     mboxgrp_t *pos;
234    
235     FIND_TREE(mboxgrps, key, pos, cmp);
236     }
237    
238    
239     /*
240     * Set new mailbox's variables to safe values.
241     */
242     void init_mbox(mbox_t * node)
243     {
244     node->next = NULL;
245 lefcha 1.4 node->name[0] = 0;
246 lefcha 1.1 node->filters[0] = NULL;
247     }
248    
249    
250     /*
251     * Append mailbox node to linked list.
252     */
253     void append_mbox(mbox_t * node)
254     {
255     mbox_t *pos;
256     mbox_t **ins;
257    
258     APPEND_LINKED_LIST(cur_acct->mboxes, node, pos, ins);
259     }
260    
261    
262     /*
263     * A new mailbox was declared, create it and set it's variables accordingly.
264     */
265     mbox_t *set_mbox(char *name)
266     {
267     mbox_t *node;
268    
269     node = (mbox_t *) create_node(sizeof(mbox_t));
270    
271     init_mbox(node);
272    
273 lefcha 1.21 if (*name == '"' && *(name + strlen(name) - 1) == '"')
274     strncat(node->name, name + 1, min(strlen(name) - 2, MBOX_NAME_LEN - 1));
275     else
276     strncat(node->name, name, min(strlen(name), MBOX_NAME_LEN - 1));
277 lefcha 1.1
278     #ifdef DEBUG
279     printf("debug: MBOX: '%s'\n", node->name);
280     #endif
281    
282     append_mbox(node);
283    
284     return node;
285     }
286    
287    
288     /*
289     * Set new filter's variables to safe values.
290     */
291     void init_filter(filter_t * node)
292     {
293     node->left = node->right = NULL;
294 lefcha 1.4 node->key[0] = 0;
295 lefcha 1.1 node->mode = FILTER_MODE_AND;
296     node->action.type = 0;
297 lefcha 1.9 node->action.destmbox[0] = node->action.args[0] = 0;
298 lefcha 1.1 node->masks = NULL;
299 lefcha 1.4 node->masknum = node->masklen = 0;
300 lefcha 1.1 }
301    
302    
303     /*
304     * Insert filter node to tree.
305     */
306     void insert_filter(filter_t * node)
307     {
308     int cmp;
309     filter_t *pos;
310     filter_t **ins;
311    
312     INSERT_TREE(filters, node, pos, ins, cmp);
313     }
314    
315    
316     /*
317     * A filter entry was declared, create it and set it's variables accordingly.
318     */
319     int set_filter(char *line, regmatch_t * match)
320     {
321     filter_t *node;
322 lefcha 1.5
323 lefcha 1.4 if (cur_fltr && !cur_fltr->action.type)
324     return ERROR_CONFIG_PARSE;
325 lefcha 1.1
326     node = (filter_t *) create_node(sizeof(filter_t));
327    
328     init_filter(node);
329    
330 lefcha 1.4 strncat(node->key, line + match[1].rm_so,
331     min(match[1].rm_eo - match[1].rm_so, KEY_LEN - 1));
332 lefcha 1.1
333 lefcha 1.4 if (match[2].rm_so != -1) {
334 lefcha 1.9 if (!strncasecmp(line + match[2].rm_so + 1, "or", 2))
335 lefcha 1.1 node->mode = FILTER_MODE_OR;
336     else
337     node->mode = FILTER_MODE_AND;
338     }
339     #ifdef DEBUG
340     printf("debug: FILTER: '%s' %s\n", node->key,
341     (node->mode == FILTER_MODE_OR ? "OR" : "AND"));
342     #endif
343    
344     insert_filter(node);
345     cur_fltr = node;
346    
347     return 0;
348     }
349    
350    
351     /*
352     * Find in the filter tree, the node with the specified key and
353     * return a pointer to it.
354     */
355     filter_t *find_filter(char *key)
356     {
357     int cmp;
358     filter_t *pos;
359    
360     FIND_TREE(filters, key, pos, cmp);
361     }
362    
363    
364     /*
365 lefcha 1.5 * Assign an action to the last declared filter.
366 lefcha 1.1 */
367 lefcha 1.4 int set_action(char *line, regmatch_t * match)
368 lefcha 1.1 {
369     if (!cur_fltr)
370 lefcha 1.4 return ERROR_CONFIG_PARSE;
371 lefcha 1.7
372 lefcha 1.5 if (!strncasecmp(line + match[1].rm_so, "delete", 6))
373 lefcha 1.4 cur_fltr->action.type = FILTER_ACTION_DELETE;
374 lefcha 1.5 else if (!strncasecmp(line + match[1].rm_so, "copy", 4)) {
375 lefcha 1.4 cur_fltr->action.type = FILTER_ACTION_COPY;
376 lefcha 1.21 if (*(line + match[2].rm_so) == '"' && *(line + match[2].rm_eo - 1) == '"')
377     strncat(cur_fltr->action.destmbox, line + match[2].rm_so + 1,
378     min(match[2].rm_eo - match[2].rm_so - 2, MBOX_NAME_LEN - 1));
379     else
380     strncat(cur_fltr->action.destmbox, line + match[2].rm_so,
381     min(match[2].rm_eo - match[2].rm_so, MBOX_NAME_LEN - 1));
382 lefcha 1.5 } else if (!strncasecmp(line + match[1].rm_so, "move", 4)) {
383 lefcha 1.4 cur_fltr->action.type = FILTER_ACTION_MOVE;
384 lefcha 1.21 if (*(line + match[3].rm_so) == '"' && *(line + match[3].rm_eo - 1) == '"')
385     strncat(cur_fltr->action.destmbox, line + match[3].rm_so + 1,
386     min(match[3].rm_eo - match[3].rm_so - 2, MBOX_NAME_LEN - 1));
387     else
388     strncat(cur_fltr->action.destmbox, line + match[3].rm_so,
389     min(match[3].rm_eo - match[3].rm_so, MBOX_NAME_LEN - 1));
390 lefcha 1.5 } else if (!strncasecmp(line + match[1].rm_so, "list", 4))
391 lefcha 1.4 cur_fltr->action.type = FILTER_ACTION_LIST;
392 lefcha 1.7
393 lefcha 1.4 if (match[4].rm_so != -1)
394     strncat(cur_fltr->action.args, line + match[4].rm_so,
395 lefcha 1.5 min(match[4].rm_eo - match[4].rm_so, ARGS_LEN - 1));
396 lefcha 1.1
397 lefcha 1.4 return 0;
398 lefcha 1.5
399 lefcha 1.1 }
400    
401    
402     /*
403     * Set new mask's variables to safe values.
404     */
405     void init_mask(mask_t * node)
406     {
407     node->next = NULL;
408     node->body[0] = 0;
409     node->type = 0;
410     }
411    
412    
413     /*
414     * Append mask node to linked list.
415     */
416     void append_mask(mask_t * node)
417     {
418     mask_t *pos;
419     mask_t **app;
420    
421     APPEND_LINKED_LIST(cur_fltr->masks, node, pos, app);
422     }
423    
424    
425     /*
426     * A new mask entry was declared, create it and set it's
427     * variables accordingly.
428     */
429     int set_mask(char *line, regmatch_t * match)
430     {
431 lefcha 1.17 int n, i, f = 0;
432 lefcha 1.1 mask_t *node;
433 lefcha 1.4 char *bp;
434 lefcha 1.5
435 lefcha 1.4 if (!cur_fltr)
436     return ERROR_CONFIG_PARSE;
437 lefcha 1.1
438     node = (mask_t *) create_node(sizeof(mask_t));
439    
440     init_mask(node);
441 lefcha 1.5
442 lefcha 1.4 bp = node->body;
443 lefcha 1.5
444 lefcha 1.4 /* If specified set mask's type. */
445     if (match[2].rm_so != -1 && cur_fltr->masks) {
446 lefcha 1.9 if (!strncasecmp(line + match[2].rm_so, "or", 2))
447 lefcha 1.1 node->type = MASK_TYPE_OR;
448     else
449     node->type = MASK_TYPE_AND;
450     }
451 lefcha 1.4 /* Add NOT if specified. */
452     if (match[3].rm_so != -1) {
453 lefcha 1.16 n = min(match[3].rm_eo - match[3].rm_so,
454 lefcha 1.4 MASK_BODY_LEN - (bp - node->body) - 1);
455 lefcha 1.16 xstrncpy(bp, line + match[3].rm_so, n);
456     string_upper(bp, n);
457     *(bp + n - 1) = ' '; /* In case it's '\t'. */
458     *(bp + n) = 0;
459     bp += n;
460 lefcha 1.1 }
461 lefcha 1.4 /* Keyword of the search key. */
462 lefcha 1.16 n = min(match[4].rm_eo - match[4].rm_so,
463 lefcha 1.4 MASK_BODY_LEN - (bp - node->body) - 3);
464 lefcha 1.16 xstrncpy(bp, line + match[4].rm_so, n);
465     string_upper(bp, n);
466     *(bp + n) = 0;
467     bp += n;
468 lefcha 1.5
469 lefcha 1.4 /* Body of the search key (string/number). */
470     for (i = 5; i <= 6; i++)
471     if (match[i].rm_so != -1) {
472     *(bp++) = ' ';
473 lefcha 1.5
474 lefcha 1.4 /* Add '"' if not supplied and search key not a number. */
475     if (match[6].rm_so == -1 &&
476     (strstr(node->body, "LARGER") ||
477 lefcha 1.13 strstr(node->body, "SMALLER") ||
478     strstr(node->body, "OLDER") ||
479     strstr(node->body, "NEWER")))
480 lefcha 1.4 f = 1;
481     else if (*(line + match[i].rm_so) != '"')
482     *(bp++) = '"';
483 lefcha 1.5
484 lefcha 1.4 *bp = 0;
485 lefcha 1.5
486 lefcha 1.16 n = min(match[i].rm_eo - match[i].rm_so,
487 lefcha 1.4 MASK_BODY_LEN - (bp - node->body) - 2);
488 lefcha 1.16 xstrncpy(bp, line + match[i].rm_so, n);
489     *(bp + n) = 0;
490     bp += n;
491 lefcha 1.5
492     if (*(line + match[i].rm_so) != '"' && !f)
493 lefcha 1.4 *(bp++) = '"';
494 lefcha 1.5 *bp = 0;
495 lefcha 1.4 }
496 lefcha 1.18 if (f && (strstr(node->body, "OLDER") || strstr(node->body, "NEWER"))) {
497 lefcha 1.13 convert_date(node);
498 lefcha 1.18 bp = node->body + strlen(node->body);
499     }
500 lefcha 1.1 append_mask(node);
501    
502 lefcha 1.4 cur_fltr->masknum++;
503     cur_fltr->masklen += (bp - node->body);
504 lefcha 1.5
505    
506 lefcha 1.1 #ifdef DEBUG
507     printf("debug: MASK: '%s'\n", node->body);
508     #endif
509    
510     return 0;
511     }
512    
513    
514     /*
515 lefcha 1.13 * Converts masks related to date filtering, because IMAP servers do not
516     * understand for example "OLDER 3", but "BEFORE 18-Oct-2001" (if
517     * hypothetically current date was 21-Oct-2001).
518     */
519     void convert_date(mask_t * node)
520     {
521     char *cp, *c;
522     char s[16];
523     time_t t;
524     struct tm *bt;
525    
526     cp = xstrdup(node->body);
527     node->body[0] = 0;
528    
529 lefcha 1.18 if (strstr(cp, "NOT"))
530     strncat(node->body, "NOT ", 4);
531    
532     if ((c = strstr(cp, "OLDER")))
533 lefcha 1.13 strncat(node->body, "BEFORE ", 7);
534 lefcha 1.18 else if ((c = strstr(cp, "NEWER")))
535 lefcha 1.13 strncat(node->body, "SINCE ", 6);
536    
537 lefcha 1.18 c += 6;
538    
539 lefcha 1.13 t = time(NULL) - (time_t) (strtoul(c, NULL, 10) * 24 * 60 * 60);
540     bt = localtime(&t);
541    
542     if (strftime(s, 15, "%d-%b-%Y", bt))
543 lefcha 1.18 strncat(node->body, s, 15);
544 lefcha 1.13
545 lefcha 1.20 xfree(cp);
546 lefcha 1.13 }
547    
548    
549     /*
550 lefcha 1.1 * A new job was declared, link filters with mailbox-groups.
551     */
552     int set_job(char *line, regmatch_t * match)
553     {
554 lefcha 1.16 int n;
555 lefcha 1.1 const char *delim = ",";
556 lefcha 1.4 char *ftok, *gtok, *fltr, *mbgrp, *f, *g;
557 lefcha 1.1 filter_t *cf;
558 lefcha 1.4 mboxgrp_t *cg;
559 lefcha 1.5
560 lefcha 1.10 if (!accounts || !filters || !cur_fltr->action.type)
561 lefcha 1.4 return ERROR_CONFIG_PARSE;
562 lefcha 1.1
563 lefcha 1.16 n = match[1].rm_eo - match[1].rm_so;
564     fltr = (char *) xmalloc(n + 1);
565 lefcha 1.5
566 lefcha 1.16 f = xstrncpy(fltr, line + match[1].rm_so, n);
567     f[n] = 0;
568 lefcha 1.1
569 lefcha 1.16 n = match[2].rm_eo - match[2].rm_so;
570     mbgrp = (char *) xmalloc(n + 1);
571 lefcha 1.5
572 lefcha 1.4 /* Go through filters. */
573     while ((ftok = strsep(&f, delim))) {
574 lefcha 1.1 cf = (filter_t *) find_filter(ftok);
575     if (!cf)
576 lefcha 1.4 return ERROR_CONFIG_PARSE;
577 lefcha 1.5
578 lefcha 1.16 g = xstrncpy(mbgrp, line + match[2].rm_so, n);
579     g[n] = 0;
580 lefcha 1.5
581 lefcha 1.4 /* Go through mailbox groups. */
582     while ((gtok = strsep(&g, delim))) {
583     cg = (mboxgrp_t *) find_mboxgrp(gtok);
584     if (!cg)
585     return ERROR_CONFIG_PARSE;
586     link_mbox_filter(cf, cg);
587 lefcha 1.1 }
588     }
589 lefcha 1.5
590 lefcha 1.20 xfree(fltr);
591     xfree(mbgrp);
592 lefcha 1.1
593 lefcha 1.4 return 0;
594 lefcha 1.1 }
595    
596    
597     /*
598     * Link a filter with a mailbox.
599     */
600 lefcha 1.4 void link_mbox_filter(filter_t * cf, mboxgrp_t * cg)
601 lefcha 1.1 {
602 lefcha 1.17 int i, j, f;
603 lefcha 1.5
604     for (i = 0; cg->mboxes[i]; i++) {
605 lefcha 1.4 for (f = j = 0; cg->mboxes[i]->filters[j]; j++)
606     if (j == MBOX_FILTERS_MAX - 1 ||
607 lefcha 1.20 !strcmp(cf->key, cg->mboxes[i]->filters[j]->key))
608 lefcha 1.4 f = 1;
609 lefcha 1.5
610 lefcha 1.4 if (f)
611     continue;
612 lefcha 1.5
613 lefcha 1.4 cg->mboxes[i]->filters[j] = cf;
614     cg->mboxes[i]->filters[j + 1] = NULL;
615 lefcha 1.1
616     }
617    
618     #ifdef DEBUG
619 lefcha 1.4 printf("debug: JOB: '%s' '%s'\n", cf->key, cg->key);
620 lefcha 1.1 #endif
621     }
622    
623    
624     /*
625 lefcha 1.3 * Free allocated memory of data structures that are not needed anymore.
626     */
627     void destroy_data(void)
628     {
629     destroy_mboxgrp(mboxgrps);
630     }
631    
632    
633     /*
634 lefcha 1.12 * Go through the mailbox-group tree, and free the allocated memory of
635     * each node.
636 lefcha 1.1 */
637     void destroy_mboxgrp(mboxgrp_t * node)
638     {
639 lefcha 1.7 if (node->left) {
640 lefcha 1.1 destroy_mboxgrp(node->left);
641 lefcha 1.7 node->left = NULL;
642     }
643     if (node->right) {
644 lefcha 1.1 destroy_mboxgrp(node->right);
645 lefcha 1.7 node->right = NULL;
646     }
647 lefcha 1.1 #ifdef DEBUG
648     printf("debug: deleting FOLDER: '%s'\n", node->key);
649     #endif
650 lefcha 1.5
651 lefcha 1.20 xfree(node);
652 lefcha 1.14 }
653    
654    
655     /*
656 lefcha 1.2 * Convert a string of specified size to upper case.
657     */
658 lefcha 1.4 void string_upper(char *str, size_t size)
659 lefcha 1.2 {
660 lefcha 1.11 unsigned int i;
661 lefcha 1.2
662 lefcha 1.8 for (i = 0; i < size; i++, str++)
663 lefcha 1.13 *str = toupper(*str);
664 lefcha 1.8 }
665    
666    
667     /*
668     * Decode the character triplet, consisting of the character '%'
669     * followed by two hexadecimal digits to its corresponding ASCII
670     * character (described in Section 2.2 of RFC 1738).
671     */
672     int string_decode(char *str)
673     {
674     char *c;
675     char hex[3];
676    
677     c = str;
678    
679     while (*c) {
680     if (*c == '%') {
681     if (!isxdigit(*(c + 1)) || !isxdigit(*(c + 2)))
682     return ERROR_CONFIG_PARSE;
683    
684 lefcha 1.15 xstrncpy(hex, ++c, 2);
685 lefcha 1.8 hex[2] = 0;
686    
687     if (!isprint(*str = (char) strtoul(hex, NULL, 16)))
688     return ERROR_CONFIG_PARSE;
689    
690     str++;
691     c += 2;
692     } else
693     *(str++) = *(c++);
694     }
695     *str = 0;
696    
697     return 0;
698 lefcha 1.19 }
699    
700    
701     /*
702     * Convert the names of personal mailboxes using the namespace specified
703     * by the mail server.
704     */
705     char *apply_namespace(char *mbox, char *prefix, char delim)
706     {
707     static char m[MBOX_NAME_LEN];
708     char *c;
709    
710     if ((!prefix[0] && !delim) || (!prefix[0] && delim == '/')
711     || !strcasecmp(mbox, "INBOX"))
712     return mbox;
713    
714     m[0] = 0;
715     strncat(m, prefix, MBOX_NAME_LEN - 1);
716     strncat(m, mbox, MBOX_NAME_LEN - strlen(m) - 1);
717    
718     c = m;
719     while ((c = strchr(c, '/')))
720     *(c++) = delim;
721    
722     #ifdef DEBUG
723     printf("debug: MAILBOX: '%s'\n", m);
724     #endif
725    
726     return m;
727 lefcha 1.1 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26