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

Contents of /imapfilter/data.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.5 - (show annotations)
Mon Oct 1 19:19:05 2001 UTC (22 years, 6 months ago) by lefcha
Branch: MAIN
Changes since 1.4: +48 -55 lines
File MIME type: text/plain
Better matching and setting of action.

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 #include <ctype.h>
10
11 #include "config.h"
12 #include "imapfilter.h"
13 #include "data.h"
14
15
16 account_t *accounts = NULL; /* First node of accounts linked list. */
17 filter_t *filters = NULL; /* First node of filters tree. */
18
19 static mboxgrp_t *mboxgrps = NULL; /* First node of mailbox-groups
20 tree. */
21
22 static account_t *cur_acct = NULL; /* Current account. */
23 static filter_t *cur_fltr = NULL; /* Current filter. */
24
25
26 /*
27 * Allocate memory of the appropriate size for a new node.
28 */
29 void *create_node(size_t size)
30 {
31 void *ptr;
32
33 ptr = (void *) malloc(size);
34
35 if (!ptr)
36 fatal(ERROR_MEMORY_ALLOCATION,
37 "imapfilter: allocating memory; %s\n", strerror(errno));
38
39 return ptr;
40 }
41
42
43 /*
44 * Set new account's variables to safe values.
45 */
46 void init_account(account_t * node)
47 {
48 node->next = NULL;
49 node->server[0] = node->username[0] = node->password[0] = 0;
50 node->port = 143;
51 node->mboxes = NULL;
52 }
53
54
55 /*
56 * Append account node to linked list.
57 */
58 void append_account(account_t * node)
59 {
60 account_t *pos;
61 account_t **app;
62
63 APPEND_LINKED_LIST(accounts, node, pos, app);
64 }
65
66
67 /*
68 * A new account entry was declared. Create it and set it's variables
69 * accordingly.
70 */
71 int set_account(char *line, regmatch_t * match)
72 {
73 int s;
74 char p[6];
75 account_t *node;
76
77 node = (account_t *) create_node(sizeof(account_t));
78
79 init_account(node);
80
81 strncat(node->username, line + match[1].rm_so,
82 min(match[1].rm_eo - match[1].rm_so, USERNAME_LEN - 1));
83 #ifdef DEBUG
84 printf("debug: USERNAME: '%s'\n", node->username);
85 #endif
86
87 strncat(node->password, line + match[2].rm_so,
88 min(match[2].rm_eo - match[2].rm_so, PASSWORD_LEN - 1));
89 #ifdef DEBUG
90 printf("debug: PASSWORD: '%s'\n", node->password);
91 #endif
92
93 strncat(node->server, line + match[3].rm_so,
94 min(match[3].rm_eo - match[3].rm_so, SERVER_LEN - 1));
95 #ifdef DEBUG
96 printf("debug: SERVER: '%s'\n", node->server);
97 #endif
98
99 if (match[4].rm_so != -1) {
100 s = min(match[4].rm_eo - match[4].rm_so - 1, 5);
101 strncpy(p, line + match[4].rm_so + 1, s);
102 p[s] = 0;
103 node->port = strtoul(p, NULL, 0);
104 #ifdef DEBUG
105 printf("debug: PORT: %d\n", node->port);
106 #endif
107 }
108 append_account(node);
109 cur_acct = node;
110
111 return 0;
112 }
113
114
115 /*
116 * Set new mailbox-group's variables to safe values.
117 */
118 void init_mboxgrp(mboxgrp_t * node)
119 {
120 node->left = node->right = NULL;
121 node->key[0] = 0;
122 node->mboxes[0] = NULL;
123 }
124
125
126 /*
127 * Insert mailbox-group node in tree.
128 */
129 void insert_mboxgrp(mboxgrp_t * node)
130 {
131 int cmp;
132 mboxgrp_t *pos;
133 mboxgrp_t **ins;
134
135 INSERT_TREE(mboxgrps, node, pos, ins, cmp);
136 }
137
138
139 /*
140 * A new mailbox-group entry was declared. Create it and set it's variables
141 * accordingly.
142 */
143 int set_mboxgrp(char *line, regmatch_t * match)
144 {
145 mboxgrp_t *node;
146 char mboxs[LINE_MAX];
147
148 mboxs[0] = 0;
149
150 if (!accounts)
151 return ERROR_CONFIG_PARSE;
152
153 node = (mboxgrp_t *) create_node(sizeof(mboxgrp_t));
154
155 init_mboxgrp(node);
156
157 strncat(node->key, line + match[1].rm_so,
158 min(match[1].rm_eo - match[1].rm_so, KEY_LEN - 1));
159
160 #ifdef DEBUG
161 printf("debug: FOLDER: '%s'\n", node->key);
162 #endif
163
164 strncat(mboxs, line + match[2].rm_so,
165 min(match[2].rm_eo - match[2].rm_so, LINE_MAX - 1));
166
167 process_mboxgrp(node, mboxs);
168
169 insert_mboxgrp(node);
170
171 return 0;
172 }
173
174
175 /*
176 * Calls set_mbox() in order to create mailboxes that are part of
177 * the mailbox-group.
178 */
179 void process_mboxgrp(mboxgrp_t * node, char *mboxs)
180 {
181 int i = 0;
182 const char *delim = ",";
183 char *tok;
184
185 while (i < MBOXGRP_MBOXES_MAX - 1 && (tok = strsep(&mboxs, delim))) {
186 node->mboxes[i] = (mbox_t *) set_mbox(tok);
187 node->mboxes[++i] = NULL;
188 }
189 }
190
191
192 /*
193 * Find in the mailbox-group tree, the node with the specified key,
194 * and return a pointer to it.
195 */
196 mboxgrp_t *find_mboxgrp(char *key)
197 {
198 int cmp;
199 mboxgrp_t *pos;
200
201 FIND_TREE(mboxgrps, key, pos, cmp);
202 }
203
204
205 /*
206 * Set new mailbox's variables to safe values.
207 */
208 void init_mbox(mbox_t * node)
209 {
210 node->next = NULL;
211 node->name[0] = 0;
212 node->filters[0] = NULL;
213 }
214
215
216 /*
217 * Append mailbox node to linked list.
218 */
219 void append_mbox(mbox_t * node)
220 {
221 mbox_t *pos;
222 mbox_t **ins;
223
224 APPEND_LINKED_LIST(cur_acct->mboxes, node, pos, ins);
225 }
226
227
228 /*
229 * A new mailbox was declared, create it and set it's variables accordingly.
230 */
231 mbox_t *set_mbox(char *name)
232 {
233 mbox_t *node;
234
235 node = (mbox_t *) create_node(sizeof(mbox_t));
236
237 init_mbox(node);
238
239 strncat(node->name, name,
240 min(strlen(name), MBOX_NAME_LEN - 1));
241
242 #ifdef DEBUG
243 printf("debug: MBOX: '%s'\n", node->name);
244 #endif
245
246 append_mbox(node);
247
248 return node;
249 }
250
251
252 /*
253 * Set new filter's variables to safe values.
254 */
255 void init_filter(filter_t * node)
256 {
257 node->left = node->right = NULL;
258 node->key[0] = 0;
259 node->mode = FILTER_MODE_AND;
260 node->action.type = 0;
261 node->action.args[0] = 0;
262 node->masks = NULL;
263 node->masknum = node->masklen = 0;
264 }
265
266
267 /*
268 * Insert filter node to tree.
269 */
270 void insert_filter(filter_t * node)
271 {
272 int cmp;
273 filter_t *pos;
274 filter_t **ins;
275
276 INSERT_TREE(filters, node, pos, ins, cmp);
277 }
278
279
280 /*
281 * A filter entry was declared, create it and set it's variables accordingly.
282 */
283 int set_filter(char *line, regmatch_t * match)
284 {
285 filter_t *node;
286
287 if (cur_fltr && !cur_fltr->action.type)
288 return ERROR_CONFIG_PARSE;
289
290 node = (filter_t *) create_node(sizeof(filter_t));
291
292 init_filter(node);
293
294 strncat(node->key, line + match[1].rm_so,
295 min(match[1].rm_eo - match[1].rm_so, KEY_LEN - 1));
296
297 if (match[2].rm_so != -1) {
298 if (*(line + match[2].rm_so + 1) == 'o' ||
299 *(line + match[2].rm_so + 1) == 'O')
300 node->mode = FILTER_MODE_OR;
301 else
302 node->mode = FILTER_MODE_AND;
303 }
304 #ifdef DEBUG
305 printf("debug: FILTER: '%s' %s\n", node->key,
306 (node->mode == FILTER_MODE_OR ? "OR" : "AND"));
307 #endif
308
309 insert_filter(node);
310 cur_fltr = node;
311
312 return 0;
313 }
314
315
316 /*
317 * Find in the filter tree, the node with the specified key and
318 * return a pointer to it.
319 */
320 filter_t *find_filter(char *key)
321 {
322 int cmp;
323 filter_t *pos;
324
325 FIND_TREE(filters, key, pos, cmp);
326 }
327
328
329 /*
330 * Assign an action to the last declared filter.
331 */
332 int set_action(char *line, regmatch_t * match)
333 {
334 if (!cur_fltr)
335 return ERROR_CONFIG_PARSE;
336
337 if (!strncasecmp(line + match[1].rm_so, "delete", 6))
338 cur_fltr->action.type = FILTER_ACTION_DELETE;
339 else if (!strncasecmp(line + match[1].rm_so, "copy", 4)) {
340 cur_fltr->action.type = FILTER_ACTION_COPY;
341 strncat(cur_fltr->action.destmbox, line + match[2].rm_so,
342 min(match[2].rm_eo - match[2].rm_so, MBOX_NAME_LEN - 1));
343 } else if (!strncasecmp(line + match[1].rm_so, "move", 4)) {
344 cur_fltr->action.type = FILTER_ACTION_MOVE;
345 strncat(cur_fltr->action.destmbox, line + match[3].rm_so,
346 min(match[3].rm_eo - match[3].rm_so, MBOX_NAME_LEN - 1));
347 } else if (!strncasecmp(line + match[1].rm_so, "list", 4))
348 cur_fltr->action.type = FILTER_ACTION_LIST;
349
350 if (match[4].rm_so != -1)
351 strncat(cur_fltr->action.args, line + match[4].rm_so,
352 min(match[4].rm_eo - match[4].rm_so, ARGS_LEN - 1));
353
354 return 0;
355
356 }
357
358
359 /*
360 * Set new mask's variables to safe values.
361 */
362 void init_mask(mask_t * node)
363 {
364 node->next = NULL;
365 node->body[0] = 0;
366 node->type = 0;
367 }
368
369
370 /*
371 * Append mask node to linked list.
372 */
373 void append_mask(mask_t * node)
374 {
375 mask_t *pos;
376 mask_t **app;
377
378 APPEND_LINKED_LIST(cur_fltr->masks, node, pos, app);
379 }
380
381
382 /*
383 * A new mask entry was declared, create it and set it's
384 * variables accordingly.
385 */
386 int set_mask(char *line, regmatch_t * match)
387 {
388 int s, i, f = 0;
389 mask_t *node;
390 char *bp;
391
392 if (!cur_fltr)
393 return ERROR_CONFIG_PARSE;
394
395 node = (mask_t *) create_node(sizeof(mask_t));
396
397 init_mask(node);
398
399 bp = node->body;
400
401 /* If specified set mask's type. */
402 if (match[2].rm_so != -1 && cur_fltr->masks) {
403 if (*(line + match[2].rm_so) == 'o' ||
404 *(line + match[2].rm_so) == 'O')
405 node->type = MASK_TYPE_OR;
406 else
407 node->type = MASK_TYPE_AND;
408 }
409 /* Add NOT if specified. */
410 if (match[3].rm_so != -1) {
411 s = min(match[3].rm_eo - match[3].rm_so,
412 MASK_BODY_LEN - (bp - node->body) - 1);
413 strncpy(bp, line + match[3].rm_so, s);
414 string_upper(bp, s);
415 *(bp + s - 1) = ' '; /* In case it's '\t'. */
416 *(bp + s) = 0;
417 bp += s;
418 }
419 /* Keyword of the search key. */
420 s = min(match[4].rm_eo - match[4].rm_so,
421 MASK_BODY_LEN - (bp - node->body) - 3);
422 strncpy(bp, line + match[4].rm_so, s);
423 string_upper(bp, s);
424 *(bp + s) = 0;
425 bp += s;
426
427 /* Body of the search key (string/number). */
428 for (i = 5; i <= 6; i++)
429 if (match[i].rm_so != -1) {
430 *(bp++) = ' ';
431
432 /* Add '"' if not supplied and search key not a number. */
433 if (match[6].rm_so == -1 &&
434 (strstr(node->body, "LARGER") ||
435 strstr(node->body, "SMALLER")))
436 f = 1;
437 else if (*(line + match[i].rm_so) != '"')
438 *(bp++) = '"';
439
440 *bp = 0;
441
442 s = min(match[i].rm_eo - match[i].rm_so,
443 MASK_BODY_LEN - (bp - node->body) - 2);
444 strncpy(bp, line + match[i].rm_so, s);
445 *(bp + s) = 0;
446 bp += s;
447
448 if (*(line + match[i].rm_so) != '"' && !f)
449 *(bp++) = '"';
450 *bp = 0;
451 }
452 append_mask(node);
453
454 cur_fltr->masknum++;
455 cur_fltr->masklen += (bp - node->body);
456
457
458 #ifdef DEBUG
459 printf("debug: MASK: '%s'\n", node->body);
460 #endif
461
462 return 0;
463 }
464
465
466 /*
467 * A new job was declared, link filters with mailbox-groups.
468 */
469 int set_job(char *line, regmatch_t * match)
470 {
471 int s;
472 const char *delim = ",";
473 char *ftok, *gtok, *fltr, *mbgrp, *f, *g;
474 filter_t *cf;
475 mboxgrp_t *cg;
476
477 if (!accounts || !filters)
478 return ERROR_CONFIG_PARSE;
479
480 s = match[1].rm_eo - match[1].rm_so;
481 fltr = (char *) malloc(s + 1);
482
483 if (!fltr)
484 fatal(ERROR_MEMORY_ALLOCATION, "imapfilter: allocating memory; %s",
485 strerror(errno));
486
487 f = strncpy(fltr, line + match[1].rm_so, s);
488 f[s] = 0;
489
490 s = match[2].rm_eo - match[2].rm_so;
491 mbgrp = (char *) malloc(s + 1);
492
493 if (!mbgrp)
494 fatal(ERROR_MEMORY_ALLOCATION, "imapfilter: allocating memory; %s",
495 strerror(errno));
496
497 /* Go through filters. */
498 while ((ftok = strsep(&f, delim))) {
499 cf = (filter_t *) find_filter(ftok);
500 if (!cf)
501 return ERROR_CONFIG_PARSE;
502
503 g = strncpy(mbgrp, line + match[2].rm_so, s);
504 g[s] = 0;
505
506 /* Go through mailbox groups. */
507 while ((gtok = strsep(&g, delim))) {
508 cg = (mboxgrp_t *) find_mboxgrp(gtok);
509 if (!cg)
510 return ERROR_CONFIG_PARSE;
511 link_mbox_filter(cf, cg);
512 }
513 }
514
515 free(fltr);
516 free(mbgrp);
517
518 return 0;
519 }
520
521
522 /*
523 * Link a filter with a mailbox.
524 */
525 void link_mbox_filter(filter_t * cf, mboxgrp_t * cg)
526 {
527 int i, j;
528 int f;
529
530 for (i = 0; cg->mboxes[i]; i++) {
531
532 for (f = j = 0; cg->mboxes[i]->filters[j]; j++)
533 if (j == MBOX_FILTERS_MAX - 1 ||
534 !strncmp(cf->key, cg->mboxes[i]->filters[j]->key, KEY_LEN))
535 f = 1;
536
537 if (f)
538 continue;
539
540 cg->mboxes[i]->filters[j] = cf;
541 cg->mboxes[i]->filters[j + 1] = NULL;
542
543 }
544
545 #ifdef DEBUG
546 printf("debug: JOB: '%s' '%s'\n", cf->key, cg->key);
547 #endif
548 }
549
550
551 /*
552 * Free allocated memory of data structures that are not needed anymore.
553 */
554 void destroy_data(void)
555 {
556 destroy_mboxgrp(mboxgrps);
557 }
558
559
560 /*
561 * Go through the mailbox-group tree, and free the memory of each node.
562 */
563 void destroy_mboxgrp(mboxgrp_t * node)
564 {
565 if (node->left)
566 destroy_mboxgrp(node->left);
567 else if (node->right)
568 destroy_mboxgrp(node->right);
569
570 #ifdef DEBUG
571 printf("debug: deleting FOLDER: '%s'\n", node->key);
572 #endif
573
574 free(node);
575 }
576
577
578 /*
579 * Convert a string of specified size to upper case.
580 */
581 void string_upper(char *str, size_t size)
582 {
583 int i;
584
585 for (i = 0; i < size; i++)
586 *(str + i) = toupper(*(str + i));
587 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26