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

Annotation of /imapfilter/data.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.20 - (hide annotations)
Mon Jan 14 18:12:38 2002 UTC (22 years, 2 months ago) by lefcha
Branch: MAIN
Changes since 1.19: +28 -10 lines
File MIME type: text/plain
Added encrypted passwords support.

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