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

Contents of /imapfilter/data.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.6 - (show annotations)
Tue Oct 2 07:31:52 2001 UTC (22 years, 6 months ago) by lefcha
Branch: MAIN
Changes since 1.5: +4 -28 lines
File MIME type: text/plain
Added safer xmalloc and xstrdup.

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

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26