Commit 6366c5c6 6366c5c6ed8ae63ed3578610729de531d33a03fa by Sam Roberts

Initial commit of the port of CMU's sieve engine. It builds, and some

actions work, but has seen very little use.
1 parent fcc8b0cb
1 gram-sieve.tab.c
2 Makefile
3 Makefile.in
4 addr.c
5 addr.h
6 sieve-gram.c
7 sieve-gram.h
8 addr-lex.c
9 sieve-lex.c
10 .deps
11 .libs
12 sieve
13 test
14 _*
1 Larry Greenfield <leg+sieve@andrew.cmu.edu> wrote the first pass.
2
3 Alexy Melnikov <mel@taxxi.com> submitted some bug fixes and improvements.
4
5 Ken Murchison <ken@oceana.com> took the ball, added more extensions
6 than existed in the known world, and overall improved the code mightily.
1 /* cmu-sieve
2 * Larry Greenfield
3 * $Id$
4 */
5 /***********************************************************
6 Copyright 1998 by Carnegie Mellon University
7
8 All Rights Reserved
9
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
17 permission.
18
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 ******************************************************************/
1 CFLAGS = -Wall -pedantic -g -DTESTING
2 INCLUDES = -I${top_srcdir}/include -I${top_srcdir}/lib
3
4 MOSTLYCLEANFILES=
5 CLEANFILES=
6 DISTCLEANFILES=
7 MAINTAINERCLEANFILES=\
8 sieve-gram.c sieve-gram.h \
9 sieve-lex.c \
10 addr-lex.c \
11 addr.c addr.h
12
13 bin_PROGRAMS = test sieve
14
15 SRC = \
16 addr-lex.c \
17 addr.c \
18 comparator.c \
19 imparse.c \
20 interp.c \
21 md5.c \
22 message.c \
23 parseaddr.c \
24 script.c \
25 sieve-lex.c \
26 sieve-gram.c \
27 sieve_err.c \
28 svfield.c \
29 tree.c \
30 util.c \
31 xmalloc.c
32
33 test_DEPENDENCIES =
34 test_LDADD =
35 test_SOURCES = \
36 test.c \
37 ${SRC}
38
39
40 sieve_DEPENDENCIES = ../mailbox/libmailbox.la
41 sieve_LDADD = ../mailbox/libmailbox.la ../lib/libmailutils.a
42 sieve_SOURCES = \
43 sieve.c \
44 ${SRC}
45
46 YACC = bison -y
47 YFLAGS = -d
48 LEX = flex
49
50 addr-lex.c: addr-lex.l addr.h
51 $(LEX) -t -Paddr addr-lex.l > $@
52
53 addr.c addr.h: addr.y
54 $(YACC) $(YFLAGS) -p addr addr.y
55 mv -f y.tab.c addr.c
56 mv -f y.tab.h addr.h
57
58 sieve-lex.c: sieve-lex.l sieve-gram.h
59 $(LEX) -t sieve-lex.l > $@
60
61 sieve-gram.c sieve-gram.h: sieve-gram.y
62 $(YACC) $(YFLAGS) sieve-gram.y
63 mv -f y.tab.c sieve-gram.c
64 mv -f y.tab.h sieve-gram.h
65
66 comparator.o: sieve-gram.h
67 script.o: sieve-gram.h
68 tree.o: sieve-gram.h
69
1 $Id$
2
3 CMU Sieve 2.0
4 -------------
5
6 - Compliant with draft-showalter-sieve-11.txt and
7 draft-showalter-sieve-vacation-03.txt.
8
9 - Added support for the regex, imapflags, notify and subaddress extensions.
10 See README for references.
11
12 - Verifies email addresses in redirect and vacation actions are syntactically
13 correct (compliant with RFC822).
14
15 - Run-time error reporting.
16
17 - Changed callback interface to use callback contexts instead of individual
18 parameters. Also added an error string buffer for run-time error reporting.
19
20 - Vacation will not reply to any message containing an "auto-submitted"
21 header containing anything other than "no".
22
23 CMU Sieve 1.4
24 -------------
25
26 Now included with imapd distribution (hell, why not?).
27
28 Error returning and recovering:
29 added error recovering to the parser (but not much!)
30 added error messages to the parser
31
32 Working on error returning and error recovering.
33 run-time errors
34 detect some errors in lexer?
35
36 Working on even better parsing:
37 verify addresses could be addresses
38 verify mailboxes could be mailboxes
39 verify outgoing headers can be headers
40
41 CMU Sieve 1.3
42 -------------
43
44 Changed for integration with cyrus deliver.
45
46 CMU Sieve 1.2
47 -------------
48
49 Added additional callbacks (ok, so I want to make my integration with deliver
50 easier) and envelope and vacation support.
51
52 Made it compile without libcyrus.
53 It should compile without libcyrus, but then it does not implement the
54 "address" test. That's just too much work to do when I have a neato
55 library to do it for me.
56
57 Todo:
58 - regex matching
59
60 CMU Sieve 1.1
61 -------------
62
63 - Updated to draft-showalter-sieve-07bis.txt
64
65 - Simple API (see sieve_interface.h; currently mostly undocumented)
66
67 - Implements all of the optional features except "envelope"
68
69 - Maintains "if it parses, it probably runs" behavior. (Goal: minimize
70 run-time errors.)
71
72 CMU Sieve 1.0
73 -------------
74
75 - prototype implementation
1 $Id$
2
3 CMU Sieve 2.0
4 -------------
5
6 This code is typically distributed as part of Cyrus imapd 1.6 and higher.
7 This code will be configured and compiled from the cyrus-imapd directory.
8
9 Notes on implementation
10 -----------------------
11
12 This is an implementation of a simple Sieve API. This API is
13 well-suited for incorporating in other programs, but is not
14 extensible. (If there is interest, we may implement an extensible API
15 in the future.)
16
17 If you wish to compile Sieve without compiling all of imapd, you'll
18 have to create a Makefile for it. I recommend you use Makefile.in as
19 a guide.
20
21 It should compile without libcyrus, but then it does not implement the
22 "address" test. That's just too much work to do when I have a neato
23 library to do it for me.
24
25 There's a simple "test" application included, which is not built by
26 default (type "make test" to build it). It expects:
27
28 test <message> <script>
29
30 And prints out the actions taken or errors encountered. (This
31 implementation will attempt all the actions or no actions.)
32
33 Questions and comments to:
34 Larry Greenfield (leg+sieve@andrew.cmu.edu)
35
36 References:
37
38 [SIEVE] Showalter, T., "Sieve: A Mail Filtering Language",
39 draft-showalter-sieve-11.txt, May, 2000.
40
41 [VACATION] Showalter, T., "Sieve: Vacation Extension",
42 draft-showalter-sieve-vacation-03.txt, May, 2000.
43
44 [IMAPFLAGS] Melnikov, A., "Sieve -- IMAP flag extension",
45 draft-melnikov-sieve-imapflags-02.txt, June, 1999.
46
47 [NOTIFY] Martin, T., "Sieve -- An extension for providing instant
48 notifications", draft-ietf-sieve-notify-00.txt, February, 2000.
49
50 [REGEX] Murchison, K., "Sieve: Regular Expression Extension",
51 draft-murchison-sieve-regex-01.txt, March, 2000.
52
53 [SUBADDR] Murchison, K., "Sieve: Subaddress Extension",
54 draft-murchison-sieve-subaddress-00.txt, March, 2000.
1 %{
2 /*
3 * addr-lex.l -- RFC 822 address lexer
4 */
5
6 #include "addr.h"
7 #include <string.h>
8
9 #undef YY_INPUT
10 #define YY_INPUT(b, r, ms) (r = addrinput(b, ms))
11
12 int addrinput(char *buf, int max_size);
13 void addrerror(const char *);
14
15 static int ncom; /* number of open comments */
16 %}
17
18 %option noyywrap
19 %x QSTRING DOMAINLIT COMMENT
20
21 %%
22
23 \" { BEGIN QSTRING; return yytext[0]; }
24 \[ { BEGIN DOMAINLIT; return yytext[0]; }
25 \( { ncom = 1; BEGIN COMMENT; }
26 \) { addrerror("address parse error, "
27 "unexpected `')'' "
28 "(unbalanced comment)");
29 yyterminate(); }
30
31 [^\(\)<>@,;:\\".\[\] \n\r]+ return ATOM;
32
33 [\t \n\r]+ /* ignore whitespace */
34 . return yytext[0];
35
36 <QSTRING>([^\n\r"\\]|\\.)* return QTEXT;
37 <QSTRING>\" { BEGIN INITIAL; return yytext[0]; }
38
39 <DOMAINLIT>([^\[\]\n\r\\]|\\.)* return DTEXT;
40 <DOMAINLIT>\] { BEGIN INITIAL; return yytext[0]; }
41
42 <COMMENT>([^\(\)\n\0\\]|\\.)* /* ignore comments */
43 <COMMENT>\( ncom++;
44 <COMMENT>\) { ncom--; if (ncom == 0) BEGIN INITIAL; }
45 <COMMENT><<EOF>> { addrerror("address parse error, "
46 "expecting `')'' "
47 "(unterminated comment)");
48 yyterminate(); }
49
50 %%
51
52 /* take input from address string provided by sieve parser */
53 int addrinput(char *buf, int max_size)
54 {
55 extern char *addrptr; /* current position in address string */
56 int n; /* number of characters to read from string */
57
58 n = strlen(addrptr) < max_size ? strlen(addrptr) : max_size;
59 if (n > 0) {
60 memcpy(buf, addrptr, n);
61 addrptr += n;
62 }
63 return n;
64 }
1 %{
2 /*
3 * addr.y -- RFC 822 address parser
4 */
5
6 #include <stdlib.h>
7 #include <string.h>
8
9 #include "addr.h"
10
11 int yyerror(char *msg);
12 extern int yylex(void);
13
14 #define yyparse addrparse
15 #define yyerror addrerror
16
17 #define YYERROR_VERBOSE /* i want better error messages! */
18 %}
19
20 %token ATOM QTEXT DTEXT
21
22 %start sieve_address
23
24 %%
25 address: mailbox /* one addressee */
26 | group /* named list */
27 ;
28
29 group: phrase ':' ';'
30 | phrase ':' mailboxes ';'
31 ;
32
33 mailboxes: mailbox
34 | mailbox ',' mailboxes
35 ;
36
37 mailbox: addrspec /* simple address */
38 | phrase routeaddr /* name & addr-spec */
39 ;
40
41 routeaddr: '<' addrspec '>'
42 | '<' route ':' addrspec '>'
43 ;
44
45 route: '@' domain /* path-relative */
46 | '@' domain ',' route
47 ;
48
49 sieve_address: addrspec /* simple address */
50 | phrase '<' addrspec '>' /* name & addr-spec */
51 ;
52
53 addrspec: localpart '@' domain /* global-address */
54 ;
55
56 localpart: word /* uninterpreted, case-preserved */
57 | word '.' localpart
58 ;
59
60 domain: subdomain
61 | subdomain '.' domain
62 ;
63
64 subdomain: domainref
65 | domainlit
66 ;
67
68 domainref: ATOM /* symbolic reference */
69 ;
70
71 domainlit: '[' DTEXT ']'
72 ;
73
74 phrase: word
75 | word phrase
76 ;
77
78 word: ATOM
79 | qstring
80 ;
81
82 qstring: '"' QTEXT '"'
83 ;
84
85 %%
86
87 /* copy address error message into buffer provided by sieve parser */
88 int yyerror(char *s)
89 {
90 extern char addrerr[];
91
92 strcpy(addrerr, s);
93 return 0;
94 }
1 /* comparator.c -- comparator functions
2 * Larry Greenfield
3 * $Id$
4 */
5 /***********************************************************
6 Copyright 1999 by Carnegie Mellon University
7
8 All Rights Reserved
9
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
17 permission.
18
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 ******************************************************************/
27
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31
32 #include <stdlib.h>
33 #include <ctype.h>
34 #include <string.h>
35 #include <fnmatch.h>
36 #ifdef HAVE_STRINGS_H
37 # include <strings.h>
38 #endif
39
40 #include "comparator.h"
41 #include "tree.h"
42 #include "sieve-gram.h"
43
44 /* --- i;octet comparators --- */
45
46 /* just compare the two; these should be NULL terminated */
47 static int octet_is(const char *pat, const char *text)
48 {
49 int sl;
50 sl = strlen(pat);
51
52 return (sl == strlen(text)) && !memcmp(pat, text, sl);
53 }
54
55 /* we implement boyer-moore for hell of it, since this is probably
56 not very useful for sieve */
57 #if 0
58 int boyer_moore(char *pat, char *text)
59 {
60 int i, j; /* indexes */
61 int M = strlen(pat); /* length of pattern */
62 int N = strlen(text); /* length of text */
63 int skip[256]; /* table of how much to skip, based on each character */
64
65 /* initialize skip table */
66 for (i = 0; i < 256; i++)
67 skip[i] = M;
68 for (i = 0; i < M; i++)
69 skip[(int) pat[i]] = M-i-1;
70
71 /* look for pat in text */
72 i = j = M-1;
73 do {
74 if (pat[j] == text[i]) {
75 i--;
76 j--;
77 } else {
78 if (M-j > skip[(int) text[i]]) {
79 i = i + M - j;
80 } else {
81 i = i + skip[(int) text[i]];
82 }
83 j = M-1;
84 }
85 } while (!((j < 0) || (i >= N)));
86 /* i+1 is the position of the match if i < N */
87 return (i < N) ? 1 : 0;
88 }
89 #endif
90
91 /* we do a brute force attack */
92 static int octet_contains(const char *pat, const char *text)
93 {
94 return (strstr(text, pat) != NULL);
95 }
96
97 static int octet_matches(const char *pat, const char *text)
98 {
99 return !fnmatch(pat, text, 0);
100 }
101
102 #ifdef ENABLE_REGEX
103 static int octet_regex(const char *pat, const char *text)
104 {
105 return (!regexec((regex_t *) pat, text, 0, NULL, 0));
106 }
107 #endif
108
109
110 /* --- i;ascii-casemap comparators --- */
111
112 static int ascii_casemap_is(const char *pat, const char *text)
113 {
114 int sl;
115 sl = strlen(pat);
116
117 return (sl == strlen(text)) && !strncasecmp(pat, text, sl);
118 }
119
120 /* sheer brute force */
121 static int ascii_casemap_contains(const char *pat, const char *text)
122 {
123 int N = strlen(text);
124 int M = strlen(pat);
125 int i, j;
126
127 i = 0, j = 0;
128 while ((j < M) && (i < N)) {
129 if (toupper(text[i]) == toupper(pat[j])) {
130 i++; j++;
131 } else {
132 i = i - j + 1;
133 j = 0;
134 }
135 }
136 return (j == M); /* we found a match! */
137 }
138
139 static int ascii_casemap_matches(const char *pat, const char *text)
140 {
141 int ret;
142 char *p, *t;
143 int i;
144
145 /* sigh, i'll just make local copies of these guys */
146 p = strdup(pat); t = strdup(text);
147 for (i = 0; p[i] != '\0'; i++)
148 p[i] = toupper(p[i]);
149 for (i = 0; t[i] != '\0'; i++)
150 t[i] = toupper(t[i]);
151
152 ret = !fnmatch(p, t, 0);
153 free(p); free(t);
154
155 return ret;
156 }
157
158 /* i;ascii-numeric; only supports "is"
159 equality: numerically equal, or both not numbers */
160 static int ascii_numeric_is(const char *pat, const char *text)
161 {
162 if (isdigit((int) *pat)) {
163 if (isdigit((int) *text)) {
164 return (atoi(pat) == atoi(text));
165 } else {
166 return 0;
167 }
168 } else if (isdigit((int) *text)) return 0;
169 else return 1; /* both not digits */
170 }
171
172 comparator_t *lookup_comp(const char *comp, int mode)
173 {
174 comparator_t *ret;
175
176 ret = NULL;
177 if (!strcmp(comp, "i;octet")) {
178 switch (mode) {
179 case IS:
180 ret = &octet_is;
181 break;
182 case CONTAINS:
183 ret = &octet_contains;
184 break;
185 case MATCHES:
186 ret = &octet_matches;
187 break;
188 #ifdef ENABLE_REGEX
189 case REGEX:
190 ret = &octet_regex;
191 break;
192 #endif
193 }
194 } else if (!strcmp(comp, "i;ascii-casemap")) {
195 switch (mode) {
196 case IS:
197 ret = &ascii_casemap_is;
198 break;
199 case CONTAINS:
200 ret = &ascii_casemap_contains;
201 break;
202 case MATCHES:
203 ret = &ascii_casemap_matches;
204 break;
205 #ifdef ENABLE_REGEX
206 case REGEX:
207 /* the ascii-casemap destinction is made during
208 the compilation of the regex in verify_regex() */
209 ret = &octet_regex;
210 break;
211 #endif
212 }
213 } else if (!strcmp(comp, "i;ascii-numeric")) {
214 switch (mode) {
215 case IS:
216 ret = &ascii_numeric_is;
217 break;
218 }
219 }
220 return ret;
221 }
1 /* comparator.h
2 * Larry Greenfield
3 */
4 /***********************************************************
5 Copyright 1999 by Carnegie Mellon University
6
7 All Rights Reserved
8
9 Permission to use, copy, modify, and distribute this software and its
10 documentation for any purpose and without fee is hereby granted,
11 provided that the above copyright notice appear in all copies and that
12 both that copyright notice and this permission notice appear in
13 supporting documentation, and that the name of Carnegie Mellon
14 University not be used in advertising or publicity pertaining to
15 distribution of the software without specific, written prior
16 permission.
17
18 CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
19 THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
20 FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE FOR
21 ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
22 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
23 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
24 OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 ******************************************************************/
26
27 #ifndef COMPARATOR_H
28 #define COMPARATOR_H
29
30 #ifdef ENABLE_REGEX
31 #ifdef HAVE_RX
32 #include <rxposix.h>
33 #else
34 #include <sys/types.h>
35 #include <regex.h>
36 #endif
37 #endif
38
39 /* compares pat to text; returns 1 if it's true, 0 otherwise
40 first arg is pat, second arg is text */
41 typedef int comparator_t(const char *, const char *);
42
43 /* returns a pointer to a comparator function given it's name */
44 comparator_t *lookup_comp(const char *comp, int mode);
45
46 #endif
1 /* exitcodes.h -- wrapper around sysextis.h
2 * $Id$
3 *
4 * Copyright (c) 1998-2000 Carnegie Mellon University. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 *
18 * 3. The name "Carnegie Mellon University" must not be used to
19 * endorse or promote products derived from this software without
20 * prior written permission. For permission or any other legal
21 * details, please contact
22 * Office of Technology Transfer
23 * Carnegie Mellon University
24 * 5000 Forbes Avenue
25 * Pittsburgh, PA 15213-3890
26 * (412) 268-4387, fax: (412) 268-7395
27 * tech-transfer@andrew.cmu.edu
28 *
29 * 4. Redistributions of any form whatsoever must retain the following
30 * acknowledgment:
31 * "This product includes software developed by Computing Services
32 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
33 *
34 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
35 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
36 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
37 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
38 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
39 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
40 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
41 *
42 */
43
44 /* Sendmail has some weird ideas on what constitutes permenant failure. On
45 more than one occasion, we have gotten burned by this moving users around
46 through various inadvisable means, screwing up the mailboxes file,
47 whatever.
48
49 We don't want to fail out permenantly on things like EX_USAGE, EX_SOFTWARE,
50 etc., because that generally means someone was just screwing with the mail
51 store and we don't want to lose mail.
52
53 Instead, we map these EC_* codes to EX_* codes, thereby lying to Sendmail,
54 since we don't derive any benefit from Sendmail knowing what the error was.
55 We just want it to retry all the time anyway. This way, should sendmail's
56 behavior be different and we start deriving benefit from Sendmail knowing
57 stuff, we can easily change it back.
58
59 So other code uses the EC_* error, then we maybe change it to TEMPFAIL if
60 we don't agree on whether the error should be permenant or not.
61
62 Comments below stolen from sysexits.h. */
63
64 #ifndef INCLUDED_EXITCODES_H
65 #define INCLUDED_EXITCODES_H
66
67 #include <sysexits.h>
68
69 #define EC_OK 0 /* successful termination */
70
71 #define EC_USAGE EX_TEMPFAIL /* command line usage error */
72 #define EC_DATAERR EX_DATAERR /* data format error */
73 #define EC_NOINPUT EX_TEMPFAIL /* cannot open input */
74 #define EC_NOUSER EX_NOUSER /* addressee unknown */
75 #define EC_NOHOST EX_TEMPFAIL /* host name unknown */
76 #define EC_UNAVAILABLE EX_TEMPFAIL /* service unavailable */
77 #define EC_SOFTWARE EX_TEMPFAIL /* internal software error */
78 #define EC_OSERR EX_TEMPFAIL /* system error (e.g., can't fork) */
79 #define EC_OSFILE EX_TEMPFAIL /* critical OS file missing */
80 #define EC_CANTCREAT EX_TEMPFAIL /* can't create (user) output file */
81 #define EC_IOERR EX_TEMPFAIL /* input/output error */
82 #define EC_TEMPFAIL EX_TEMPFAIL /* user is invited to retry */
83 #define EC_PROTOCOL EX_TEMPFAIL /* remote error in protocol */
84 #define EC_NOPERM EX_TEMPFAIL /* permission denied */
85 #define EC_CONFIG EX_TEMPFAIL /* configuration error */
86
87 #endif /* INCLUDED_EXITCODES_H */
1 /* hmac-md5.h -- HMAC_MD5 functions
2 */
3
4 #ifndef HMAC_MD5_H
5 #define HMAC_MD5_H 1
6
7 #define HMAC_MD5_SIZE 16
8
9 /* intermediate MD5 context */
10 typedef struct HMAC_MD5_CTX_s {
11 MD5_CTX ictx, octx;
12 } HMAC_MD5_CTX;
13
14 /* intermediate HMAC state
15 * values stored in network byte order (Big Endian)
16 */
17 typedef struct HMAC_MD5_STATE_s {
18 UINT4 istate[4];
19 UINT4 ostate[4];
20 } HMAC_MD5_STATE;
21
22 /* One step hmac computation
23 *
24 * digest may be same as text or key
25 */
26 void hmac_md5(const unsigned char *text, int text_len,
27 const unsigned char *key, int key_len,
28 unsigned char digest[HMAC_MD5_SIZE]);
29
30 /* create context from key
31 */
32 void hmac_md5_init(HMAC_MD5_CTX *hmac,
33 const unsigned char *key, int key_len);
34
35 /* precalculate intermediate state from key
36 */
37 void hmac_md5_precalc(HMAC_MD5_STATE *hmac,
38 const unsigned char *key, int key_len);
39
40 /* initialize context from intermediate state
41 */
42 void hmac_md5_import(HMAC_MD5_CTX *hmac, HMAC_MD5_STATE *state);
43
44 #define hmac_md5_update(hmac, text, text_len) MD5Update(&(hmac)->ictx, (text), (text_len))
45
46 /* finish hmac from intermediate result. Intermediate result is zeroed.
47 */
48 void hmac_md5_final(unsigned char digest[HMAC_MD5_SIZE],
49 HMAC_MD5_CTX *hmac);
50
51 #endif /* HMAC_MD5_H */
1 /* imparse.c -- IMxP client-side parsing routines
2 $Id$
3
4 * Copyright (c) 1998-2000 Carnegie Mellon University. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 *
18 * 3. The name "Carnegie Mellon University" must not be used to
19 * endorse or promote products derived from this software without
20 * prior written permission. For permission or any other legal
21 * details, please contact
22 * Office of Technology Transfer
23 * Carnegie Mellon University
24 * 5000 Forbes Avenue
25 * Pittsburgh, PA 15213-3890
26 * (412) 268-4387, fax: (412) 268-7395
27 * tech-transfer@andrew.cmu.edu
28 *
29 * 4. Redistributions of any form whatsoever must retain the following
30 * acknowledgment:
31 * "This product includes software developed by Computing Services
32 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
33 *
34 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
35 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
36 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
37 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
38 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
39 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
40 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
41 *
42 *
43 */
44 #include <config.h>
45 #include <stdio.h>
46 #include <ctype.h>
47
48 #include "imparse.h"
49
50 /*
51 * Parse a word from the string starting at the pointer pointed to by 's'.
52 * Places a pointer to the parsed word in the pointer at 'retval',
53 * returns the character following the word, and modifies the pointer at
54 * 's' to point after the returned character. Modifies the input buffer.
55 */
56 int imparse_word(s, retval)
57 char **s;
58 char **retval;
59 {
60 int c;
61
62 *retval = *s;
63 for (;;) {
64 c = *(*s)++;
65 if (!c || isspace(c) || c == '(' || c == ')' || c == '\"') {
66 (*s)[-1] = '\0';
67 return c;
68 }
69 }
70 }
71
72 /*
73 * Parse an astring from the string starting at the pointer pointed to
74 * by 's'. On success, places a pointer to the parsed word in the
75 * pointer at 'retval', returns the character following the word, and
76 * modifies the pointer at 's' to point after the returned character.
77 * On failure, returns EOF, modifies the pointer at 'retval' to point
78 * at the empty string, and modifies 's' to point around the syntax error.
79 * Modifies the input buffer.
80 */
81 int imparse_astring(s, retval)
82 char **s;
83 char **retval;
84 {
85 int c;
86 char *d;
87 int len = 0;
88 int sawdigit = 0;
89
90 switch (**s) {
91 case '\0':
92 case ' ':
93 case '(':
94 case ')':
95 case '\r':
96 case '\n':
97 /* Invalid starting character */
98 *retval = "";
99 return EOF;
100
101 default:
102 /*
103 * Atom -- parser is liberal in accepting specials other
104 * than whitespace, parens, or double quotes
105 */
106 return imparse_word(s, retval);
107
108 case '\"':
109 /*
110 * Quoted-string. Parser is liberal in accepting qspecials
111 * other than double-quote, CR, and LF.
112 */
113 *retval = d = ++(*s);
114 for (;;) {
115 c = *(*s)++;
116 if (c == '\\') {
117 c = *(*s)++;
118 }
119 else if (c == '\"') {
120 *d = '\0';
121 return *(*s)++;
122 }
123 else if (c == '\0' || c == '\r' || c == '\n') {
124 *retval = "";
125 return EOF;
126 }
127 *d++ = c;
128 }
129
130 case '{':
131 /* Literal */
132 (*s)++;
133 while (isdigit(c = *(*s)++)) {
134 sawdigit = 1;
135 len = len*10 + c - '0';
136 }
137 if (!sawdigit || c != '}' || *(*s)++ != '\r' || *(*s)++ != '\n') {
138 *retval = "";
139 return EOF;
140 }
141 *retval = *s;
142 *s += len;
143 c = **s;
144 *(*s)++ = '\0'; /* Note that 0 and '\0' mean the same thing */
145 return c;
146 }
147 }
148
149 /*
150 * Return nonzero if 's' matches the grammar for an atom
151 */
152 int imparse_isatom(s)
153 const char *s;
154 {
155 int len = 0;
156
157 if (!*s) return 0;
158 for (; *s; s++) {
159 len++;
160 if (*s & 0x80 || *s < 0x1f || *s == 0x7f ||
161 *s == ' ' || *s == '{' || *s == '(' || *s == ')' ||
162 *s == '\"' || *s == '%' || *s == '*' || *s == '\\') return 0;
163 }
164 if (len >= 1024) return 0;
165 return 1;
166 }
167
168 /*
169 * Return nonzero if 's' matches the grammar for a sequence
170 */
171 int imparse_issequence(const char* s)
172 {
173 int c;
174 int len = 0;
175 int sawcolon = 0;
176
177 while ((c = *s)) {
178 if (c == ',') {
179 if (!len) return 0;
180 if (!isdigit((int) s[-1]) && s[-1] != '*') return 0;
181 sawcolon = 0;
182 }
183 else if (c == ':') {
184 if (sawcolon || !len) return 0;
185 if (!isdigit((int) s[-1]) && s[-1] != '*') return 0;
186 sawcolon = 1;
187 }
188 else if (c == '*') {
189 if (len && s[-1] != ',' && s[-1] != ':') return 0;
190 if (isdigit((int) s[1])) return 0;
191 }
192 else if (!isdigit(c)) {
193 return 0;
194 }
195 s++;
196 len++;
197 }
198 if (len == 0) return 0;
199 if (!isdigit((int) s[-1]) && s[-1] != '*') return 0;
200 return 1;
201 }
202
203 /*
204 * Return nonzero if 's' matches the grammar for a number
205 */
206 int imparse_isnumber(const char *s)
207 {
208 if (!*s) return 0;
209 for (; *s; s++) {
210 if (!isdigit((int) *s)) return 0;
211 }
212 return 1;
213 }
1 /* imparse.h -- IMxP client-side parsing routines
2 * $Id$
3 * Copyright (c) 1998-2000 Carnegie Mellon University. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. The name "Carnegie Mellon University" must not be used to
18 * endorse or promote products derived from this software without
19 * prior written permission. For permission or any other legal
20 * details, please contact
21 * Office of Technology Transfer
22 * Carnegie Mellon University
23 * 5000 Forbes Avenue
24 * Pittsburgh, PA 15213-3890
25 * (412) 268-4387, fax: (412) 268-7395
26 * tech-transfer@andrew.cmu.edu
27 *
28 * 4. Redistributions of any form whatsoever must retain the following
29 * acknowledgment:
30 * "This product includes software developed by Computing Services
31 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
32 *
33 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
34 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
35 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
36 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
37 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
38 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
39 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
40 *
41 */
42
43 #ifndef INCLUDED_IMPARSE_H
44 #define INCLUDED_IMPARSE_H
45
46 extern int imparse_word (char **s, char **retval);
47 extern int imparse_astring (char **s, char **retval);
48 extern int imparse_isatom (const char *s);
49 extern int imparse_issequence (const char *s);
50 extern int imparse_isnumber (const char *s);
51
52 #endif /* INCLUDED_IMPARSE_H */
1 /* interp.c -- sieve script interpretor builder
2 * Larry Greenfield
3 * $Id$
4 */
5 /***********************************************************
6 Copyright 1999 by Carnegie Mellon University
7
8 All Rights Reserved
9
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
17 permission.
18
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 ******************************************************************/
27
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31
32 #include <stdlib.h>
33
34 #include "xmalloc.h"
35
36 #include "sieve_interface.h"
37 #include "interp.h"
38
39 const char *sieve_version = "cmu-sieve 2.0";
40
41 /* build a sieve interpretor */
42 int sieve_interp_alloc(sieve_interp_t **interp, void *interp_context)
43 {
44 sieve_interp_t *i;
45 static int initonce;
46
47 if (!initonce) {
48 initialize_siev_error_table();
49 initonce = 1;
50 }
51
52 *interp = NULL;
53 i = (sieve_interp_t *) xmalloc(sizeof(sieve_interp_t));
54 if (i == NULL) {
55 return SIEVE_NOMEM;
56 }
57
58 i->redirect = i->discard = i->reject = i->fileinto = i->keep = NULL;
59 i->getsize = NULL;
60 i->getheader = NULL;
61 i->getenvelope = NULL;
62 i->vacation = NULL;
63 i->notify = NULL;
64
65 i->curflags.flag = NULL; i->curflags.nflags = 0;
66 i->markflags = NULL;
67
68 i->interp_context = interp_context;
69 i->err = NULL;
70
71 *interp = i;
72 return SIEVE_OK;
73 }
74
75 static const char *sieve_extensions = "fileinto reject envelope vacation"
76 " imapflags notify subaddress"
77 #ifdef ENABLE_REGEX
78 " regex";
79 #else
80 "";
81 #endif /* ENABLE_REGEX */
82
83 const char *sieve_listextensions(void)
84 {
85 return sieve_extensions;
86 }
87
88 void free_imapflags(sieve_imapflags_t *imapflags)
89 {
90 while (imapflags->nflags)
91 free(imapflags->flag[--imapflags->nflags]);
92 free(imapflags->flag);
93
94 imapflags->flag = NULL;
95 }
96
97 int sieve_interp_free(sieve_interp_t **interp)
98 {
99 free_imapflags(&(*interp)->curflags);
100 free(*interp);
101
102 return SIEVE_OK;
103 }
104
105 /* add the callbacks */
106 int sieve_register_redirect(sieve_interp_t *interp, sieve_callback *f)
107 {
108 interp->redirect = f;
109
110 return SIEVE_OK;
111 }
112
113 int sieve_register_discard(sieve_interp_t *interp, sieve_callback *f)
114 {
115 interp->discard = f;
116
117 return SIEVE_OK;
118 }
119
120 int sieve_register_reject(sieve_interp_t *interp, sieve_callback *f)
121 {
122 interp->reject = f;
123
124 return SIEVE_OK;
125 }
126
127 int sieve_register_fileinto(sieve_interp_t *interp, sieve_callback *f)
128 {
129 interp->fileinto = f;
130
131 return SIEVE_OK;
132 }
133
134 int sieve_register_keep(sieve_interp_t *interp, sieve_callback *f)
135 {
136 interp->keep = f;
137
138 return SIEVE_OK;
139 }
140
141 static char *default_markflags[] = { "\\flagged" };
142 static sieve_imapflags_t default_mark = { default_markflags, 1 };
143
144 int sieve_register_imapflags(sieve_interp_t *interp, sieve_imapflags_t *mark)
145 {
146 interp->markflags =
147 (mark && mark->flag && mark->nflags) ? mark : &default_mark;
148
149 return SIEVE_OK;
150 }
151
152 int sieve_register_notify(sieve_interp_t *interp, sieve_callback *f)
153 {
154 interp->notify = f;
155
156 return SIEVE_OK;
157 }
158
159 /* add the callbacks for messages. again, undefined if used after
160 sieve_script_parse */
161 int sieve_register_size(sieve_interp_t *interp, sieve_get_size *f)
162 {
163 interp->getsize = f;
164 return SIEVE_OK;
165 }
166
167 int sieve_register_header(sieve_interp_t *interp, sieve_get_header *f)
168 {
169 interp->getheader = f;
170 return SIEVE_OK;
171 }
172
173 int sieve_register_envelope(sieve_interp_t *interp, sieve_get_envelope *f)
174 {
175 interp->getenvelope = f;
176 return SIEVE_OK;
177 }
178
179 int sieve_register_vacation(sieve_interp_t *interp, sieve_vacation_t *v)
180 {
181 if (!interp->getenvelope) {
182 return SIEVE_NOT_FINALIZED; /* we need envelope for vacation! */
183 }
184
185 if (v->min_response == 0) v->min_response = 3;
186 if (v->max_response == 0) v->max_response = 90;
187 if (v->min_response < 0 || v->max_response < 7 || !v->autorespond
188 || !v->send_response) {
189 return SIEVE_FAIL;
190 }
191
192 interp->vacation = v;
193 return SIEVE_OK;
194 }
195
196 int sieve_register_parse_error(sieve_interp_t *interp, sieve_parse_error *f)
197 {
198 interp->err = f;
199 return SIEVE_OK;
200 }
201
202 int sieve_register_execute_error(sieve_interp_t *interp, sieve_execute_error *f)
203 {
204 interp->execute_err = f;
205 return SIEVE_OK;
206 }
207
208 int sieve_register_summary(sieve_interp_t *interp, sieve_execute_error *f)
209 {
210 interp->summary = f;
211 return SIEVE_OK;
212 }
213
214 int interp_verify(sieve_interp_t *i)
215 {
216 if (i->redirect && i->keep && i->getsize && i->getheader) {
217 return SIEVE_OK;
218 } else {
219 return SIEVE_NOT_FINALIZED;
220 }
221 }
1 /* interp.h -- interpretor definition
2 * Larry Greenfield
3 * $Id$
4 */
5 /***********************************************************
6 Copyright 1999 by Carnegie Mellon University
7
8 All Rights Reserved
9
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
17 permission.
18
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 *****************************************************************/
27
28 #ifndef SIEVE_INTERP_H
29 #define SIEVE_INTERP_H
30
31 #include "sieve_interface.h"
32
33 struct sieve_interp {
34 /* standard callbacks for actions */
35 sieve_callback *redirect, *discard, *reject, *fileinto, *keep;
36 sieve_callback *notify;
37 sieve_vacation_t *vacation;
38
39 sieve_get_size *getsize;
40 sieve_get_header *getheader;
41 sieve_get_envelope *getenvelope;
42
43 sieve_parse_error *err;
44
45 /* current imapflags state */
46 sieve_imapflags_t curflags;
47
48 /* site-specific imapflags for mark/unmark */
49 sieve_imapflags_t *markflags;
50
51 sieve_execute_error *execute_err;
52 sieve_execute_error *summary;
53
54 /* context to pass along */
55 void *interp_context;
56 };
57
58 int interp_verify(sieve_interp_t *interp);
59 void free_imapflags(sieve_imapflags_t *imapflags);
60
61 #endif
This diff is collapsed. Click to expand it.
1 /* MD5.H - header file for MD5C.C
2 */
3
4 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
5 rights reserved.
6
7 License to copy and use this software is granted provided that it
8 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
9 Algorithm" in all material mentioning or referencing this software
10 or this function.
11
12 License is also granted to make and use derivative works provided
13 that such works are identified as "derived from the RSA Data
14 Security, Inc. MD5 Message-Digest Algorithm" in all material
15 mentioning or referencing the derived work.
16
17 RSA Data Security, Inc. makes no representations concerning either
18 the merchantability of this software or the suitability of this
19 software for any particular purpose. It is provided "as is"
20 without express or implied warranty of any kind.
21 These notices must be retained in any copies of any part of this
22 documentation and/or software.
23 */
24
25 /* MD5 context. */
26 typedef struct {
27 UINT4 state[4]; /* state (ABCD) */
28 UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
29 unsigned char buffer[64]; /* input buffer */
30 } MD5_CTX;
31
32 void MD5Init PROTO_LIST ((MD5_CTX *));
33 void MD5Update PROTO_LIST
34 ((MD5_CTX *, unsigned char *, unsigned int));
35 void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
36
37 void hmac_md5 PROTO_LIST ((unsigned char *, int, unsigned char *, int, unsigned char*));
1 /* GLOBAL.H - RSAREF types and constants
2 */
3
4 /* PROTOTYPES should be set to one if and only if the compiler supports
5 function argument prototyping.
6 The following makes PROTOTYPES default to 0 if it has not already
7 been defined with C compiler flags.
8 */
9 #ifndef PROTOTYPES
10 #define PROTOTYPES 0
11 #endif
12
13 /* POINTER defines a generic pointer type */
14 typedef unsigned char *POINTER;
15
16 /* UINT2 defines a two byte word */
17 typedef unsigned short int UINT2;
18
19 /* UINT4 defines a four byte word */
20 typedef unsigned long int UINT4;
21
22 /* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
23 If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
24 returns an empty list.
25 */
26 #if PROTOTYPES
27 #define PROTO_LIST(list) list
28 #else
29 #define PROTO_LIST(list) ()
30 #endif
31
1 /* message.h
2 * Larry Greenfield
3 * $Id$
4 */
5 /***********************************************************
6 Copyright 1999 by Carnegie Mellon University
7
8 All Rights Reserved
9
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
17 permission.
18
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 ******************************************************************/
27
28 #ifndef MESSAGE_H
29 #define MESSAGE_H
30
31 #include "sieve_interface.h" /* for action contexts */
32 #include "tree.h" /* for stringlist_t */
33
34 typedef struct Action action_list_t;
35
36 typedef enum {
37 ACTION_NONE,
38 ACTION_REJECT,
39 ACTION_FILEINTO,
40 ACTION_KEEP,
41 ACTION_REDIRECT,
42 ACTION_DISCARD,
43 ACTION_VACATION,
44 ACTION_SETFLAG,
45 ACTION_ADDFLAG,
46 ACTION_REMOVEFLAG,
47 ACTION_MARK,
48 ACTION_UNMARK,
49 ACTION_NOTIFY,
50 ACTION_DENOTIFY
51 } action_t;
52
53 /* information */
54 action_list_t *new_action_list(void);
55 void free_action_list(action_list_t *actions);
56
57 /* invariant: always have a dummy element when free_action_list, param
58 and vac_subj are freed. none of the others are automatically freed.
59
60 the do_action() functions should copy param */
61 struct Action {
62 action_t a;
63 union {
64 sieve_reject_context_t rej;
65 sieve_fileinto_context_t fil;
66 sieve_keep_context_t keep;
67 sieve_redirect_context_t red;
68 struct {
69 /* addr, fromaddr, subj - freed! */
70 sieve_send_response_context_t send;
71 sieve_autorespond_context_t autoresp;
72 } vac;
73 struct {
74 char *flag;
75 } fla;
76 } u;
77 char *param; /* freed! */
78 struct Action *next;
79 char *vac_subj; /* freed! */
80 char *vac_msg;
81 int vac_days;
82 };
83
84 typedef struct notify_action_s {
85
86 int exists; /* 0 = no +/-1 = yes (-1 flags default action) */
87
88 const char *priority;
89 char *message;
90 stringlist_t *headers;
91
92 } notify_action_t;
93
94 /* header parsing */
95 typedef enum {
96 ADDRESS_ALL,
97 ADDRESS_LOCALPART,
98 ADDRESS_DOMAIN,
99 ADDRESS_USER,
100 ADDRESS_DETAIL
101 } address_part_t;
102
103 int parse_address(const char *header, void **data, void **marker);
104 char *get_address(address_part_t addrpart, void **data, void **marker,
105 int canon_domain);
106 int free_address(void **data, void **marker);
107 notify_action_t *default_notify_action(void);
108
109 /* actions; return negative on failure.
110 * these don't actually perform the actions, they just add it to the
111 * action list */
112 int do_reject(action_list_t *m, char *msg);
113 int do_fileinto(action_list_t *m, char *mbox, sieve_imapflags_t *imapflags);
114 int do_forward(action_list_t *m, char *addr);
115 int do_keep(action_list_t *m, sieve_imapflags_t *imapflags);
116 int do_discard(action_list_t *m);
117 int do_vacation(action_list_t *m, char *addr, char *fromaddr,
118 char *subj, char *msg,
119 int days, int mime);
120 int do_setflag(action_list_t *m, char *flag);
121 int do_addflag(action_list_t *m, char *flag);
122 int do_removeflag(action_list_t *m, char *flag);
123 int do_mark(action_list_t *m);
124 int do_unmark(action_list_t *m);
125 int do_notify(sieve_interp_t *i,void *m, notify_action_t *notify,
126 const char *priority, char *message, stringlist_t *sl);
127 int do_denotify(notify_action_t *notify);
128
129
130 #endif
1 /* parseaddr.c -- RFC 822 address parser
2 * $Id$
3 *
4 * Copyright (c) 1998-2000 Carnegie Mellon University. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 *
18 * 3. The name "Carnegie Mellon University" must not be used to
19 * endorse or promote products derived from this software without
20 * prior written permission. For permission or any other legal
21 * details, please contact
22 * Office of Technology Transfer
23 * Carnegie Mellon University
24 * 5000 Forbes Avenue
25 * Pittsburgh, PA 15213-3890
26 * (412) 268-4387, fax: (412) 268-7395
27 * tech-transfer@andrew.cmu.edu
28 *
29 * 4. Redistributions of any form whatsoever must retain the following
30 * acknowledgment:
31 * "This product includes software developed by Computing Services
32 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
33 *
34 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
35 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
36 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
37 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
38 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
39 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
40 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
41 *
42 */
43
44 #include <config.h>
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <ctype.h>
48 #include <string.h>
49
50 #include "parseaddr.h"
51 #include "xmalloc.h"
52
53 static char parseaddr_unspecified_domain[] = "unspecified-domain";
54
55 static void parseaddr_append (struct address ***addrpp, char *name,
56 char *route, char *mailbox, char *domain,
57 char **freemep);
58 static int parseaddr_phrase (char **inp, char **phrasep, char *specials);
59 static int parseaddr_domain (char **inp, char **domainp, char **commmentp);
60 static int parseaddr_route (char **inp, char **routep);
61
62 /*
63 * Parse an address list in 's', appending address structures to
64 * the list pointed to by 'addrp'.
65 */
66 void
67 parseaddr_list(str, addrp)
68 const char *str;
69 struct address **addrp;
70 {
71 char *s;
72 int ingroup = 0;
73 char *freeme;
74 int tok = ' ';
75 char *phrase, *route, *mailbox, *domain, *comment;
76
77 /* Skip down to the tail */
78 while (*addrp) {
79 addrp = &(*addrp)->next;
80 }
81
82 s = freeme = xstrdup(str);
83
84 while (tok) {
85 tok = parseaddr_phrase(&s, &phrase, ingroup ? ",@<;" : ",@<:");
86 switch (tok) {
87 case ',':
88 case '\0':
89 case ';':
90 if (*phrase) {
91 parseaddr_append(&addrp, 0, 0, phrase, "", &freeme);
92 }
93 if (tok == ';') {
94 parseaddr_append(&addrp, 0, 0, 0, 0, &freeme);
95 ingroup = 0;
96 }
97 continue;
98
99 case ':':
100 parseaddr_append(&addrp, 0, 0, phrase, 0, &freeme);
101 ingroup++;
102 continue;
103
104 case '@':
105 tok = parseaddr_domain(&s, &domain, &comment);
106 parseaddr_append(&addrp, comment, 0, phrase, domain, &freeme);
107 continue;
108
109 case '<':
110 tok = parseaddr_phrase(&s, &mailbox, "@>");
111 if (tok == '@') {
112 route = 0;
113 if (!*mailbox) {
114 *--s = '@';
115 tok = parseaddr_route(&s, &route);
116 if (tok != ':') {
117 parseaddr_append(&addrp, phrase, route, "", "", &freeme);
118 while (tok && tok != '>') tok = *s++;
119 continue;
120 }
121 tok = parseaddr_phrase(&s, &mailbox, "@>");
122 if (tok != '@') {
123 parseaddr_append(&addrp, phrase, route, mailbox, "",
124 &freeme);
125 continue;
126 }
127 }
128 tok = parseaddr_domain(&s, &domain, 0);
129 parseaddr_append(&addrp, phrase, route, mailbox, domain,
130 &freeme);
131 while (tok && tok != '>') tok = *s++;
132 continue; /* effectively auto-inserts a comma */
133 }
134 else {
135 parseaddr_append(&addrp, phrase, 0, mailbox, "", &freeme);
136 }
137 }
138 }
139 if (ingroup) parseaddr_append(&addrp, 0, 0, 0, 0, &freeme);
140
141 if (freeme) free(freeme);
142 }
143
144 /*
145 * Free the address list 'addr'
146 */
147 void
148 parseaddr_free(addr)
149 struct address *addr;
150 {
151 struct address *next;
152
153 while (addr) {
154 if (addr->freeme) free(addr->freeme);
155 next = addr->next;
156 free((char *)addr);
157 addr = next;
158 }
159 }
160
161 /*
162 * Helper function to append a new address structure to and address list.
163 */
164 static void
165 parseaddr_append(addrpp, name, route, mailbox, domain, freemep)
166 struct address ***addrpp;
167 char *name;
168 char *route;
169 char *mailbox;
170 char *domain;
171 char **freemep;
172 {
173 struct address *newaddr;
174
175 newaddr = (struct address *)xmalloc(sizeof(struct address));
176 if (name && *name) {
177 newaddr->name = name;
178 }
179 else {
180 newaddr->name = 0;
181 }
182
183 if (route && *route) {
184 newaddr->route = route;
185 }
186 else {
187 newaddr->route = 0;
188 }
189
190 newaddr->mailbox = mailbox;
191
192 if (domain && !*domain) {
193 domain = parseaddr_unspecified_domain;
194 }
195 newaddr->domain = domain;
196
197 newaddr->next = 0;
198 newaddr->freeme = *freemep;
199 *freemep = 0;
200
201 **addrpp = newaddr;
202 *addrpp = &newaddr->next;
203 }
204
205 /* Macro to skip white space and rfc822 comments */
206
207 #define SKIPWHITESPACE(s) \
208 { \
209 int _c, _comment = 0; \
210 \
211 while ((_c = *(s))) { \
212 if (_c == '(') { \
213 _comment = 1; \
214 (s)++; \
215 while ((_comment && (_c = *(s)))) { \
216 (s)++; \
217 if (_c == '\\' && *(s)) (s)++; \
218 else if (_c == '(') _comment++; \
219 else if (_c == ')') _comment--; \
220 } \
221 (s)--; \
222 } \
223 else if (!isspace(_c)) break; \
224 (s)++; \
225 } \
226 }
227
228 /*
229 * Parse an RFC 822 "phrase", stopping at 'specials'
230 */
231 static int parseaddr_phrase(inp, phrasep, specials)
232 char **inp;
233 char **phrasep;
234 char *specials;
235 {
236 int c;
237 char *src = *inp;
238 char *dst;
239
240 SKIPWHITESPACE(src);
241
242 *phrasep = dst = src;
243
244 for (;;) {
245 c = *src++;
246 if (c == '\"') {
247 while ((c = *src)) {
248 src++;
249 if (c == '\"') break;
250 if (c == '\\') {
251 if (!(c = *src)) break;
252 src++;
253 }
254 *dst++ = c;
255 }
256 }
257 else if (isspace(c) || c == '(') {
258 src--;
259 SKIPWHITESPACE(src);
260 *dst++ = ' ';
261 }
262 else if (!c || strchr(specials, c)) {
263 if (dst > *phrasep && dst[-1] == ' ') dst--;
264 *dst = '\0';
265 *inp = src;
266 return c;
267 }
268 else {
269 *dst++ = c;
270 }
271 }
272 }
273
274 /*
275 * Parse a domain. If 'commentp' is non-nil, parses any trailing comment
276 */
277 static int parseaddr_domain(inp, domainp, commentp)
278 char **inp;
279 char **domainp;
280 char **commentp;
281 {
282 int c;
283 char *src = *inp;
284 char *dst;
285 char *cdst;
286 int comment;
287
288 if (commentp) *commentp = 0;
289 SKIPWHITESPACE(src);
290
291 *domainp = dst = src;
292
293 for (;;) {
294 c = *src++;
295 if (isalnum(c) || c == '-' || c == '[' || c == ']') {
296 *dst++ = c;
297 if (commentp) *commentp = 0;
298 }
299 else if (c == '.') {
300 if (dst > *domainp && dst[-1] != '.') *dst++ = c;
301 if (commentp) *commentp = 0;
302 }
303 else if (c == '(') {
304 if (commentp) {
305 *commentp = cdst = src;
306 comment = 1;
307 while (comment && (c = *src)) {
308 src++;
309 if (c == '(') comment++;
310 else if (c == ')') comment--;
311 else if (c == '\\' && (c = *src)) src++;
312
313 if (comment) *cdst++ = c;
314 }
315 *cdst = '\0';
316 }
317 else {
318 src--;
319 SKIPWHITESPACE(src);
320 }
321 }
322 else if (!isspace(c)) {
323 if (dst > *domainp && dst[-1] == '.') dst--;
324 *dst = '\0';
325 *inp = src;
326 return c;
327 }
328 }
329 }
330
331 /*
332 * Parse a source route (at-domain-list)
333 */
334 static int parseaddr_route(inp, routep)
335 char **inp;
336 char **routep;
337 {
338 int c;
339 char *src = *inp;
340 char *dst;
341
342 SKIPWHITESPACE(src);
343
344 *routep = dst = src;
345
346 for (;;) {
347 c = *src++;
348 if (isalnum(c) || c == '-' || c == '[' || c == ']' ||
349 c == ',' || c == '@') {
350 *dst++ = c;
351 }
352 else if (c == '.') {
353 if (dst > *routep && dst[-1] != '.') *dst++ = c;
354 }
355 else if (isspace(c) || c == '(') {
356 src--;
357 SKIPWHITESPACE(src);
358 }
359 else {
360 while (dst > *routep &&
361 (dst[-1] == '.' || dst[-1] == ',' || dst[-1] == '@')) dst--;
362 *dst = '\0';
363 *inp = src;
364 return c;
365 }
366 }
367 }
368
1 /* parseaddr.h -- RFC 822 address parser
2 $Id$
3
4 * Copyright (c) 1998-2000 Carnegie Mellon University. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 *
18 * 3. The name "Carnegie Mellon University" must not be used to
19 * endorse or promote products derived from this software without
20 * prior written permission. For permission or any other legal
21 * details, please contact
22 * Office of Technology Transfer
23 * Carnegie Mellon University
24 * 5000 Forbes Avenue
25 * Pittsburgh, PA 15213-3890
26 * (412) 268-4387, fax: (412) 268-7395
27 * tech-transfer@andrew.cmu.edu
28 *
29 * 4. Redistributions of any form whatsoever must retain the following
30 * acknowledgment:
31 * "This product includes software developed by Computing Services
32 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
33 *
34 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
35 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
36 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
37 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
38 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
39 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
40 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
41 *
42 *
43 */
44
45 #ifndef INCLUDED_PARSEADDR_H
46 #define INCLUDED_PARSEADDR_H
47
48 #ifndef P
49 #ifdef __STDC__
50 #define P(x) x
51 #else
52 #define P(x) ()
53 #endif
54 #endif
55
56 struct address {
57 char *name;
58 char *route;
59 char *mailbox;
60 char *domain;
61 struct address *next;
62 char *freeme; /* If non-nil, free */
63 };
64
65 extern void parseaddr_list P((const char *s, struct address **addrp));
66 extern void parseaddr_free P((struct address *addr));
67
68
69 #endif /* INCLUDED_PARSEADDR_H */
1 /* script.h -- script definition
2 * Larry Greenfield
3 * $Id$
4 */
5 /***********************************************************
6 Copyright 1999 by Carnegie Mellon University
7
8 All Rights Reserved
9
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
17 permission.
18
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 ******************************************************************/
27
28 #ifndef SIEVE_SCRIPT_H
29 #define SIEVE_SCRIPT_H
30
31 #include "sieve_interface.h"
32 #include "interp.h"
33 #include "tree.h"
34
35 struct sieve_script {
36 sieve_interp_t interp;
37
38 /* was a "require" done for these? */
39 struct sieve_support {
40 int fileinto : 1;
41 int reject : 1;
42 int envelope : 1;
43 int vacation : 1;
44 int imapflags : 1;
45 int notify : 1;
46 int regex : 1;
47 int subaddress: 1;
48 } support;
49
50 void *script_context;
51 commandlist_t *cmds;
52
53 int err;
54 };
55
56 /* generated by the yacc script */
57 commandlist_t *sieve_parse(sieve_script_t *interp, FILE *f);
58 int script_require(sieve_script_t *s, char *req);
59
60 #endif
1 %{
2 /* sieve.l -- sieve lexer
3 * Larry Greenfield
4 */
5 /***********************************************************
6 Copyright 1999 by Carnegie Mellon University
7
8 All Rights Reserved
9
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
17 permission.
18
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 ******************************************************************/
27
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31
32 #include <string.h> /* for strdup */
33 #include "xmalloc.h"
34
35 #include "tree.h"
36 #include "sieve-gram.h"
37
38 static int tonum(char *c);
39 static char *fixstr(char *);
40 static char *mlbuf;
41 static int mlbufsz, mlcur;
42 extern int yyerror(char *);
43 %}
44
45 %option yylineno
46 %option noyywrap
47
48 ws [ \t]+
49 ident [a-zA-Z_][a-zA-Z_0-9]*
50 CRLF (\r\n|\r|\n)
51
52 %state MULTILINE
53
54 %%
55 <MULTILINE>^\.{CRLF} { BEGIN INITIAL;
56 mlbuf[mlcur] = '\0';
57 yylval.sval = mlbuf; return STRING; }
58 <MULTILINE>^\.\. { /* dot stuffing! we want one . */ yyless(1); }
59 <MULTILINE>(.|\n) { if (mlcur == mlbufsz)
60 mlbuf = xrealloc(mlbuf, 1 + (mlbufsz+=1024));
61 mlbuf[mlcur++] = yytext[0]; }
62 <MULTILINE><<EOF>> { yyerror("unexpected end of file in string");
63 yyterminate(); }
64 <INITIAL>text:{ws}?(#.*)?{CRLF} { BEGIN MULTILINE;
65 mlcur = 0; mlbufsz = 0; mlbuf = NULL; }
66 <INITIAL>[0-9]+[KMG]? { yylval.nval = tonum(yytext); return NUMBER; }
67 <INITIAL>if return IF;
68 <INITIAL>elsif return ELSIF;
69 <INITIAL>else return ELSE;
70 <INITIAL>anyof return ANYOF;
71 <INITIAL>allof return ALLOF;
72 <INITIAL>exists return EXISTS;
73 <INITIAL>false return SFALSE;
74 <INITIAL>true return STRUE;
75 <INITIAL>address return ADDRESS;
76 <INITIAL>envelope return ENVELOPE;
77 <INITIAL>header return HEADER;
78 <INITIAL>not return NOT;
79 <INITIAL>size return SIZE;
80 <INITIAL>reject return REJCT;
81 <INITIAL>fileinto return FILEINTO;
82 <INITIAL>redirect return FORWARD;
83 <INITIAL>keep return KEEP;
84 <INITIAL>require return REQUIRE;
85 <INITIAL>stop return STOP;
86 <INITIAL>discard return DISCARD;
87 <INITIAL>setflag return SETFLAG;
88 <INITIAL>addflag return ADDFLAG;
89 <INITIAL>removeflag return REMOVEFLAG;
90 <INITIAL>mark return MARK;
91 <INITIAL>unmark return UNMARK;
92 <INITIAL>notify return NOTIFY;
93 <INITIAL>denotify return DENOTIFY;
94 <INITIAL>:low return LOW;
95 <INITIAL>:medium return MEDIUM;
96 <INITIAL>:high return HIGH;
97 <INITIAL>vacation return VACATION;
98 <INITIAL>:days return DAYS;
99 <INITIAL>:addresses return ADDRESSES;
100 <INITIAL>:subject return SUBJECT;
101 <INITIAL>:mime return MIME;
102 <INITIAL>:comparator return COMPARATOR;
103 <INITIAL>:is return IS;
104 <INITIAL>:contains return CONTAINS;
105 <INITIAL>:matches return MATCHES;
106 <INITIAL>:regex return REGEX;
107 <INITIAL>:over return OVER;
108 <INITIAL>:under return UNDER;
109 <INITIAL>:all return ALL;
110 <INITIAL>:localpart return LOCALPART;
111 <INITIAL>:domain return DOMAIN;
112 <INITIAL>:user return USER;
113 <INITIAL>:detail return DETAIL;
114 <INITIAL>\"([^"]|\\.)*\" { yylval.sval = fixstr(yytext); return STRING; }
115 <INITIAL>[ \t\n\r] ; /* ignore whitespace */
116 <INITIAL>#.* ; /* ignore comments */
117 . return yytext[0];
118
119 %%
120 static int tonum(char *c)
121 {
122 int val = atoi(c);
123 switch (c[strlen(c)-1]) {
124 case 'K': val *= (1 << 10); break;
125 case 'M': val *= (1 << 20); break;
126 case 'G': val *= (1 << 30); break;
127 default: break;
128 }
129 return val;
130 }
131
132 static char *fixstr(char *str)
133 {
134 char *r, *s = (char *) xmalloc(sizeof(char) * strlen(str));
135
136 r = s;
137 str++; /* skip open " */
138 while (*str != '"') {
139 if (*str == '\\')
140 str++;
141 *s++ = *str++;
142 }
143 *s = '\0';
144 return r;
145 }
1 /*
2 * sieve_err.c:
3 * This file is automatically generated; please do not edit it.
4 */
5 #if 0
6
7 #ifdef __STDC__
8 #define NOARGS void
9 #else
10 #define NOARGS
11 #define const
12 #endif
13
14 static const char * const text[] = {
15 "Generic Sieve error",
16 "Sieve interpretor not finalized",
17 "Parse error in Sieve script",
18 "Run-time error during Sieve execution",
19 "Internal error in Sieve subsystem",
20 "Memory exhausted in Sieve subsystem",
21 "Sieve action already taken",
22 0
23 };
24
25 struct error_table {
26 char const * const * msgs;
27 long base;
28 int n_msgs;
29 };
30 struct et_list {
31 struct et_list *next;
32 const struct error_table * table;
33 };
34 extern struct et_list *_et_list;
35
36 static const struct error_table et = { text, -1237848064L, 7 };
37
38 static struct et_list link = { 0, 0 };
39 #endif
40
41 void initialize_siev_error_table (NOARGS) {
42 #if 0
43 if (!link.table) {
44 link.next = _et_list;
45 link.table = &et;
46 _et_list = &link;
47 }
48 #endif
49 }
50
1 /*
2 * sieve_err.h:
3 * This file is automatically generated; please do not edit it.
4 */
5 #define SIEVE_FAIL (-1237848064L)
6 #define SIEVE_NOT_FINALIZED (-1237848063L)
7 #define SIEVE_PARSE_ERROR (-1237848062L)
8 #define SIEVE_RUN_ERROR (-1237848061L)
9 #define SIEVE_INTERNAL_ERROR (-1237848060L)
10 #define SIEVE_NOMEM (-1237848059L)
11 #define SIEVE_DONE (-1237848058L)
12 extern void initialize_siev_error_table ();
13 #define ERROR_TABLE_BASE_siev (-1237848064L)
14
15 /* for compatibility with older versions... */
16 #define init_siev_err_tbl initialize_siev_error_table
17 #define siev_err_base ERROR_TABLE_BASE_siev
1 /* sieve_interface.h -- interface for deliver
2 * $Id$
3 */
4 /***********************************************************
5 Copyright 1999 by Carnegie Mellon University
6
7 All Rights Reserved
8
9 Permission to use, copy, modify, and distribute this software and its
10 documentation for any purpose and without fee is hereby granted,
11 provided that the above copyright notice appear in all copies and that
12 both that copyright notice and this permission notice appear in
13 supporting documentation, and that the name of Carnegie Mellon
14 University not be used in advertising or publicity pertaining to
15 distribution of the software without specific, written prior
16 permission.
17
18 CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
19 THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
20 FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE FOR
21 ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
22 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
23 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
24 OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 ******************************************************************/
26
27 #ifndef SIEVE_H
28 #define SIEVE_H
29
30 #include <stdio.h>
31
32 extern const char *sieve_version;
33
34 /* error codes */
35 #define SIEVE_OK (0)
36
37 #include <sieve_err.h>
38
39 /* external sieve types */
40 typedef struct sieve_interp sieve_interp_t;
41 typedef struct sieve_script sieve_script_t;
42
43 typedef int sieve_callback(void *action_context, void *interp_context,
44 void *script_context,
45 void *message_context, const char **errmsg);
46 typedef int sieve_get_size(void *message_context, int *size);
47 typedef int sieve_get_header(void *message_context,
48 const char *header,
49 const char ***contents);
50 typedef int sieve_get_envelope(void *message_context,
51 const char *field,
52 const char ***contents);
53
54 typedef struct sieve_vacation {
55 int min_response; /* 0 -> defaults to 3 */
56 int max_response; /* 0 -> defaults to 90 */
57
58 /* given a hash, say whether we've already responded to it in the last
59 days days. return SIEVE_OK if we SHOULD autorespond (have not already)
60 or SIEVE_DONE if we SHOULD NOT. */
61 sieve_callback *autorespond;
62
63 /* mail the response */
64 sieve_callback *send_response;
65 } sieve_vacation_t;
66
67 typedef struct sieve_imapflags {
68 char **flag; /* NULL -> defaults to \flagged */
69 int nflags;
70 } sieve_imapflags_t;
71
72 typedef struct sieve_redirect_context {
73 char *addr;
74 } sieve_redirect_context_t;
75
76 typedef struct sieve_reject_context {
77 char *msg;
78 } sieve_reject_context_t;
79
80 typedef struct sieve_fileinto_context {
81 char *mailbox;
82 sieve_imapflags_t *imapflags;
83 } sieve_fileinto_context_t;
84
85 typedef struct sieve_keep_context {
86 sieve_imapflags_t *imapflags;
87 } sieve_keep_context_t;
88
89 typedef struct sieve_notify_context {
90 const char *priority;
91 char *message;
92 } sieve_notify_context_t;
93
94 typedef struct sieve_autorespond_context {
95 unsigned char *hash;
96 int len;
97 int days;
98 } sieve_autorespond_context_t;
99
100 typedef struct sieve_send_response_context {
101 char *addr;
102 char *fromaddr;
103 char *subj;
104 char *msg;
105 int mime;
106 } sieve_send_response_context_t;
107
108 /* build a sieve interpretor */
109 int sieve_interp_alloc(sieve_interp_t **interp, void *interp_context);
110 int sieve_interp_free(sieve_interp_t **interp);
111
112 /* add the callbacks for actions. undefined behavior results if these
113 are called after sieve_script_parse is called! */
114 int sieve_register_redirect(sieve_interp_t *interp, sieve_callback *f);
115 int sieve_register_discard(sieve_interp_t *interp, sieve_callback *f);
116 int sieve_register_reject(sieve_interp_t *interp, sieve_callback *f);
117 int sieve_register_fileinto(sieve_interp_t *interp, sieve_callback *f);
118 int sieve_register_keep(sieve_interp_t *interp, sieve_callback *f);
119 int sieve_register_vacation(sieve_interp_t *interp, sieve_vacation_t *v);
120 int sieve_register_imapflags(sieve_interp_t *interp, sieve_imapflags_t *mark);
121 int sieve_register_notify(sieve_interp_t *interp, sieve_callback *f);
122
123 /* add the callbacks for messages. again, undefined if used after
124 sieve_script_parse */
125 int sieve_register_size(sieve_interp_t *interp, sieve_get_size *f);
126 int sieve_register_header(sieve_interp_t *interp, sieve_get_header *f);
127 int sieve_register_envelope(sieve_interp_t *interp, sieve_get_envelope *f);
128
129 typedef int sieve_parse_error(int lineno, const char *msg,
130 void *interp_context,
131 void *script_context);
132 int sieve_register_parse_error(sieve_interp_t *interp, sieve_parse_error *f);
133
134 typedef int sieve_execute_error(const char *msg, void *interp_context,
135 void *script_context, void *message_context);
136 int sieve_register_execute_error(sieve_interp_t *interp,
137 sieve_execute_error *f);
138 int sieve_register_summary(sieve_interp_t *interp,
139 sieve_execute_error *f);
140
141 /* given an interpretor and a script, produce an executable script */
142 int sieve_script_parse(sieve_interp_t *interp, FILE *script,
143 void *script_context, sieve_script_t **ret);
144
145 int sieve_script_free(sieve_script_t **s);
146
147 /* execute a script on a message, producing side effects via callbacks */
148 int sieve_execute_script(sieve_script_t *script,
149 void *message_context);
150
151 /* Get space separated list of extensions supported by the implementation */
152 const char *sieve_listextensions(void);
153
154 #endif
1 /*
2 * sieve header field cache.
3 */
4
5 #ifdef HAVE_CONFIG_H
6 #include <config.h>
7 #endif
8
9 #include <ctype.h>
10 #include <errno.h>
11 #include <stdlib.h>
12 #include <string.h>
13
14 #ifdef HAVE_STRINGS_H
15 #include <strings.h>
16 #endif
17
18 #include "svfield.h"
19
20 static int
21 sv_hash_field_name (const char *name)
22 {
23 int x = 0;
24 /* all CHAR up to the first that is ' ', :, or a ctrl char */
25 for (; !iscntrl (*name) && (*name != ' ') && (*name != ':'); name++)
26 {
27 x *= 256;
28 x += tolower (*name);
29 x %= SV_FIELD_CACHE_SIZE;
30 }
31 return x;
32 }
33
34 /*
35 The body is kept, the name is still the caller's.
36 */
37 int
38 sv_field_cache_add (sv_field_cache_t * m, const char *name, char *body)
39 {
40 int cl, clinit;
41
42 /* put it in the hash table */
43 clinit = cl = sv_hash_field_name (name);
44
45 while (m->cache[cl] != NULL && strcasecmp (name, m->cache[cl]->name))
46 {
47 cl++; /* resolve collisions linearly */
48 cl %= SV_FIELD_CACHE_SIZE;
49 if (cl == clinit)
50 break; /* gone all the way around, so bail */
51 }
52
53 /* found where to put it, so insert it into a list */
54 if (m->cache[cl])
55 {
56 /* add this body on */
57
58 m->cache[cl]->contents[m->cache[cl]->ncontents++] = body;
59
60 /* whoops, won't have room for the null at the end! */
61 if (!(m->cache[cl]->ncontents % 8))
62 {
63 /* increase the size */
64 sv_field_t* field = (sv_field_t *) realloc (
65 m->cache[cl],
66 sizeof(sv_field_t) +
67 ((8 + m->cache[cl]->ncontents) * sizeof(char *))
68 );
69 if (field == NULL)
70 {
71 return ENOMEM;
72 }
73 m->cache[cl] = field;
74 }
75 }
76 else
77 {
78 /* create a new entry in the hash table */
79 sv_field_t* field = (sv_field_t *) malloc (sizeof (sv_field_t) +
80 8 * sizeof (char *));
81 if (field)
82 {
83 return ENOMEM;
84 }
85 m->cache[cl] = field;
86 m->cache[cl]->name = strdup (name);
87 m->cache[cl]->contents[0] = body;
88 m->cache[cl]->ncontents = 1;
89 }
90
91 /* we always want a NULL at the end */
92 m->cache[cl]->contents[m->cache[cl]->ncontents] = NULL;
93
94 return 0;
95 }
96
97 int
98 sv_field_cache_get (sv_field_cache_t * m,
99 const char *name, const char ***body)
100 {
101 int rc = ENOENT;
102 int clinit, cl;
103
104 clinit = cl = sv_hash_field_name (name);
105
106 while (m->cache[cl] != NULL)
107 {
108 if (strcasecmp (name, m->cache[cl]->name) == 0)
109 {
110 *body = (const char **) m->cache[cl]->contents;
111 rc = 0;
112 break;
113 }
114 cl++; /* try next hash bin */
115 cl %= SV_FIELD_CACHE_SIZE;
116 if (cl == clinit)
117 break; /* gone all the way around */
118 }
119
120 return rc;
121 }
122
123 void
124 sv_field_cache_release (sv_field_cache_t * m)
125 {
126 int i;
127 for (i = 0; i < SV_FIELD_CACHE_SIZE; i++)
128 {
129 if (m->cache[i])
130 {
131 int j;
132 for (j = 0; m->cache[i]->contents[j]; j++)
133 {
134 free (m->cache[i]->contents[j]);
135 }
136 free (m->cache[i]);
137 }
138 }
139 }
140
1 /*
2 * sieve field cache.
3 */
4
5 #ifndef SVFIELD_H
6 #define SVFIELD_H
7
8 #define SV_FIELD_CACHE_SIZE 1019
9
10 typedef struct sv_field_t
11 {
12 char *name;
13 int ncontents;
14 char *contents[1];
15 }
16 sv_field_t;
17
18 typedef struct sv_field_cache_t
19 {
20 sv_field_t *cache[SV_FIELD_CACHE_SIZE];
21 }
22 sv_field_cache_t;
23
24 extern int sv_field_cache_add (sv_field_cache_t* m, const char *name, char *body);
25 extern int sv_field_cache_get (sv_field_cache_t* m, const char *name, const char ***body);
26 extern void sv_field_cache_release (sv_field_cache_t* m);
27
28 #endif
29
1 /*
2 * Copyright (c) 2000 Carnegie Mellon University. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. The name "Carnegie Mellon University" must not be used to
17 * endorse or promote products derived from this software without
18 * prior written permission. For permission or any other legal
19 * details, please contact
20 * Office of Technology Transfer
21 * Carnegie Mellon University
22 * 5000 Forbes Avenue
23 * Pittsburgh, PA 15213-3890
24 * (412) 268-4387, fax: (412) 268-7395
25 * tech-transfer@andrew.cmu.edu
26 *
27 * 4. Redistributions of any form whatsoever must retain the following
28 * acknowledgment:
29 * "This product includes software developed by Computing Services
30 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
31 *
32 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
33 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
34 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
35 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
36 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
37 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
38 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
39 *
40 */
41
42
43
44 /*
45 * Copyright (c) 1987, 1993
46 * The Regents of the University of California. All rights reserved.
47 *
48 * Redistribution and use in source and binary forms, with or without
49 * modification, are permitted provided that the following conditions
50 * are met:
51 * 1. Redistributions of source code must retain the above copyright
52 * notice, this list of conditions and the following disclaimer.
53 * 2. Redistributions in binary form must reproduce the above copyright
54 * notice, this list of conditions and the following disclaimer in the
55 * documentation and/or other materials provided with the distribution.
56 * 3. All advertising materials mentioning features or use of this software
57 * must display the following acknowledgement:
58 * This product includes software developed by the University of
59 * California, Berkeley and its contributors.
60 * 4. Neither the name of the University nor the names of its contributors
61 * may be used to endorse or promote products derived from this software
62 * without specific prior written permission.
63 *
64 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
65 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
66 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
67 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
68 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
69 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
70 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
71 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
72 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
73 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
74 * SUCH DAMAGE.
75 *
76 * @(#)sysexits.h 8.1 (Berkeley) 6/2/93
77 */
78
79 #ifndef _SYSEXITS_H_
80 #define _SYSEXITS_H_
81
82 /*
83 * SYSEXITS.H -- Exit status codes for system programs.
84 *
85 * This include file attempts to categorize possible error
86 * exit statuses for system programs, notably delivermail
87 * and the Berkeley network.
88 *
89 * Error numbers begin at EX__BASE to reduce the possibility of
90 * clashing with other exit statuses that random programs may
91 * already return. The meaning of the codes is approximately
92 * as follows:
93 *
94 * EX_USAGE -- The command was used incorrectly, e.g., with
95 * the wrong number of arguments, a bad flag, a bad
96 * syntax in a parameter, or whatever.
97 * EX_DATAERR -- The input data was incorrect in some way.
98 * This should only be used for user's data & not
99 * system files.
100 * EX_NOINPUT -- An input file (not a system file) did not
101 * exist or was not readable. This could also include
102 * errors like "No message" to a mailer (if it cared
103 * to catch it).
104 * EX_NOUSER -- The user specified did not exist. This might
105 * be used for mail addresses or remote logins.
106 * EX_NOHOST -- The host specified did not exist. This is used
107 * in mail addresses or network requests.
108 * EX_UNAVAILABLE -- A service is unavailable. This can occur
109 * if a support program or file does not exist. This
110 * can also be used as a catchall message when something
111 * you wanted to do doesn't work, but you don't know
112 * why.
113 * EX_SOFTWARE -- An internal software error has been detected.
114 * This should be limited to non-operating system related
115 * errors as possible.
116 * EX_OSERR -- An operating system error has been detected.
117 * This is intended to be used for such things as "cannot
118 * fork", "cannot create pipe", or the like. It includes
119 * things like getuid returning a user that does not
120 * exist in the passwd file.
121 * EX_OSFILE -- Some system file (e.g., /etc/passwd, /etc/utmp,
122 * etc.) does not exist, cannot be opened, or has some
123 * sort of error (e.g., syntax error).
124 * EX_CANTCREAT -- A (user specified) output file cannot be
125 * created.
126 * EX_IOERR -- An error occurred while doing I/O on some file.
127 * EX_TEMPFAIL -- temporary failure, indicating something that
128 * is not really an error. In sendmail, this means
129 * that a mailer (e.g.) could not create a connection,
130 * and the request should be reattempted later.
131 * EX_PROTOCOL -- the remote system returned something that
132 * was "not possible" during a protocol exchange.
133 * EX_NOPERM -- You did not have sufficient permission to
134 * perform the operation. This is not intended for
135 * file system problems, which should use NOINPUT or
136 * CANTCREAT, but rather for higher level permissions.
137 */
138
139 #define EX_OK 0 /* successful termination */
140
141 #define EX__BASE 64 /* base value for error messages */
142
143 #define EX_USAGE 64 /* command line usage error */
144 #define EX_DATAERR 65 /* data format error */
145 #define EX_NOINPUT 66 /* cannot open input */
146 #define EX_NOUSER 67 /* addressee unknown */
147 #define EX_NOHOST 68 /* host name unknown */
148 #define EX_UNAVAILABLE 69 /* service unavailable */
149 #define EX_SOFTWARE 70 /* internal software error */
150 #define EX_OSERR 71 /* system error (e.g., can't fork) */
151 #define EX_OSFILE 72 /* critical OS file missing */
152 #define EX_CANTCREAT 73 /* can't create (user) output file */
153 #define EX_IOERR 74 /* input/output error */
154 #define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */
155 #define EX_PROTOCOL 76 /* remote error in protocol */
156 #define EX_NOPERM 77 /* permission denied */
157 #define EX_CONFIG 78 /* configuration error */
158
159 #define EX__MAX 78 /* maximum listed value */
160
161 #endif /* !_SYSEXITS_H_ */
This diff is collapsed. Click to expand it.
1 /* tree.c -- abstract syntax tree handling
2 * Larry Greenfield
3 * $Id$
4 */
5 /***********************************************************
6 Copyright 1999 by Carnegie Mellon University
7
8 All Rights Reserved
9
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
17 permission.
18
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 ******************************************************************/
27
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31
32 #include <stdlib.h>
33 #include "xmalloc.h"
34
35 #include "tree.h"
36 #include "sieve-gram.h"
37
38 stringlist_t *new_sl(char *s, stringlist_t *n)
39 {
40 stringlist_t *p = (stringlist_t *) xmalloc(sizeof(stringlist_t));
41 p->s = s;
42 p->next = n;
43 return p;
44 }
45
46 patternlist_t *new_pl(void *pat, patternlist_t *n)
47 {
48 patternlist_t *p = (patternlist_t *) xmalloc(sizeof(patternlist_t));
49 p->p = pat;
50 p->next = n;
51 return p;
52 }
53
54 tag_t *new_tag(int type, char *s)
55 {
56 tag_t *p = (tag_t *) xmalloc(sizeof(tag_t));
57 p->type = type;
58 p->arg = s;
59 return p;
60 }
61
62 taglist_t *new_taglist(tag_t *t, taglist_t *n)
63 {
64 taglist_t *p = (taglist_t *) xmalloc(sizeof(taglist_t));
65 p->t = t;
66 p->next = n;
67 return p;
68 }
69
70 test_t *new_test(int type)
71 {
72 test_t *p = (test_t *) xmalloc(sizeof(test_t));
73 p->type = type;
74 return p;
75 }
76
77 testlist_t *new_testlist(test_t *t, testlist_t *n)
78 {
79 testlist_t *p = (testlist_t *) xmalloc(sizeof(testlist_t));
80 p->t = t;
81 p->next = n;
82 return p;
83 }
84
85 commandlist_t *new_command(int type)
86 {
87 commandlist_t *p = (commandlist_t *) xmalloc(sizeof(commandlist_t));
88 p->type = type;
89 p->next = NULL;
90 return p;
91 }
92
93 commandlist_t *new_if(test_t *t, commandlist_t *y, commandlist_t *n)
94 {
95 commandlist_t *p = (commandlist_t *) xmalloc(sizeof(commandlist_t));
96 p->type = IF;
97 p->u.i.t = t;
98 p->u.i.do_then = y;
99 p->u.i.do_else = n;
100 p->next = NULL;
101 return p;
102 }
103
104 void free_sl(stringlist_t *sl)
105 {
106 stringlist_t *sl2;
107
108 while (sl != NULL) {
109 sl2 = sl->next;
110
111 if (sl->s) free(sl->s);
112
113 free(sl);
114 sl = sl2;
115 }
116 }
117
118 void free_pl(patternlist_t *pl, int comptag)
119 {
120 patternlist_t *pl2;
121
122 while (pl != NULL) {
123 pl2 = pl->next;
124
125 if (pl->p) {
126 #ifdef ENABLE_REGEX
127 if (comptag == REGEX) {
128 regfree((regex_t *) pl->p);
129 }
130 #endif
131 free(pl->p);
132 }
133
134 free(pl);
135 pl = pl2;
136 }
137 }
138
139 void free_test(test_t *t);
140
141 void free_tl(testlist_t *tl)
142 {
143 testlist_t *tl2;
144
145 while (tl) {
146 tl2 = tl->next;
147
148 if (tl->t) free_test(tl->t);
149
150 free(tl);
151 tl = tl2;
152 }
153 }
154
155 void free_test(test_t *t)
156 {
157 if (t == NULL) return;
158
159 switch (t->type) {
160 case ANYOF:
161 case ALLOF:
162 free_tl(t->u.tl);
163 break;
164
165 case EXISTS:
166 free_sl(t->u.sl);
167 break;
168
169 case SIZE:
170 case SFALSE:
171 case STRUE:
172 break;
173
174 case HEADER:
175 free_sl(t->u.h.sl);
176 free_pl(t->u.h.pl, t->u.h.comptag);
177 break;
178
179 case ADDRESS:
180 free_sl(t->u.ae.sl);
181 free_pl(t->u.ae.pl, t->u.ae.comptag);
182 break;
183
184 case NOT:
185 free_test(t->u.t);
186 break;
187 }
188
189 free(t);
190 }
191
192 void free_tree(commandlist_t *cl)
193 {
194 commandlist_t *cl2;
195
196 while (cl != NULL) {
197 cl2 = cl->next;
198 switch (cl->type) {
199 case IF:
200 free_test(cl->u.i.t);
201 free_tree(cl->u.i.do_then);
202 free_tree(cl->u.i.do_else);
203 break;
204
205 case REJCT:
206 if (cl->u.str) free(cl->u.str);
207 break;
208
209 case VACATION:
210 if (cl->u.v.subject) free(cl->u.v.subject);
211 if (cl->u.v.addresses) free_sl(cl->u.v.addresses);
212 if (cl->u.v.message) free(cl->u.v.message);
213 break;
214
215 case FILEINTO:
216 case FORWARD:
217 case SETFLAG:
218 case ADDFLAG:
219 case REMOVEFLAG:
220 free_sl(cl->u.sl);
221 break;
222
223 case KEEP:
224 case STOP:
225 case DISCARD:
226 break;
227 }
228
229 free(cl);
230 cl = cl2;
231 }
232 }
1 /* tree.h -- abstract syntax tree
2 * Larry Greenfield
3 * $Id$
4 */
5 /***********************************************************
6 Copyright 1999 by Carnegie Mellon University
7
8 All Rights Reserved
9
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
17 permission.
18
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 ******************************************************************/
27
28 #ifndef TREE_H
29 #define TREE_H
30
31 #include "comparator.h"
32
33 /* abstract syntax tree for sieve */
34 typedef struct Stringlist stringlist_t;
35 typedef struct Patternlist patternlist_t;
36 typedef struct Commandlist commandlist_t;
37 typedef struct Test test_t;
38 typedef struct Testlist testlist_t;
39 typedef struct Tag tag_t;
40 typedef struct Taglist taglist_t;
41
42 struct Stringlist {
43 char *s;
44 stringlist_t *next;
45 };
46
47 struct Patternlist {
48 void *p;
49 patternlist_t *next;
50 };
51
52 struct Tag {
53 int type;
54 char *arg;
55 };
56
57 struct Taglist {
58 tag_t *t;
59 taglist_t *next;
60 };
61
62 struct Test {
63 int type;
64 union {
65 testlist_t *tl; /* anyof, allof */
66 stringlist_t *sl; /* exists */
67 struct { /* it's a header test */
68 int comptag;
69 comparator_t *comp;
70 stringlist_t *sl;
71 patternlist_t *pl;
72 } h;
73 struct { /* it's an address or envelope test */
74 int comptag;
75 comparator_t *comp;
76 stringlist_t *sl;
77 patternlist_t *pl;
78 int addrpart;
79 } ae;
80 test_t *t; /* not */
81 struct { /* size */
82 int t; /* tag */
83 int n; /* param */
84 } sz;
85 } u;
86 };
87
88 struct Testlist {
89 test_t *t;
90 testlist_t *next;
91 };
92
93 struct Commandlist {
94 int type;
95 union {
96 char *str;
97 stringlist_t *sl; /* the parameters */
98 struct { /* it's an if statement */
99 test_t *t;
100 commandlist_t *do_then;
101 commandlist_t *do_else;
102 } i;
103 struct { /* it's a vacation action */
104 char *subject;
105 int days;
106 stringlist_t *addresses;
107 char *message;
108 int mime;
109 } v;
110 struct { /* it's a notify action */
111 char *priority;
112 char *message;
113 stringlist_t *headers_list;
114 } n;
115 } u;
116 struct Commandlist *next;
117 };
118
119 stringlist_t *new_sl(char *s, stringlist_t *n);
120 tag_t *new_tag(int type, char *s);
121 taglist_t *new_taglist(tag_t *t, taglist_t *n);
122 test_t *new_test(int type);
123 testlist_t *new_testlist(test_t *t, testlist_t *n);
124 commandlist_t *new_command(int type);
125 commandlist_t *new_if(test_t *t, commandlist_t *y, commandlist_t *n);
126
127 void free_sl(stringlist_t *sl);
128 void free_test(test_t *t);
129 void free_tree(commandlist_t *cl);
130
131 #endif
1 /* util.c -- general utility functions
2 *
3 * Copyright (c) 1998-2000 Carnegie Mellon University. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. The name "Carnegie Mellon University" must not be used to
18 * endorse or promote products derived from this software without
19 * prior written permission. For permission or any other legal
20 * details, please contact
21 * Office of Technology Transfer
22 * Carnegie Mellon University
23 * 5000 Forbes Avenue
24 * Pittsburgh, PA 15213-3890
25 * (412) 268-4387, fax: (412) 268-7395
26 * tech-transfer@andrew.cmu.edu
27 *
28 * 4. Redistributions of any form whatsoever must retain the following
29 * acknowledgment:
30 * "This product includes software developed by Computing Services
31 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
32 *
33 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
34 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
35 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
36 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
37 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
38 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
39 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
40 *
41 * Author: Chris Newman
42 * Start Date: 4/6/93
43 */
44 /* $Id$
45 */
46
47 #include <config.h>
48 #include <stdio.h>
49 #include <ctype.h>
50 #include <string.h>
51 #include "util.h"
52
53 /* from OS: */
54 extern char *malloc(), *realloc();
55
56 #define BEAUTYBUFSIZE 4096
57
58 const unsigned char convert_to_lowercase[256] = {
59 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
60 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
61 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
62 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
63 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
64 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
65 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
66 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
67 0x40, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
68 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
69 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
70 'x', 'y', 'z', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
71 0x60, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
72 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
73 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
74 'x', 'y', 'z', 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
75 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
76 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
77 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
78 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
79 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
80 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
81 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
82 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
83 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
84 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
85 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
86 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
87 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
88 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
89 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
90 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
91 };
92
93 const unsigned char convert_to_uppercase[256] = {
94 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
95 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
96 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
97 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
98 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
99 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
100 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
101 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
102 0x40, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
103 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
104 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
105 'X', 'Y', 'Z', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
106 0x60, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
107 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
108 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
109 'X', 'Y', 'Z', 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
110 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
111 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
112 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
113 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
114 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
115 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
116 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
117 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
118 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
119 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
120 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
121 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
122 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
123 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
124 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
125 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
126 };
127
128 /* convert string to all lower case
129 */
130 char *lcase(char* str)
131 {
132 char *scan = str;
133
134 while (*scan) {
135 *scan = TOLOWER(*scan);
136 scan++;
137 }
138
139 return (str);
140 }
141
142 /* convert string to all upper case
143 */
144 char *ucase(char* str)
145 {
146 char *scan = str;
147
148 while (*scan) {
149 *scan = convert_to_uppercase[(unsigned char)(*scan)];
150 scan++;
151 }
152
153 return (str);
154 }
155
156 /* clean up control characters in a string while copying it
157 * returns pointer to end of dst string.
158 * dst must have twice the length of source
159 */
160 char *beautify_copy(char* dst, const char* src)
161 {
162 unsigned char c;
163
164 while (*src) {
165 c = *src++ & 0x7F;
166 if (!isprint(c)) {
167 *dst++ = '^';
168 if (c > ' ') {
169 c = '?';
170 } else {
171 c += '@';
172 }
173 }
174 *dst++ = c;
175 }
176 *dst = '\0';
177
178 return (dst);
179 }
180
181
182 /* clean up control characters in a string while copying it
183 * returns pointer to a static buffer containing the cleaned-up version
184 * returns NULL on malloc() error
185 */
186 char *beautify_string(const char* src)
187 {
188 static char *beautybuf = NULL;
189 static int beautysize = 0;
190 int len;
191
192 len = strlen(src) * 2 + 1;
193 if (beautysize < len) {
194 if (!beautysize) {
195 beautysize = len > BEAUTYBUFSIZE ? len : BEAUTYBUFSIZE;
196 beautybuf = malloc(beautysize);
197 } else {
198 beautysize *= 2;
199 if (len > beautysize) beautysize = len;
200 beautybuf = realloc(beautybuf, beautysize);
201 }
202 if (!beautybuf) {
203 beautysize = 0;
204 return "";
205 }
206 }
207 (void) beautify_copy(beautybuf, src);
208
209 return (beautybuf);
210 }
211
212 /* do a binary search in a keyvalue array
213 * nelem is the number of keyvalue elements in the kv array
214 * cmpf is the comparison function (strcmp, strcasecmp, etc).
215 * returns NULL if not found, or key/value pair if found.
216 */
217 keyvalue *kv_bsearch(const char* key, keyvalue* kv, int nelem,
218 int (*cmpf) (const char *s1, const char *s2))
219 {
220 int top, mid = 0, bot, cmp = 0;
221
222 cmp = 1;
223 bot = 0;
224 top = nelem - 1;
225 while (top >= bot && (cmp = (*cmpf)(key, kv[mid = (bot + top) >> 1].key)))
226 if (cmp < 0) {
227 top = mid - 1;
228 } else {
229 bot = mid + 1;
230 }
231
232 return (cmp ? NULL : kv + mid);
233 }
1 /* util.h -- general utility functions
2 * $Id$
3 *
4 * Copyright (c) 1999-2000 Carnegie Mellon University. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 *
18 * 3. The name "Carnegie Mellon University" must not be used to
19 * endorse or promote products derived from this software without
20 * prior written permission. For permission or any other legal
21 * details, please contact
22 * Office of Technology Transfer
23 * Carnegie Mellon University
24 * 5000 Forbes Avenue
25 * Pittsburgh, PA 15213-3890
26 * (412) 268-4387, fax: (412) 268-7395
27 * tech-transfer@andrew.cmu.edu
28 *
29 * 4. Redistributions of any form whatsoever must retain the following
30 * acknowledgment:
31 * "This product includes software developed by Computing Services
32 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
33 *
34 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
35 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
36 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
37 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
38 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
39 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
40 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
41 *
42 * Author: Chris Newman
43 * Start Date: 4/6/93
44 */
45
46 #ifndef INCLUDED_UTIL_H
47 #define INCLUDED_UTIL_H
48
49 extern const unsigned char convert_to_lowercase[256];
50 extern const unsigned char convert_to_uppercase[256];
51
52 #define TOUPPER(c) (convert_to_uppercase[(unsigned char)(c)])
53 #define TOLOWER(c) (convert_to_lowercase[(unsigned char)(c)])
54
55 typedef struct keyvalue {
56 char *key, *value;
57 } keyvalue;
58
59 /* convert string to all lower case
60 */
61 extern char *lcase (char *str);
62
63 /* convert string to all upper case
64 */
65 extern char *ucase (char *str);
66
67 /* clean up control characters in a string while copying it
68 * returns pointer to end of dst string.
69 * dst must have twice the length of source
70 */
71 extern char *beautify_copy (char *dst, const char *src);
72
73 /* clean up control characters in a string while copying it
74 * returns pointer to a static buffer containing the cleaned-up version
75 * returns NULL on malloc() error
76 */
77 extern char *beautify_string (const char *src);
78
79 /* do a binary search in a keyvalue array
80 * nelem is the number of keyvalue elements in the kv array
81 * cmpf is the comparison function (strcmp, stricmp, etc).
82 * returns NULL if not found, or key/value pair if found.
83 */
84 extern keyvalue *kv_bsearch (const char *key, keyvalue *kv, int nelem,
85 int (*cmpf)(const char *s1, const char *s2));
86
87 #endif /* INCLUDED_UTIL_H */
1 /* xmalloc.c -- Allocation package that calls fatal() when out of memory
2 *
3 * Copyright (c) 1998-2000 Carnegie Mellon University. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. The name "Carnegie Mellon University" must not be used to
18 * endorse or promote products derived from this software without
19 * prior written permission. For permission or any other legal
20 * details, please contact
21 * Office of Technology Transfer
22 * Carnegie Mellon University
23 * 5000 Forbes Avenue
24 * Pittsburgh, PA 15213-3890
25 * (412) 268-4387, fax: (412) 268-7395
26 * tech-transfer@andrew.cmu.edu
27 *
28 * 4. Redistributions of any form whatsoever must retain the following
29 * acknowledgment:
30 * "This product includes software developed by Computing Services
31 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
32 *
33 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
34 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
35 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
36 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
37 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
38 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
39 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
40 */
41 /*
42 * $Id$
43 */
44 #include <config.h>
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #include "xmalloc.h"
49
50 #include "exitcodes.h"
51
52 void* xmalloc(unsigned size)
53 {
54 void *ret;
55
56 ret = malloc(size);
57 if (ret != NULL) return ret;
58
59 fatal("Virtual memory exhausted", EC_TEMPFAIL);
60 return 0; /*NOTREACHED*/
61 }
62
63 void* xzmalloc(unsigned size)
64 {
65 void *ret;
66
67 ret = malloc(size);
68 if (ret != NULL) {
69 memset(ret, 0, size);
70 return ret;
71 }
72
73 fatal("Virtual memory exhausted", EC_TEMPFAIL);
74 return 0; /*NOTREACHED*/
75 }
76
77 void *xrealloc (void* ptr, unsigned size)
78 {
79 void *ret;
80
81 /* xrealloc (NULL, size) behaves like xmalloc (size), as in ANSI C */
82 ret = (!ptr ? malloc (size) : realloc (ptr, size));
83 if (ret != NULL) return ret;
84
85 fatal("Virtual memory exhausted", EC_TEMPFAIL);
86 return 0; /*NOTREACHED*/
87 }
88
89 char *xstrdup(const char* str)
90 {
91 char *p = xmalloc(strlen(str)+1);
92 strcpy(p, str);
93 return p;
94 }
95
96 char *xstrndup(const char* str, unsigned len)
97 {
98 char *p = xmalloc(len+1);
99 strncpy(p, str, len);
100 p[len] = '\0';
101 return p;
102 }
103
104 /* Same as xmalloc() */
105 void *fs_get(unsigned size)
106 {
107 void *ret;
108
109 if ((ret = malloc(size)) != NULL)
110 return (void *)ret;
111
112 fatal("Virtual memory exhausted", EC_TEMPFAIL);
113 }
114
115 void fs_give(void** ptr)
116 {
117 free((void *)*ptr);
118 *ptr = 0;
119 }
120
121 #ifndef HAVE_STRLCPY
122 /* strlcpy -- copy string smartly.
123 *
124 * i believe/hope this is compatible with the BSD strlcpy().
125 */
126 size_t strlcpy(char *dst, const char *src, size_t len)
127 {
128 size_t n;
129
130 if (len <= 0) return strlen(src);
131 for (n = 0; n < len; n++) {
132 if ((dst[n] = src[n]) == '\0') break;
133 }
134 if (src[n] == '\0') {
135 /* copied entire string */
136 return n;
137 } else {
138 dst[n] = '\0';
139 /* ran out of space */
140 return n + strlen(src + n);
141 }
142 }
143 #endif
144
145 #ifndef HAVE_STRLCAT
146 size_t strlcat(char *dst, const char *src, size_t len)
147 {
148 size_t i, j, o;
149
150 o = strlen(dst);
151 if (len < o + 1)
152 return o + strlen(src);
153 len -= o + 1;
154 for (i = 0, j = o; i < len; i++, j++) {
155 if ((dst[j] = src[i]) == '\0') break;
156 }
157 dst[j] = '\0';
158 if (src[i] == '\0') {
159 return j;
160 } else {
161 return j + strlen(src + i);
162 }
163 }
164 #endif
1 /* xmalloc.h -- Allocation package that calls fatal() when out of memory
2 * $Id$
3 *
4 * Copyright (c) 1998-2000 Carnegie Mellon University. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 *
18 * 3. The name "Carnegie Mellon University" must not be used to
19 * endorse or promote products derived from this software without
20 * prior written permission. For permission or any other legal
21 * details, please contact
22 * Office of Technology Transfer
23 * Carnegie Mellon University
24 * 5000 Forbes Avenue
25 * Pittsburgh, PA 15213-3890
26 * (412) 268-4387, fax: (412) 268-7395
27 * tech-transfer@andrew.cmu.edu
28 *
29 * 4. Redistributions of any form whatsoever must retain the following
30 * acknowledgment:
31 * "This product includes software developed by Computing Services
32 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
33 *
34 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
35 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
36 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
37 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
38 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
39 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
40 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
41 *
42 */
43
44 #ifndef INCLUDED_XMALLOC_H
45 #define INCLUDED_XMALLOC_H
46
47 /* for size_t */
48 #include <stdio.h>
49
50 extern void *xmalloc (unsigned size);
51 extern void *xzmalloc (unsigned size);
52 extern void *xrealloc (void *ptr, unsigned size);
53 extern char *xstrdup (const char *str);
54 extern char *xstrndup (const char *str, unsigned len);
55 extern void *fs_get (unsigned size);
56 extern void fs_give (void **ptr);
57
58 /* handy string manipulation functions */
59 #ifndef HAVE_STRLCPY
60 extern size_t strlcpy(char *dst, const char *src, size_t len);
61 #endif
62 #ifndef HAVE_STRLCAT
63 extern size_t strlcat(char *dst, const char *src, size_t len);
64 #endif
65
66 /* Functions using xmalloc.h must provide a function called fatal() conforming
67 to the following: */
68 extern void fatal(const char *fatal_message, int fatal_code)
69 __attribute__ ((noreturn));
70
71 #endif /* INCLUDED_XMALLOC_H */