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

Annotation of /imapfilter/data.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.36 - (hide annotations)
Sat Feb 22 16:06:41 2003 UTC (21 years, 2 months ago) by lefcha
Branch: MAIN
Changes since 1.35: +542 -485 lines
File MIME type: text/plain
Coding style to KNF and some code cleanup.

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

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26