New sieve extension test.
Showing
1 changed file
with
211 additions
and
0 deletions
examples/list.c
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 2003 Free Software Foundation, Inc. | ||
3 | |||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU Lesser General Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | GNU Mailutils is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU Lesser General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU Lesser General Public License | ||
15 | along with GNU Mailutils; if not, write to the Free Software | ||
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ | ||
17 | |||
18 | /* Implements "list" sieve extension test. See "Syntax:" below for the | ||
19 | description */ | ||
20 | |||
21 | #ifdef HAVE_CONFIG_H | ||
22 | # include <config.h> | ||
23 | #endif | ||
24 | |||
25 | #include <unistd.h> | ||
26 | #include <stdlib.h> | ||
27 | #include <string.h> | ||
28 | #include <mailutils/libsieve.h> | ||
29 | |||
30 | |||
31 | |||
32 | /* Auxiliary functions */ | ||
33 | struct header_closure { | ||
34 | header_t header; /* Message header */ | ||
35 | int index; /* Header index */ | ||
36 | char *delim; /* List delimiter */ | ||
37 | char *value; /* Retrieved header value */ | ||
38 | char *save; /* Save pointer for strtok_r */ | ||
39 | }; | ||
40 | |||
41 | static void | ||
42 | cleanup (struct header_closure *hc) | ||
43 | { | ||
44 | free (hc->value); | ||
45 | hc->value = hc->save = NULL; | ||
46 | } | ||
47 | |||
48 | static int | ||
49 | retrieve_next_header (struct header_closure *hc, char *name, char **pval) | ||
50 | { | ||
51 | char buf[512]; | ||
52 | size_t n; | ||
53 | |||
54 | cleanup (hc); | ||
55 | while (!header_get_field_name (hc->header, hc->index, buf, sizeof(buf), &n)) | ||
56 | { | ||
57 | int i = hc->index++; | ||
58 | if (strcasecmp (buf, name) == 0) | ||
59 | { | ||
60 | if (header_aget_field_value (hc->header, i, &hc->value)) | ||
61 | return 1; | ||
62 | *pval = strtok_r (hc->value, hc->delim, &hc->save); | ||
63 | if (*pval == NULL) | ||
64 | { | ||
65 | cleanup (hc); | ||
66 | return 1; | ||
67 | } | ||
68 | return 0; | ||
69 | } | ||
70 | } | ||
71 | |||
72 | return 1; | ||
73 | } | ||
74 | |||
75 | static int | ||
76 | list_retrieve_header (void *item, void *data, int idx, char **pval) | ||
77 | { | ||
78 | struct header_closure *hc = data; | ||
79 | char *p; | ||
80 | |||
81 | if (idx == 0) | ||
82 | hc->index = 1; | ||
83 | |||
84 | while (1) | ||
85 | { | ||
86 | if (!hc->value) | ||
87 | { | ||
88 | if (retrieve_next_header (hc, (char*) item, &p)) | ||
89 | return 1; | ||
90 | } | ||
91 | else | ||
92 | { | ||
93 | p = strtok_r (NULL, hc->delim, &hc->save); | ||
94 | if (!p) | ||
95 | { | ||
96 | cleanup (hc); | ||
97 | continue; | ||
98 | } | ||
99 | } | ||
100 | |||
101 | *pval = strdup (p); | ||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | return 1; | ||
106 | } | ||
107 | |||
108 | static int | ||
109 | waitdebug() | ||
110 | { | ||
111 | static volatile int _st=0; | ||
112 | while (!_st) | ||
113 | _st=_st; | ||
114 | } | ||
115 | |||
116 | |||
117 | /* The test proper */ | ||
118 | |||
119 | /* Syntax: list [COMPARATOR] [MATCH-TYPE] | ||
120 | [ :delim <delimiters: string> ] | ||
121 | <headers: string-list> <key-list: string-list> | ||
122 | |||
123 | The "list" test evaluates to true if any of the headers | ||
124 | match any key. Each header is regarded as containing a | ||
125 | list of keywords. By default, comma is assumed as list | ||
126 | separator. This can be overridden by specifying ":delim" | ||
127 | tag, whose value is a string consisting of valid list | ||
128 | delimiter characters. | ||
129 | |||
130 | list :matches :delim " ," [ "X-Spam-Keywords", "X-Spamd-Keywords" ] | ||
131 | [ "HTML_*", "FORGED_*" ] | ||
132 | |||
133 | |||
134 | */ | ||
135 | |||
136 | static int | ||
137 | list_test (sieve_machine_t mach, list_t args, list_t tags) | ||
138 | { | ||
139 | sieve_value_t *h, *v, *arg; | ||
140 | sieve_comparator_t comp = sieve_get_comparator (mach, tags); | ||
141 | struct header_closure clos; | ||
142 | int result; | ||
143 | |||
144 | memset (&clos, 0, sizeof clos); | ||
145 | if (sieve_tag_lookup (tags, "delim", &arg)) | ||
146 | clos.delim = arg->v.string; | ||
147 | else | ||
148 | clos.delim = ","; | ||
149 | |||
150 | h = sieve_value_get (args, 0); | ||
151 | if (!h) | ||
152 | { | ||
153 | sieve_error (mach, _("list: can't get argument 1")); | ||
154 | sieve_abort (mach); | ||
155 | } | ||
156 | v = sieve_value_get (args, 1); | ||
157 | if (!v) | ||
158 | { | ||
159 | sieve_error (mach, _("list: can't get argument 2")); | ||
160 | sieve_abort (mach); | ||
161 | } | ||
162 | |||
163 | message_get_header (sieve_get_message (mach), &clos.header); | ||
164 | result = sieve_vlist_compare (h, v, comp, sieve_get_relcmp (mach, tags), | ||
165 | list_retrieve_header, | ||
166 | &clos, NULL) > 0; | ||
167 | cleanup (&clos); | ||
168 | return result; | ||
169 | } | ||
170 | |||
171 | |||
172 | /* Initialization */ | ||
173 | |||
174 | /* Required arguments: */ | ||
175 | static sieve_data_type list_req_args[] = { | ||
176 | SVT_STRING_LIST, | ||
177 | SVT_STRING_LIST, | ||
178 | SVT_VOID | ||
179 | }; | ||
180 | |||
181 | static sieve_tag_def_t match_part_tags[] = { | ||
182 | { "is", SVT_VOID }, | ||
183 | { "contains", SVT_VOID }, | ||
184 | { "matches", SVT_VOID }, | ||
185 | { "regex", SVT_VOID }, | ||
186 | { "count", SVT_STRING }, | ||
187 | { "value", SVT_STRING }, | ||
188 | { "comparator", SVT_STRING }, | ||
189 | { NULL } | ||
190 | }; | ||
191 | |||
192 | static sieve_tag_def_t delim_part_tags[] = { | ||
193 | { "delim", SVT_STRING }, | ||
194 | { NULL } | ||
195 | }; | ||
196 | |||
197 | static sieve_tag_group_t list_tag_groups[] = { | ||
198 | { match_part_tags, sieve_match_part_checker }, | ||
199 | { delim_part_tags, NULL }, | ||
200 | { NULL } | ||
201 | }; | ||
202 | |||
203 | /* Initialization function. */ | ||
204 | int | ||
205 | SIEVE_EXPORT(list,init) (sieve_machine_t mach) | ||
206 | { | ||
207 | return sieve_register_test (mach, "list", list_test, | ||
208 | list_req_args, list_tag_groups, 1); | ||
209 | } | ||
210 | |||
211 | /* End of list.c */ |
-
Please register or sign in to post a comment