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

Annotation of /imapfilter/data.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.43 - (hide annotations)
Thu Jul 31 15:47:37 2003 UTC (20 years, 8 months ago) by lefcha
Branch: MAIN
CVS Tags: HEAD
Changes since 1.42: +0 -0 lines
File MIME type: text/plain
FILE REMOVED
Program and header files, data.c and data.h, broken to new smaller files.

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 lefcha 1.42 if (strcasestr(line + m[8].rm_so, "SSL2"))
127 lefcha 1.41 node->ssl = SSL_SSL_V2;
128 lefcha 1.42 else if (strcasestr(line + m[8].rm_so, "SSL3"))
129 lefcha 1.36 node->ssl = SSL_SSL_V3;
130 lefcha 1.41 else
131 lefcha 1.36 node->ssl = SSL_TLS_V1;
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.39 char s[MBOX_NAME_LEN];
291     mbox_t *node, *m;
292    
293     *s = '\0';
294    
295     if (*name == '"' && *(name + strlen(name) - 1) == '"')
296     strncat(s, name + 1, min(strlen(name) - 2, MBOX_NAME_LEN - 1));
297     else
298     strncat(s, name, min(strlen(name), MBOX_NAME_LEN - 1));
299    
300     for (m = cur_acct->mboxes; m != NULL; m = m->next)
301     if (!strcmp(m->name, s))
302 lefcha 1.40 return m;
303 lefcha 1.1
304 lefcha 1.36 node = (mbox_t *) create_node(sizeof(mbox_t));
305 lefcha 1.1
306 lefcha 1.36 init_mbox(node);
307 lefcha 1.1
308 lefcha 1.39 strncat(node->name, s, MBOX_NAME_LEN - 1);
309 lefcha 1.1
310     #ifdef DEBUG
311 lefcha 1.36 fprintf(stderr, "debug: MBOX: '%s'\n", node->name);
312 lefcha 1.1 #endif
313    
314 lefcha 1.36 append_mbox(node);
315 lefcha 1.1
316 lefcha 1.36 return node;
317 lefcha 1.1 }
318    
319    
320     /*
321     * Set new filter's variables to safe values.
322     */
323 lefcha 1.36 void
324     init_filter(filter_t * node)
325 lefcha 1.1 {
326 lefcha 1.36 node->left = node->right = NULL;
327     node->key[0] = '\0';
328     node->mode = FILTER_MODE_AND;
329 lefcha 1.38 node->action.type = node->action.msgflags = 0;
330 lefcha 1.36 node->action.raccount = NULL;
331     node->action.destmbox[0] = node->action.args[0] = '\0';
332     node->masks = NULL;
333     node->masknum = node->masklen = 0;
334 lefcha 1.1 }
335    
336    
337     /*
338     * Insert filter node to tree.
339     */
340 lefcha 1.36 void
341     insert_filter(filter_t * node)
342 lefcha 1.1 {
343 lefcha 1.36 int cmp;
344     filter_t *pos;
345     filter_t **ins;
346 lefcha 1.1
347 lefcha 1.36 INSERT_TREE(filters, node, pos, ins, cmp);
348 lefcha 1.1 }
349    
350    
351     /*
352     * A filter entry was declared, create it and set it's variables accordingly.
353     */
354 lefcha 1.36 int
355     set_filter(char *line, regmatch_t * m)
356 lefcha 1.1 {
357 lefcha 1.36 filter_t *node;
358 lefcha 1.5
359 lefcha 1.36 if (cur_fltr != NULL && cur_fltr->action.type == 0)
360     return ERROR_CONFIG_PARSE;
361 lefcha 1.1
362 lefcha 1.36 node = (filter_t *) create_node(sizeof(filter_t));
363 lefcha 1.1
364 lefcha 1.36 init_filter(node);
365 lefcha 1.1
366 lefcha 1.36 strncat(node->key, line + m[1].rm_so,
367     min(m[1].rm_eo - m[1].rm_so, KEY_LEN - 1));
368 lefcha 1.1
369 lefcha 1.36 if (m[2].rm_so != -1) {
370     if (!strncasecmp(line + m[2].rm_so + 1, "or", 2))
371     node->mode = FILTER_MODE_OR;
372     else
373     node->mode = FILTER_MODE_AND;
374     }
375 lefcha 1.1 #ifdef DEBUG
376 lefcha 1.36 fprintf(stderr, "debug: FILTER: '%s' %s\n", node->key,
377     (node->mode == FILTER_MODE_OR ? "OR" : "AND"));
378 lefcha 1.1 #endif
379    
380 lefcha 1.36 insert_filter(node);
381     cur_fltr = node;
382 lefcha 1.1
383 lefcha 1.36 return 0;
384 lefcha 1.1 }
385    
386    
387     /*
388     * Find in the filter tree, the node with the specified key and
389     * return a pointer to it.
390     */
391 lefcha 1.36 filter_t *
392     find_filter(char *key)
393 lefcha 1.1 {
394 lefcha 1.36 int cmp;
395     filter_t *pos;
396 lefcha 1.1
397 lefcha 1.36 FIND_TREE(filters, key, pos, cmp);
398 lefcha 1.1 }
399    
400    
401     /*
402 lefcha 1.5 * Assign an action to the last declared filter.
403 lefcha 1.1 */
404 lefcha 1.36 int
405     set_action(char *line, regmatch_t * m)
406 lefcha 1.1 {
407 lefcha 1.36 char *c, *cp, *t;
408     account_t *a;
409 lefcha 1.26
410 lefcha 1.36 if (cur_fltr == NULL)
411 lefcha 1.26 return ERROR_CONFIG_PARSE;
412 lefcha 1.31
413 lefcha 1.36 if (!strncasecmp(line + m[1].rm_so, "delete", 6))
414     cur_fltr->action.type = FILTER_ACTION_DELETE;
415     else if (!strncasecmp(line + m[1].rm_so, "copy", 4)) {
416     cur_fltr->action.type = FILTER_ACTION_COPY;
417     if (*(line + m[2].rm_so) == '"' &&
418     *(line + m[2].rm_eo - 1) == '"')
419     strncat(cur_fltr->action.destmbox,
420     line + m[2].rm_so + 1,
421     min(m[2].rm_eo - m[2].rm_so - 2,
422     MBOX_NAME_LEN - 1));
423     else
424     strncat(cur_fltr->action.destmbox, line + m[2].rm_so,
425     min(m[2].rm_eo - m[2].rm_so, MBOX_NAME_LEN - 1));
426     } else if (!strncasecmp(line + m[1].rm_so, "move", 4)) {
427     cur_fltr->action.type = FILTER_ACTION_MOVE;
428     if (*(line + m[3].rm_so) == '"' &&
429     *(line + m[3].rm_eo - 1) == '"')
430     strncat(cur_fltr->action.destmbox,
431     line + m[3].rm_so + 1,
432     min(m[3].rm_eo - m[3].rm_so - 2,
433     MBOX_NAME_LEN - 1));
434     else
435     strncat(cur_fltr->action.destmbox, line + m[3].rm_so,
436     min(m[3].rm_eo - m[3].rm_so, MBOX_NAME_LEN - 1));
437     } else if (!strncasecmp(line + m[1].rm_so, "rcopy", 5)) {
438     cur_fltr->action.type = FILTER_ACTION_RCOPY;
439     for (a = accounts; a; a = a->next)
440     if (!strncasecmp(line + m[4].rm_so, a->key,
441     strlen(a->key)))
442     cur_fltr->action.raccount = a;
443     if (!cur_fltr->action.raccount)
444     return ERROR_CONFIG_PARSE;
445    
446     if (*(line + m[5].rm_so) == '"' &&
447     *(line + m[5].rm_eo - 1) == '"')
448     strncat(cur_fltr->action.destmbox,
449     line + m[5].rm_so + 1,
450     min(m[5].rm_eo - m[5].rm_so - 2,
451     MBOX_NAME_LEN - 1));
452     else
453     strncat(cur_fltr->action.destmbox, line + m[5].rm_so,
454     min(m[5].rm_eo - m[5].rm_so, MBOX_NAME_LEN - 1));
455     } else if (!strncasecmp(line + m[1].rm_so, "rmove", 5)) {
456     cur_fltr->action.type = FILTER_ACTION_RMOVE;
457     for (a = accounts; a; a = a->next)
458     if (!strncasecmp(line + m[6].rm_so, a->key,
459     strlen(a->key)))
460     cur_fltr->action.raccount = a;
461     if (!cur_fltr->action.raccount)
462     return ERROR_CONFIG_PARSE;
463    
464     if (*(line + m[7].rm_so) == '"' &&
465     *(line + m[7].rm_eo - 1) == '"')
466     strncat(cur_fltr->action.destmbox,
467     line + m[7].rm_so + 1,
468     min(m[7].rm_eo - m[7].rm_so - 2,
469     MBOX_NAME_LEN - 1));
470     else
471     strncat(cur_fltr->action.destmbox, line + m[7].rm_so,
472     min(m[7].rm_eo - m[7].rm_so, MBOX_NAME_LEN - 1));
473     } else if (!strncasecmp(line + m[1].rm_so, "flag", 4)) {
474     if (!strncasecmp(line + m[8].rm_so, "replace", 7))
475     cur_fltr->action.type = FILTER_ACTION_FLAG_REPLACE;
476     else if (!strncasecmp(line + m[8].rm_so, "add", 3))
477     cur_fltr->action.type = FILTER_ACTION_FLAG_ADD;
478     else
479     cur_fltr->action.type = FILTER_ACTION_FLAG_REMOVE;
480    
481     c = cp = (char *)malloc(m[9].rm_eo - m[9].rm_so + 1);
482     xstrncpy(c, line + m[9].rm_so, m[9].rm_eo - m[9].rm_so);
483    
484     t = strtok_r(c, ",", &c);
485     while (t) {
486     if (!strcasecmp(t, "none")) {
487     if (m[9].rm_eo - m[9].rm_so != strlen("none"))
488     return ERROR_CONFIG_PARSE;
489     } else if (!strcasecmp(t, "seen"))
490     cur_fltr->action.msgflags |= MESSAGE_FLAG_SEEN;
491     else if (!strcasecmp(t, "answered"))
492     cur_fltr->action.msgflags |=
493     MESSAGE_FLAG_ANSWERED;
494     else if (!strcasecmp(t, "flagged"))
495     cur_fltr->action.msgflags |=
496     MESSAGE_FLAG_FLAGGED;
497     else if (!strcasecmp(t, "deleted"))
498     cur_fltr->action.msgflags |=
499     MESSAGE_FLAG_DELETED;
500     else if (!strcasecmp(t, "draft"))
501     cur_fltr->action.msgflags |= MESSAGE_FLAG_DRAFT;
502     else
503     return ERROR_CONFIG_PARSE;
504    
505     t = strtok_r(NULL, ",", &c);
506     }
507     xfree(cp);
508     } else if (!strncasecmp(line + m[1].rm_so, "list", 4)) {
509     cur_fltr->action.type = FILTER_ACTION_LIST;
510     }
511     if (m[10].rm_so != -1) {
512     strncat(cur_fltr->action.args, line + m[10].rm_so,
513     min(m[10].rm_eo - m[10].rm_so, ARGS_LEN - 2));
514     while ((c = strchr(cur_fltr->action.args, ',')))
515     *c = ' ';
516     }
517     #ifdef DEBUG
518     fprintf(stderr, "debug: ACTION: %d '%s' '%s' %d '%s'\n",
519     cur_fltr->action.type,
520     (cur_fltr->action.raccount ? cur_fltr->action.raccount->key : ""),
521     cur_fltr->action.destmbox,
522     cur_fltr->action.msgflags,
523     cur_fltr->action.args);
524 lefcha 1.25 #endif
525 lefcha 1.36 return 0;
526 lefcha 1.1 }
527    
528    
529     /*
530     * Set new mask's variables to safe values.
531     */
532 lefcha 1.36 void
533     init_mask(mask_t * node)
534 lefcha 1.1 {
535 lefcha 1.36 node->next = NULL;
536     node->body[0] = '\0';
537     node->type = 0;
538 lefcha 1.1 }
539    
540    
541     /*
542     * Append mask node to linked list.
543     */
544 lefcha 1.36 void
545     append_mask(mask_t * node)
546 lefcha 1.1 {
547 lefcha 1.36 mask_t *pos;
548     mask_t **app;
549 lefcha 1.1
550 lefcha 1.36 APPEND_LINKED_LIST(cur_fltr->masks, node, pos, app);
551 lefcha 1.1 }
552    
553    
554     /*
555     * A new mask entry was declared, create it and set it's
556     * variables accordingly.
557     */
558 lefcha 1.36 int
559     set_mask(char *line, regmatch_t * m, int mmt)
560 lefcha 1.1 {
561 lefcha 1.36 int n;
562     mask_t *node;
563     char *bp;
564 lefcha 1.5
565 lefcha 1.36 if (cur_fltr == NULL)
566     return ERROR_CONFIG_PARSE;
567 lefcha 1.1
568 lefcha 1.36 node = (mask_t *) create_node(sizeof(mask_t));
569 lefcha 1.1
570 lefcha 1.36 init_mask(node);
571 lefcha 1.5
572 lefcha 1.36 bp = node->body;
573 lefcha 1.5
574 lefcha 1.36 /* If specified set mask's type. */
575     if (m[2].rm_so != -1 && cur_fltr->masks) {
576     if (!strncasecmp(line + m[2].rm_so, "or", 2)) {
577     node->type = MASK_TYPE_OR;
578     } else
579     node->type = MASK_TYPE_AND;
580     }
581     /* Add NOT if specified. */
582     if (m[3].rm_so != -1) {
583     n = min(m[3].rm_eo - m[3].rm_so,
584     MASK_BODY_LEN - (bp - node->body) - 1);
585     xstrncpy(bp, line + m[3].rm_so, n);
586     string_upper(bp, n);
587     *(bp + n - 1) = ' '; /* In case it's '\t'. */
588     *(bp + n) = '\0';
589     bp += n;
590     }
591     /* Keyword of the search key. */
592     n = min(m[4].rm_eo - m[4].rm_so,
593     MASK_BODY_LEN - (bp - node->body) - 3);
594     xstrncpy(bp, line + m[4].rm_so, n);
595 lefcha 1.16 string_upper(bp, n);
596 lefcha 1.36 *(bp + n) = '\0';
597 lefcha 1.29 bp += n;
598    
599 lefcha 1.36 if (mmt != MASK_MATCH_1) {
600     *(bp++) = ' ';
601    
602     if (mmt != MASK_MATCH_4 && *(line + m[5].rm_so) != '"')
603     *(bp++) = '"';
604     *bp = '\0';
605 lefcha 1.29
606 lefcha 1.36 n = min(m[5].rm_eo - m[5].rm_so,
607 lefcha 1.29 MASK_BODY_LEN - (bp - node->body) - 2);
608 lefcha 1.36 xstrncpy(bp, line + m[5].rm_so, n);
609     *(bp + n) = '\0';
610     bp += n;
611    
612     if (mmt != MASK_MATCH_4 && *(line + m[5].rm_so) != '"')
613     *(bp++) = '"';
614     *bp = '\0';
615    
616     if (mmt == MASK_MATCH_3) {
617     *(bp++) = ' ';
618    
619     if (*(line + m[6].rm_so) != '"')
620     *(bp++) = '"';
621     *bp = '\0';
622    
623     n = min(m[6].rm_eo - m[6].rm_so,
624     MASK_BODY_LEN - (bp - node->body) - 2);
625     xstrncpy(bp, line + m[6].rm_so, n);
626     *(bp + n) = '\0';
627     bp += n;
628    
629     if (*(line + m[6].rm_so) != '"')
630     *(bp++) = '"';
631     *bp = '\0';
632     }
633     if (mmt == MASK_MATCH_4 && (strstr(node->body, "OLDER") ||
634     strstr(node->body, "NEWER"))) {
635     convert_date(node);
636     bp = node->body + strlen(node->body);
637     }
638 lefcha 1.29 }
639 lefcha 1.36 append_mask(node);
640 lefcha 1.1
641 lefcha 1.36 cur_fltr->masknum++;
642     cur_fltr->masklen += (bp - node->body);
643 lefcha 1.5
644    
645 lefcha 1.1 #ifdef DEBUG
646 lefcha 1.36 fprintf(stderr, "debug: MASK: '%s'\n", node->body);
647 lefcha 1.1 #endif
648    
649 lefcha 1.36 return 0;
650 lefcha 1.1 }
651    
652    
653     /*
654 lefcha 1.13 * Converts masks related to date filtering, because IMAP servers do not
655     * understand for example "OLDER 3", but "BEFORE 18-Oct-2001" (if
656     * hypothetically current date was 21-Oct-2001).
657     */
658 lefcha 1.36 void
659     convert_date(mask_t * node)
660 lefcha 1.13 {
661 lefcha 1.36 char *cp, *c;
662     char s[16];
663     time_t te;
664     struct tm *tl;
665 lefcha 1.13
666 lefcha 1.36 cp = xstrdup(node->body);
667     node->body[0] = '\0';
668 lefcha 1.13
669 lefcha 1.36 if (strstr(cp, "NOT"))
670     strncat(node->body, "NOT ", 4);
671 lefcha 1.18
672 lefcha 1.36 if ((c = strstr(cp, "OLDER")))
673     strncat(node->body, "BEFORE ", 7);
674     else if ((c = strstr(cp, "NEWER")))
675     strncat(node->body, "SINCE ", 6);
676 lefcha 1.13
677 lefcha 1.36 c += 6;
678 lefcha 1.18
679 lefcha 1.36 te = time(NULL) - (time_t) (strtoul(c, NULL, 10) * 24 * 60 * 60);
680     tl = localtime(&te);
681 lefcha 1.13
682 lefcha 1.36 if (strftime(s, 15, "%d-%b-%Y", tl))
683     strncat(node->body, s, 15);
684 lefcha 1.13
685 lefcha 1.36 xfree(cp);
686 lefcha 1.13 }
687    
688    
689     /*
690 lefcha 1.1 * A new job was declared, link filters with mailbox-groups.
691     */
692 lefcha 1.36 int
693     set_job(char *line, regmatch_t * match)
694 lefcha 1.1 {
695 lefcha 1.36 int n;
696     char *ftok, *gtok, *fltr, *mbgrp, *f, *g;
697     filter_t *cf;
698     mboxgrp_t *cg;
699    
700     if (accounts == NULL || filters == NULL || cur_fltr->action.type == 0)
701 lefcha 1.4 return ERROR_CONFIG_PARSE;
702 lefcha 1.31
703 lefcha 1.36 n = match[1].rm_eo - match[1].rm_so;
704     fltr = (char *)xmalloc(n + 1);
705    
706     f = xstrncpy(fltr, line + match[1].rm_so, n);
707     f[n] = '\0';
708    
709     n = match[2].rm_eo - match[2].rm_so;
710     mbgrp = (char *)xmalloc(n + 1);
711    
712     /* Go through filters. */
713     ftok = strtok_r(f, ",", &f);
714     while (ftok != NULL) {
715     cf = (filter_t *) find_filter(ftok);
716     if (cf == NULL)
717     return ERROR_CONFIG_PARSE;
718    
719     g = xstrncpy(mbgrp, line + match[2].rm_so, n);
720     g[n] = '\0';
721    
722     /* Go through mailbox groups. */
723     gtok = strtok_r(g, ",", &g);
724     while (gtok != NULL) {
725     cg = (mboxgrp_t *) find_mboxgrp(gtok);
726     if (cg == NULL)
727     return ERROR_CONFIG_PARSE;
728     link_mbox_filter(cf, cg);
729    
730     gtok = strtok_r(NULL, ",", &g);
731     }
732    
733     ftok = strtok_r(NULL, ",", &f);
734 lefcha 1.1 }
735 lefcha 1.31
736 lefcha 1.36 xfree(fltr);
737     xfree(mbgrp);
738 lefcha 1.1
739 lefcha 1.36 return 0;
740 lefcha 1.1 }
741    
742    
743     /*
744     * Link a filter with a mailbox.
745     */
746 lefcha 1.36 void
747     link_mbox_filter(filter_t * cf, mboxgrp_t * cg)
748 lefcha 1.1 {
749 lefcha 1.36 int i, j, f;
750 lefcha 1.5
751 lefcha 1.36 for (i = 0; cg->mboxes[i] != NULL; i++) {
752     for (f = j = 0; cg->mboxes[i]->filters[j] != NULL; j++)
753     if (j == MBOX_FILTERS_MAX - 1 ||
754     !strcmp(cf->key, cg->mboxes[i]->filters[j]->key))
755     f = 1;
756 lefcha 1.5
757 lefcha 1.36 if (f)
758     continue;
759 lefcha 1.5
760 lefcha 1.36 cg->mboxes[i]->filters[j] = cf;
761     cg->mboxes[i]->filters[j + 1] = NULL;
762 lefcha 1.1
763 lefcha 1.36 }
764 lefcha 1.1
765     #ifdef DEBUG
766 lefcha 1.36 fprintf(stderr, "debug: JOB: '%s' '%s'\n", cf->key, cg->key);
767 lefcha 1.1 #endif
768     }
769    
770    
771     /*
772 lefcha 1.40 * Free allocated memory of all data structures.
773     */
774     void
775     destroy_all(void)
776     {
777     destroy_accounts(accounts);
778     accounts = NULL;
779     destroy_filters(filters);
780     filters = NULL;
781     destroy_mboxgrps(mboxgrps);
782     mboxgrps = NULL;
783     }
784    
785    
786     /*
787 lefcha 1.3 * Free allocated memory of data structures that are not needed anymore.
788     */
789 lefcha 1.36 void
790 lefcha 1.40 destroy_unneeded(void)
791 lefcha 1.3 {
792 lefcha 1.38 destroy_mboxgrps(mboxgrps);
793 lefcha 1.40 mboxgrps = NULL;
794 lefcha 1.3 }
795    
796    
797     /*
798 lefcha 1.12 * Go through the mailbox-group tree, and free the allocated memory of
799     * each node.
800 lefcha 1.1 */
801 lefcha 1.36 void
802 lefcha 1.38 destroy_mboxgrps(mboxgrp_t * node)
803 lefcha 1.1 {
804 lefcha 1.36 if (node == NULL)
805     return;
806 lefcha 1.33
807 lefcha 1.36 if (node->left != NULL) {
808 lefcha 1.38 destroy_mboxgrps(node->left);
809 lefcha 1.36 node->left = NULL;
810     }
811     if (node->right != NULL) {
812 lefcha 1.38 destroy_mboxgrps(node->right);
813 lefcha 1.36 node->right = NULL;
814     }
815 lefcha 1.1 #ifdef DEBUG
816 lefcha 1.36 fprintf(stderr, "debug: deleting FOLDER: '%s'\n", node->key);
817 lefcha 1.1 #endif
818 lefcha 1.5
819 lefcha 1.36 xfree(node);
820 lefcha 1.38 }
821    
822    
823     /*
824     * Go through the mailbox linked list of the account and free the allocated
825     * memory of each node.
826     */
827     void
828     destroy_mboxs(mbox_t * node)
829     {
830     mbox_t *p, *t;
831    
832     for (p = node; p != NULL; p = t) {
833     t = p->next;
834     #ifdef DEBUG
835     fprintf(stderr, "debug: deleting MBOX: '%s'\n", p->name);
836     #endif
837     xfree(p);
838     }
839     }
840    
841    
842     /*
843     * Go through the accounts' linked list and free the allocated memory of
844     * each node.
845     */
846     void
847     destroy_accounts(account_t * node)
848     {
849     account_t *p, *t;
850    
851     for (p = node; p != NULL; p = t) {
852     t = p->next;
853     #ifdef DEBUG
854     fprintf(stderr, "debug: deleting ACCOUNT: '%s'\n", p->key);
855     #endif
856     destroy_mboxs(p->mboxes);
857     sfree(p->password);
858     xfree(p);
859     }
860     }
861    
862    
863     /*
864     * Go through the filters' tree and free the allocated memory of each node.
865     */
866     void
867     destroy_filters(filter_t * node)
868     {
869     if (node == NULL)
870     return;
871    
872     if (node->left != NULL) {
873     destroy_filters(node->left);
874     node->left = NULL;
875     }
876     if (node->right != NULL) {
877     destroy_filters(node->right);
878     node->right = NULL;
879     }
880     #ifdef DEBUG
881     fprintf(stderr, "debug: deleting FILTER: '%s'\n", node->key);
882     #endif
883     destroy_masks(node->masks);
884     xfree(node);
885     }
886    
887    
888     /*
889     * Go through the masks' linked list and free the allocated memory of each
890     * node.
891     */
892     void
893     destroy_masks(mask_t * node)
894     {
895     mask_t *p, *t;
896    
897     for (p = node; p != NULL; p = t) {
898     t = p->next;
899     #ifdef DEBUG
900     fprintf(stderr, "debug: deleting MASK: '%s'\n", p->body);
901     #endif
902     xfree(p);
903     }
904 lefcha 1.14 }
905    
906    
907     /*
908 lefcha 1.2 * Convert a string of specified size to upper case.
909     */
910 lefcha 1.36 void
911     string_upper(char *str, size_t size)
912 lefcha 1.2 {
913 lefcha 1.36 unsigned int i;
914 lefcha 1.2
915 lefcha 1.36 for (i = 0; i < size; i++, str++)
916     *str = toupper(*str);
917 lefcha 1.8 }
918    
919    
920     /*
921     * Decode the character triplet, consisting of the character '%'
922     * followed by two hexadecimal digits to its corresponding ASCII
923     * character (described in Section 2.2 of RFC 1738).
924     */
925 lefcha 1.36 int
926     string_decode(char *str)
927 lefcha 1.8 {
928 lefcha 1.36 char *c;
929     char hex[3];
930 lefcha 1.8
931 lefcha 1.36 c = str;
932 lefcha 1.8
933 lefcha 1.36 while (*c != '\0') {
934     if (*c == '%') {
935     if (!isxdigit((unsigned char)(*(c + 1))) ||
936     !isxdigit((unsigned char)(*(c + 2))))
937     return ERROR_CONFIG_PARSE;
938    
939     xstrncpy(hex, ++c, 2);
940     hex[2] = '\0';
941    
942     if (!isprint((unsigned char)(*str = (char)strtoul(hex,
943     NULL, 16))))
944     return ERROR_CONFIG_PARSE;
945    
946     str++;
947     c += 2;
948     } else
949     *(str++) = *(c++);
950     }
951     *str = '\0';
952 lefcha 1.8
953 lefcha 1.36 return 0;
954 lefcha 1.19 }
955    
956    
957     /*
958     * Convert the names of personal mailboxes using the namespace specified
959     * by the mail server.
960     */
961 lefcha 1.36 char *
962     apply_namespace(char *mbox, char *prefix, char delim)
963 lefcha 1.19 {
964 lefcha 1.36 static char m[MBOX_NAME_LEN];
965     char *c;
966 lefcha 1.19
967 lefcha 1.36 if ((prefix[0] == '\0' && delim == '\0') ||
968     (prefix[0] == '\0' && delim == '/') ||
969     !strcasecmp(mbox, "INBOX"))
970     return mbox;
971 lefcha 1.19
972 lefcha 1.36 m[0] = '\0';
973     strncat(m, prefix, MBOX_NAME_LEN - 1);
974     strncat(m, mbox, MBOX_NAME_LEN - strlen(m) - 1);
975 lefcha 1.19
976 lefcha 1.36 c = m;
977     while ((c = strchr(c, '/')))
978     *(c++) = delim;
979 lefcha 1.19
980     #ifdef DEBUG
981 lefcha 1.36 fprintf(stderr, "debug: MAILBOX: '%s'\n", m);
982 lefcha 1.19 #endif
983    
984 lefcha 1.36 return m;
985 lefcha 1.1 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26