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

Annotation of /imapfilter/data.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.30.2.1 - (hide 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 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.26 static mboxgrp_t *mboxgrps = NULL; /* First node of mailbox-groups tree. */
24 lefcha 1.1
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 lefcha 1.25 node->key[0] = node->server[0] = node->username[0] = node->password[0] = 0;
36 lefcha 1.20 node->passwdattr = PASSWORD_NONE;
37 lefcha 1.1 node->port = 143;
38 lefcha 1.12 node->ssl = SSL_DISABLED;
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 lefcha 1.26 node->password = (char *)smalloc(PASSWORD_LEN);
67 lefcha 1.1
68     init_account(node);
69 lefcha 1.20
70 lefcha 1.25 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 lefcha 1.19 } else {
80 lefcha 1.25 strncat(node->username, line + match[5].rm_so,
81     min(match[5].rm_eo - match[5].rm_so, USERNAME_LEN - 1));
82 lefcha 1.19 }
83 lefcha 1.8 if (strchr(node->username, '%'))
84     if (string_decode(node->username))
85     return ERROR_CONFIG_PARSE;
86 lefcha 1.1 #ifdef DEBUG
87     printf("debug: USERNAME: '%s'\n", node->username);
88     #endif
89 lefcha 1.20
90 lefcha 1.25 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 lefcha 1.19 if (strchr(node->password, '%'))
94     if (string_decode(node->password))
95     return ERROR_CONFIG_PARSE;
96 lefcha 1.20 node->passwdattr = PASSWORD_PLAIN;
97 lefcha 1.23 } else
98     flags |= FLAG_BLANK_PASSWORD;
99 lefcha 1.1 #ifdef DEBUG
100     printf("debug: PASSWORD: '%s'\n", node->password);
101     #endif
102    
103 lefcha 1.25 strncat(node->server, line + match[6].rm_so,
104     min(match[6].rm_eo - match[6].rm_so, SERVER_LEN - 1));
105 lefcha 1.1 #ifdef DEBUG
106     printf("debug: SERVER: '%s'\n", node->server);
107     #endif
108    
109 lefcha 1.25 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 lefcha 1.16 p[n] = 0;
113 lefcha 1.11 node->port = strtoul(p, NULL, 10);
114 lefcha 1.1 #ifdef DEBUG
115     printf("debug: PORT: %d\n", node->port);
116     #endif
117     }
118 lefcha 1.25 if (match[8].rm_so != -1) {
119     if (match[7].rm_so == -1)
120 lefcha 1.12 node->port = 993;
121    
122 lefcha 1.25 if (strcasestr(line + match[8].rm_so, "ssl3"))
123 lefcha 1.12 node->ssl = SSL_SSL_V3;
124 lefcha 1.25 else if (strcasestr(line + match[8].rm_so, "tls1"))
125 lefcha 1.12 node->ssl = SSL_TLS_V1;
126     else
127     node->ssl = SSL_SSL_V2;
128     }
129 lefcha 1.1 append_account(node);
130     cur_acct = node;
131    
132     return 0;
133     }
134    
135    
136 lefcha 1.20 #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 lefcha 1.26
153 lefcha 1.20 #endif
154    
155 lefcha 1.1 /*
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 lefcha 1.4 node->key[0] = 0;
162 lefcha 1.1 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 lefcha 1.4 mboxs[0] = 0;
189    
190 lefcha 1.1 if (!accounts)
191 lefcha 1.4 return ERROR_CONFIG_PARSE;
192 lefcha 1.1
193     node = (mboxgrp_t *) create_node(sizeof(mboxgrp_t));
194    
195     init_mboxgrp(node);
196    
197 lefcha 1.4 strncat(node->key, line + match[1].rm_so,
198     min(match[1].rm_eo - match[1].rm_so, KEY_LEN - 1));
199 lefcha 1.1
200     #ifdef DEBUG
201     printf("debug: FOLDER: '%s'\n", node->key);
202     #endif
203    
204 lefcha 1.4 strncat(mboxs, line + match[2].rm_so,
205     min(match[2].rm_eo - match[2].rm_so, LINE_MAX - 1));
206 lefcha 1.1
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 lefcha 1.16 unsigned int i = 0;
222 lefcha 1.1 char *tok;
223    
224 lefcha 1.30.2.1 tok = strtok_r(mboxs, ",", &mboxs);
225     while (i < MBOXGRP_MBOXES_MAX - 1 && tok) {
226 lefcha 1.1 node->mboxes[i] = (mbox_t *) set_mbox(tok);
227     node->mboxes[++i] = NULL;
228 lefcha 1.30.2.1
229     tok = strtok_r(NULL, ",", &mboxs);
230 lefcha 1.1 }
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 lefcha 1.4 node->name[0] = 0;
254 lefcha 1.1 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 lefcha 1.21 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 lefcha 1.1
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 lefcha 1.4 node->key[0] = 0;
303 lefcha 1.1 node->mode = FILTER_MODE_AND;
304     node->action.type = 0;
305 lefcha 1.25 node->action.raccount = NULL;
306 lefcha 1.9 node->action.destmbox[0] = node->action.args[0] = 0;
307 lefcha 1.1 node->masks = NULL;
308 lefcha 1.30 node->masknum = node->masklen = 0;
309 lefcha 1.1 }
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 lefcha 1.5
332 lefcha 1.4 if (cur_fltr && !cur_fltr->action.type)
333     return ERROR_CONFIG_PARSE;
334 lefcha 1.1
335     node = (filter_t *) create_node(sizeof(filter_t));
336    
337     init_filter(node);
338    
339 lefcha 1.4 strncat(node->key, line + match[1].rm_so,
340     min(match[1].rm_eo - match[1].rm_so, KEY_LEN - 1));
341 lefcha 1.1
342 lefcha 1.4 if (match[2].rm_so != -1) {
343 lefcha 1.28 if (!strncasecmp(line + match[2].rm_so + 1, "or", 2))
344 lefcha 1.1 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 lefcha 1.5 * Assign an action to the last declared filter.
375 lefcha 1.1 */
376 lefcha 1.4 int set_action(char *line, regmatch_t * match)
377 lefcha 1.1 {
378 lefcha 1.26 char *c, *cp, *t;
379 lefcha 1.25 account_t *a;
380 lefcha 1.26
381 lefcha 1.1 if (!cur_fltr)
382 lefcha 1.4 return ERROR_CONFIG_PARSE;
383 lefcha 1.7
384 lefcha 1.28 if (!strncasecmp(line + match[1].rm_so, "delete", 6))
385 lefcha 1.4 cur_fltr->action.type = FILTER_ACTION_DELETE;
386 lefcha 1.28 else if (!strncasecmp(line + match[1].rm_so, "copy", 4)) {
387 lefcha 1.4 cur_fltr->action.type = FILTER_ACTION_COPY;
388 lefcha 1.21 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 lefcha 1.26 min(match[2].rm_eo - match[2].rm_so - 2, MBOX_NAME_LEN - 1));
391 lefcha 1.21 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 lefcha 1.28 } else if (!strncasecmp(line + match[1].rm_so, "move", 4)) {
395 lefcha 1.4 cur_fltr->action.type = FILTER_ACTION_MOVE;
396 lefcha 1.21 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 lefcha 1.26 min(match[3].rm_eo - match[3].rm_so - 2, MBOX_NAME_LEN - 1));
399 lefcha 1.21 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 lefcha 1.28 } else if (!strncasecmp(line + match[1].rm_so, "rcopy", 5)) {
403 lefcha 1.25 cur_fltr->action.type = FILTER_ACTION_RCOPY;
404     for (a = accounts; a; a = a->next)
405 lefcha 1.28 if (!strncasecmp(line + match[4].rm_so, a->key, strlen(a->key)))
406 lefcha 1.25 cur_fltr->action.raccount = a;
407     if (!cur_fltr->action.raccount)
408 lefcha 1.26 return ERROR_CONFIG_PARSE;
409 lefcha 1.25
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 lefcha 1.26 min(match[5].rm_eo - match[5].rm_so - 2, MBOX_NAME_LEN - 1));
413 lefcha 1.25 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 lefcha 1.28 } else if (!strncasecmp(line + match[1].rm_so, "rmove", 5)) {
417 lefcha 1.25 cur_fltr->action.type = FILTER_ACTION_RMOVE;
418     for (a = accounts; a; a = a->next)
419 lefcha 1.28 if (!strncasecmp(line + match[6].rm_so, a->key, strlen(a->key)))
420 lefcha 1.25 cur_fltr->action.raccount = a;
421     if (!cur_fltr->action.raccount)
422 lefcha 1.26 return ERROR_CONFIG_PARSE;
423 lefcha 1.25
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 lefcha 1.26 min(match[7].rm_eo - match[7].rm_so - 2, MBOX_NAME_LEN - 1));
427 lefcha 1.25 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 lefcha 1.28 } else if (!strncasecmp(line + match[1].rm_so, "flag", 4)) {
431     if (!strncasecmp(line + match[8].rm_so, "replace", 7))
432 lefcha 1.26 cur_fltr->action.type = FILTER_ACTION_FLAG_REPLACE;
433 lefcha 1.28 else if (!strncasecmp(line + match[8].rm_so, "add", 3))
434 lefcha 1.26 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 lefcha 1.30.2.1
441     t = strtok_r(c, ",", &c);
442     while (t) {
443 lefcha 1.26 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 lefcha 1.30.2.1
459     t = strtok_r(NULL, ",", &c);
460 lefcha 1.26 }
461     xfree(cp);
462 lefcha 1.29 } else if (!strncasecmp(line + match[1].rm_so, "list", 4)) {
463 lefcha 1.4 cur_fltr->action.type = FILTER_ACTION_LIST;
464 lefcha 1.28 }
465 lefcha 1.26 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 lefcha 1.25 while ((c = strchr(cur_fltr->action.args, ',')))
469     *c = ' ';
470     }
471     #ifdef DEBUG
472 lefcha 1.26 printf("debug: ACTION: %d '%s' '%s' %d '%s'\n", cur_fltr->action.type,
473 lefcha 1.25 cur_fltr->action.raccount->key, cur_fltr->action.destmbox,
474 lefcha 1.26 cur_fltr->action.msgflags, cur_fltr->action.args);
475 lefcha 1.25 #endif
476 lefcha 1.4 return 0;
477 lefcha 1.5
478 lefcha 1.1 }
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 lefcha 1.29 int set_mask(char *line, regmatch_t * match, int mmt)
509 lefcha 1.1 {
510 lefcha 1.29 int n;
511 lefcha 1.1 mask_t *node;
512 lefcha 1.4 char *bp;
513 lefcha 1.5
514 lefcha 1.4 if (!cur_fltr)
515     return ERROR_CONFIG_PARSE;
516 lefcha 1.1
517     node = (mask_t *) create_node(sizeof(mask_t));
518    
519     init_mask(node);
520 lefcha 1.5
521 lefcha 1.4 bp = node->body;
522 lefcha 1.5
523 lefcha 1.4 /* If specified set mask's type. */
524     if (match[2].rm_so != -1 && cur_fltr->masks) {
525 lefcha 1.28 if (!strncasecmp(line + match[2].rm_so, "or", 2)) {
526 lefcha 1.1 node->type = MASK_TYPE_OR;
527 lefcha 1.25 } else
528 lefcha 1.1 node->type = MASK_TYPE_AND;
529     }
530 lefcha 1.4 /* Add NOT if specified. */
531     if (match[3].rm_so != -1) {
532 lefcha 1.16 n = min(match[3].rm_eo - match[3].rm_so,
533 lefcha 1.4 MASK_BODY_LEN - (bp - node->body) - 1);
534 lefcha 1.16 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 lefcha 1.1 }
540 lefcha 1.4 /* Keyword of the search key. */
541 lefcha 1.16 n = min(match[4].rm_eo - match[4].rm_so,
542 lefcha 1.4 MASK_BODY_LEN - (bp - node->body) - 3);
543 lefcha 1.16 xstrncpy(bp, line + match[4].rm_so, n);
544     string_upper(bp, n);
545     *(bp + n) = 0;
546     bp += n;
547 lefcha 1.5
548 lefcha 1.29 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 lefcha 1.4 if (match[i].rm_so != -1) {
590     *(bp++) = ' ';
591 lefcha 1.5
592 lefcha 1.4 if (match[6].rm_so == -1 &&
593     (strstr(node->body, "LARGER") ||
594 lefcha 1.13 strstr(node->body, "SMALLER") ||
595     strstr(node->body, "OLDER") ||
596     strstr(node->body, "NEWER")))
597 lefcha 1.4 f = 1;
598     else if (*(line + match[i].rm_so) != '"')
599     *(bp++) = '"';
600 lefcha 1.5
601 lefcha 1.4 *bp = 0;
602 lefcha 1.5
603 lefcha 1.16 n = min(match[i].rm_eo - match[i].rm_so,
604 lefcha 1.4 MASK_BODY_LEN - (bp - node->body) - 2);
605 lefcha 1.16 xstrncpy(bp, line + match[i].rm_so, n);
606     *(bp + n) = 0;
607     bp += n;
608 lefcha 1.5
609     if (*(line + match[i].rm_so) != '"' && !f)
610 lefcha 1.4 *(bp++) = '"';
611 lefcha 1.5 *bp = 0;
612 lefcha 1.4 }
613 lefcha 1.18 if (f && (strstr(node->body, "OLDER") || strstr(node->body, "NEWER"))) {
614 lefcha 1.13 convert_date(node);
615 lefcha 1.18 bp = node->body + strlen(node->body);
616 lefcha 1.29 }*/
617    
618 lefcha 1.1 append_mask(node);
619    
620 lefcha 1.4 cur_fltr->masknum++;
621     cur_fltr->masklen += (bp - node->body);
622 lefcha 1.5
623    
624 lefcha 1.1 #ifdef DEBUG
625     printf("debug: MASK: '%s'\n", node->body);
626     #endif
627    
628     return 0;
629     }
630    
631    
632     /*
633 lefcha 1.13 * 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 lefcha 1.18 if (strstr(cp, "NOT"))
648     strncat(node->body, "NOT ", 4);
649    
650     if ((c = strstr(cp, "OLDER")))
651 lefcha 1.13 strncat(node->body, "BEFORE ", 7);
652 lefcha 1.18 else if ((c = strstr(cp, "NEWER")))
653 lefcha 1.13 strncat(node->body, "SINCE ", 6);
654    
655 lefcha 1.18 c += 6;
656    
657 lefcha 1.13 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 lefcha 1.18 strncat(node->body, s, 15);
662 lefcha 1.13
663 lefcha 1.20 xfree(cp);
664 lefcha 1.13 }
665    
666    
667     /*
668 lefcha 1.1 * A new job was declared, link filters with mailbox-groups.
669     */
670     int set_job(char *line, regmatch_t * match)
671     {
672 lefcha 1.16 int n;
673 lefcha 1.4 char *ftok, *gtok, *fltr, *mbgrp, *f, *g;
674 lefcha 1.1 filter_t *cf;
675 lefcha 1.4 mboxgrp_t *cg;
676 lefcha 1.5
677 lefcha 1.10 if (!accounts || !filters || !cur_fltr->action.type)
678 lefcha 1.4 return ERROR_CONFIG_PARSE;
679 lefcha 1.1
680 lefcha 1.16 n = match[1].rm_eo - match[1].rm_so;
681 lefcha 1.26 fltr = (char *)xmalloc(n + 1);
682 lefcha 1.5
683 lefcha 1.16 f = xstrncpy(fltr, line + match[1].rm_so, n);
684     f[n] = 0;
685 lefcha 1.1
686 lefcha 1.16 n = match[2].rm_eo - match[2].rm_so;
687 lefcha 1.26 mbgrp = (char *)xmalloc(n + 1);
688 lefcha 1.5
689 lefcha 1.4 /* Go through filters. */
690 lefcha 1.30.2.1 ftok = strtok_r(f, ",", &f);
691     while (ftok) {
692 lefcha 1.1 cf = (filter_t *) find_filter(ftok);
693     if (!cf)
694 lefcha 1.4 return ERROR_CONFIG_PARSE;
695 lefcha 1.5
696 lefcha 1.16 g = xstrncpy(mbgrp, line + match[2].rm_so, n);
697     g[n] = 0;
698 lefcha 1.5
699 lefcha 1.4 /* Go through mailbox groups. */
700 lefcha 1.30.2.1 gtok = strtok_r(g, ",", &g);
701     while (gtok) {
702 lefcha 1.4 cg = (mboxgrp_t *) find_mboxgrp(gtok);
703     if (!cg)
704     return ERROR_CONFIG_PARSE;
705     link_mbox_filter(cf, cg);
706 lefcha 1.30.2.1
707     gtok = strtok_r(NULL, ",", &g);
708 lefcha 1.1 }
709 lefcha 1.30.2.1
710     ftok = strtok_r(NULL, ",", &f);
711 lefcha 1.1 }
712 lefcha 1.5
713 lefcha 1.20 xfree(fltr);
714     xfree(mbgrp);
715 lefcha 1.1
716 lefcha 1.4 return 0;
717 lefcha 1.1 }
718    
719    
720     /*
721     * Link a filter with a mailbox.
722     */
723 lefcha 1.4 void link_mbox_filter(filter_t * cf, mboxgrp_t * cg)
724 lefcha 1.1 {
725 lefcha 1.17 int i, j, f;
726 lefcha 1.5
727     for (i = 0; cg->mboxes[i]; i++) {
728 lefcha 1.4 for (f = j = 0; cg->mboxes[i]->filters[j]; j++)
729     if (j == MBOX_FILTERS_MAX - 1 ||
730 lefcha 1.20 !strcmp(cf->key, cg->mboxes[i]->filters[j]->key))
731 lefcha 1.4 f = 1;
732 lefcha 1.5
733 lefcha 1.4 if (f)
734     continue;
735 lefcha 1.5
736 lefcha 1.4 cg->mboxes[i]->filters[j] = cf;
737     cg->mboxes[i]->filters[j + 1] = NULL;
738 lefcha 1.1
739     }
740    
741     #ifdef DEBUG
742 lefcha 1.4 printf("debug: JOB: '%s' '%s'\n", cf->key, cg->key);
743 lefcha 1.1 #endif
744     }
745    
746    
747     /*
748 lefcha 1.3 * 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 lefcha 1.12 * Go through the mailbox-group tree, and free the allocated memory of
758     * each node.
759 lefcha 1.1 */
760     void destroy_mboxgrp(mboxgrp_t * node)
761     {
762 lefcha 1.7 if (node->left) {
763 lefcha 1.1 destroy_mboxgrp(node->left);
764 lefcha 1.7 node->left = NULL;
765     }
766     if (node->right) {
767 lefcha 1.1 destroy_mboxgrp(node->right);
768 lefcha 1.7 node->right = NULL;
769     }
770 lefcha 1.1 #ifdef DEBUG
771     printf("debug: deleting FOLDER: '%s'\n", node->key);
772     #endif
773 lefcha 1.5
774 lefcha 1.20 xfree(node);
775 lefcha 1.14 }
776    
777    
778     /*
779 lefcha 1.2 * Convert a string of specified size to upper case.
780     */
781 lefcha 1.4 void string_upper(char *str, size_t size)
782 lefcha 1.2 {
783 lefcha 1.11 unsigned int i;
784 lefcha 1.2
785 lefcha 1.8 for (i = 0; i < size; i++, str++)
786 lefcha 1.13 *str = toupper(*str);
787 lefcha 1.8 }
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 lefcha 1.30.2.1 if (!isxdigit((unsigned char)(*(c + 1))) ||
805     !isxdigit((unsigned char)(*(c + 2))))
806 lefcha 1.8 return ERROR_CONFIG_PARSE;
807    
808 lefcha 1.15 xstrncpy(hex, ++c, 2);
809 lefcha 1.8 hex[2] = 0;
810    
811 lefcha 1.30.2.1 if (!isprint((unsigned char)(*str = (char)strtoul(hex, NULL, 16))))
812 lefcha 1.8 return ERROR_CONFIG_PARSE;
813    
814     str++;
815     c += 2;
816     } else
817     *(str++) = *(c++);
818     }
819     *str = 0;
820    
821     return 0;
822 lefcha 1.19 }
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 lefcha 1.1 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26