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

Annotation of /imapfilter/data.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.30 - (hide annotations)
Thu Jul 25 21:27:48 2002 UTC (21 years, 8 months ago) by lefcha
Branch: MAIN
CVS Tags: release-0_8
Branch point for: release-0_8-patches
Changes since 1.29: +1 -3 lines
File MIME type: text/plain
Removed unused variable.

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

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26