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

Contents of /imapfilter/data.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (show annotations)
Mon Sep 10 23:43:29 2001 UTC (22 years, 6 months ago) by lefcha
Branch: MAIN
File MIME type: text/plain
New imapfilter.

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

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26