1
/* message.c -- message parsing functions
5
/***********************************************************
6
Copyright 1999 by Carnegie Mellon University
10
Permission to use, copy, modify, and distribute this software and its
11
documentation for any purpose and without fee is hereby granted,
12
provided that the above copyright notice appear in all copies and that
13
both that copyright notice and this permission notice appear in
14
supporting documentation, and that the name of Carnegie Mellon
15
University not be used in advertising or publicity pertaining to
16
distribution of the software without specific, written prior
19
CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
20
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
21
FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE FOR
22
ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
23
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
24
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
25
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
26
******************************************************************/
36
#include <sys/types.h>
43
#include "sieve_interface.h"
46
#include "parseaddr.h"
49
/* reject message m with message msg
51
* incompatible with: fileinto, redirect
53
int do_reject(action_list_t *a, const char *msg)
55
action_list_t *b = NULL;
57
/* see if this conflicts with any previous actions taken on this message */
60
if (a->a == ACTION_FILEINTO ||
61
a->a == ACTION_KEEP ||
62
a->a == ACTION_REDIRECT ||
63
a->a == ACTION_REJECT ||
64
a->a == ACTION_VACATION ||
65
a->a == ACTION_SETFLAG ||
66
a->a == ACTION_ADDFLAG ||
67
a->a == ACTION_REMOVEFLAG ||
68
a->a == ACTION_MARK ||
71
return SIEVE_RUN_ERROR;
75
/* add to the action list */
76
a = (action_list_t *) xmalloc(sizeof(action_list_t));
87
/* fileinto message m into mailbox
89
* incompatible with: reject
91
int do_fileinto(action_list_t *a, const char *mbox, int cancel_keep,
92
sieve_imapflags_t *imapflags)
94
action_list_t *b = NULL;
96
/* see if this conflicts with any previous actions taken on this message */
99
if (a->a == ACTION_REJECT)
100
return SIEVE_RUN_ERROR;
104
/* add to the action list */
105
a = (action_list_t *) xmalloc(sizeof(action_list_t));
108
a->a = ACTION_FILEINTO;
109
a->cancel_keep = cancel_keep;
110
a->u.fil.mailbox = mbox;
111
a->u.fil.imapflags = imapflags;
117
/* redirect message m to to addr
119
* incompatible with: reject
121
int do_redirect(action_list_t *a, const char *addr, int cancel_keep)
123
action_list_t *b = NULL;
125
/* xxx we should validate addr */
127
/* see if this conflicts with any previous actions taken on this message */
130
if (a->a == ACTION_REJECT)
131
return SIEVE_RUN_ERROR;
135
/* add to the action list */
136
a = (action_list_t *) xmalloc(sizeof(action_list_t));
139
a->a = ACTION_REDIRECT;
140
a->cancel_keep = cancel_keep;
141
a->u.red.addr = addr;
149
* incompatible with: reject
151
int do_keep(action_list_t *a, sieve_imapflags_t *imapflags)
153
action_list_t *b = NULL;
155
/* see if this conflicts with any previous actions taken on this message */
158
if (a->a == ACTION_REJECT)
159
return SIEVE_RUN_ERROR;
160
if (a->a == ACTION_KEEP) /* don't bother doing it twice */
165
/* add to the action list */
166
a = (action_list_t *) xmalloc(sizeof(action_list_t));
171
a->u.keep.imapflags = imapflags;
179
* incompatible with: nothing---it doesn't cancel any actions
181
int do_discard(action_list_t *a)
183
action_list_t *b = NULL;
185
/* see if this conflicts with any previous actions taken on this message */
188
if (a->a == ACTION_DISCARD) /* don't bother doing twice */
193
/* add to the action list */
194
a = (action_list_t *) xmalloc(sizeof(action_list_t));
197
a->a = ACTION_DISCARD;
204
static int makehash(unsigned char hash[],
205
const char *s1, const char *s2, const char *s3)
207
struct md5_context ctx;
210
md5_update(&ctx, s1, strlen(s1));
211
md5_update(&ctx, s2, strlen(s2));
212
if (s3) md5_update(&ctx, s3, strlen(s3));
213
md5_final(&ctx, hash);
218
int do_vacation(action_list_t *a, char *addr, char *fromaddr,
219
char *subj, const char *msg, int days,
220
int mime, const char *handle)
222
action_list_t *b = NULL;
224
/* see if this conflicts with any previous actions taken on this message */
227
if (a->a == ACTION_REJECT ||
228
a->a == ACTION_VACATION) /* vacation can't be used twice */
229
return SIEVE_RUN_ERROR;
233
/* add to the action list */
234
a = (action_list_t *) xmalloc(sizeof(action_list_t));
237
a->a = ACTION_VACATION;
239
a->u.vac.send.addr = addr;
240
a->u.vac.send.fromaddr = fromaddr;
241
a->u.vac.send.subj = subj; /* user specified subject */
242
a->u.vac.send.msg = msg;
243
a->u.vac.send.mime = mime;
245
makehash(a->u.vac.autoresp.hash, addr, handle, NULL);
247
makehash(a->u.vac.autoresp.hash, addr, fromaddr, msg);
248
a->u.vac.autoresp.days = days;
254
/* setflag f on message m
256
* incompatible with: reject
258
int do_setflag(action_list_t *a, const char *flag)
260
action_list_t *b = NULL;
262
/* see if this conflicts with any previous actions taken on this message */
265
if (a->a == ACTION_REJECT)
266
return SIEVE_RUN_ERROR;
270
/* add to the action list */
271
a = (action_list_t *) xmalloc(sizeof(action_list_t));
274
a->a = ACTION_SETFLAG;
276
a->u.fla.flag = flag;
282
/* addflag f on message m
284
* incompatible with: reject
286
int do_addflag(action_list_t *a, const char *flag)
288
action_list_t *b = NULL;
290
/* see if this conflicts with any previous actions taken on this message */
293
if (a->a == ACTION_REJECT)
294
return SIEVE_RUN_ERROR;
298
/* add to the action list */
299
a = (action_list_t *) xmalloc(sizeof(action_list_t));
302
a->a = ACTION_ADDFLAG;
304
a->u.fla.flag = flag;
310
/* removeflag f on message m
312
* incompatible with: reject
314
int do_removeflag(action_list_t *a, const char *flag)
316
action_list_t *b = NULL;
318
/* see if this conflicts with any previous actions taken on this message */
321
if (a->a == ACTION_REJECT)
322
return SIEVE_RUN_ERROR;
326
/* add to the action list */
327
a = (action_list_t *) xmalloc(sizeof(action_list_t));
330
a->a = ACTION_REMOVEFLAG;
332
a->u.fla.flag = flag;
341
* incompatible with: reject
343
int do_mark(action_list_t *a)
345
action_list_t *b = NULL;
347
/* see if this conflicts with any previous actions taken on this message */
350
if (a->a == ACTION_REJECT)
351
return SIEVE_RUN_ERROR;
355
/* add to the action list */
356
a = (action_list_t *) xmalloc(sizeof(action_list_t));
369
* incompatible with: reject
371
int do_unmark(action_list_t *a)
374
action_list_t *b = NULL;
375
/* see if this conflicts with any previous actions taken on this message */
378
if (a->a == ACTION_REJECT)
379
return SIEVE_RUN_ERROR;
383
/* add to the action list */
384
a = (action_list_t *) xmalloc(sizeof(action_list_t));
387
a->a = ACTION_UNMARK;
396
* incompatible with: none
398
int do_notify(notify_list_t *a, const char *id,
399
const char *method, const char **options,
400
const char *priority, const char *message)
402
notify_list_t *b = NULL;
404
/* find the end of the notify list */
410
/* add to the notify list */
411
a = (notify_list_t *) xmalloc(sizeof(notify_list_t));
419
a->options = options;
420
a->priority = priority;
421
a->message = message;
428
* incomaptible with: none
430
int do_denotify(notify_list_t *n, comparator_t *comp, const void *pat,
431
void *comprock, const char *priority)
435
(!priority || !strcasecmp(n->priority, priority)) &&
436
(!comp || (n->id && comp(n->id, strlen(n->id), pat, comprock)))) {
447
/* given a header, extract an address out of it. if marker points to NULL,
448
extract the first address. otherwise, it's an index into the header to
449
say where to start extracting */
451
struct address *where;
455
int parse_address(const char *header, void **data, void **marker)
457
struct addr_marker *am = (struct addr_marker *) *marker;
459
parseaddr_list(header, (struct address **) data);
460
am = (void *) xmalloc(sizeof(struct addr_marker));
467
char *get_address(address_part_t addrpart,
468
void **data ATTR_UNUSED,
474
struct addr_marker *am = *marker;
485
if (canon_domain && a->domain)
490
#define U_DOMAIN "unspecified-domain"
491
#define U_USER "unknown-user"
492
if (a->mailbox || a->domain) {
493
char *m = a->mailbox ? a->mailbox : U_USER;
494
char *d = a->domain ? a->domain : U_DOMAIN;
495
am->freeme = (char *) xmalloc(strlen(m) + strlen(d) + 2);
497
sprintf(am->freeme, "%s@%s", m, d);
504
case ADDRESS_LOCALPART:
514
char *p = strchr(a->mailbox, '+');
515
int len = p ? p - a->mailbox : (int)strlen(a->mailbox);
517
am->freeme = (char *) xmalloc(len + 1);
518
strncpy(am->freeme, a->mailbox, len);
519
am->freeme[len] = '\0';
529
char *p = strchr(a->mailbox, '+');
530
ret = (p ? p + 1 : NULL);
545
int free_address(void **data, void **marker)
547
struct addr_marker *am = (struct addr_marker *) *marker;
550
parseaddr_free((struct address *) *data);
552
if (am->freeme) free(am->freeme);
558
notify_list_t *new_notify_list(void)
560
notify_list_t *ret = xmalloc(sizeof(notify_list_t));
567
ret->priority = NULL;
574
void free_notify_list(notify_list_t *n)
577
notify_list_t *b = n->next;
578
free(n->options); /* strings live in bytecode, only free the array */
584
action_list_t *new_action_list(void)
586
action_list_t *ret = xmalloc(sizeof(action_list_t));
589
ret->a = ACTION_NONE;
592
ret->cancel_keep = 0;
597
void free_action_list(action_list_t *a)
600
action_list_t *b = a->next;
602
if(a->a == ACTION_VACATION) {
603
if(a->u.vac.send.subj) free(a->u.vac.send.subj);
604
if(a->u.vac.send.addr) free(a->u.vac.send.addr);
605
if(a->u.vac.send.fromaddr) free(a->u.vac.send.fromaddr);