Commit 7059a1d6 7059a1d632daf2e19e0967f8cf65e682ab1d0869 by Sergey Poznyakoff

Sample loadable extension for sieve.

1 parent 61ad6f45
1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3
4 This program 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 This program 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 this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18 /* This is an example on how to write extension tests for GNU sieve.
19 It provides test "numaddr".
20
21 Syntax: numaddr [":over" / ":under"] <header-names: string-list>
22 <limit: number>
23
24 The "numaddr" test counts Internet addresses in structured headers
25 that contain addresses. It returns true if the total number of
26 addresses satisfies the requested relation:
27
28 If the argument is ":over" and the number of addresses is greater than
29 the number provided, the test is true; otherwise, it is false.
30
31 If the argument is ":under" and the number of addresses is less than
32 the number provided, the test is true; otherwise, it is false.
33
34 If the argument is empty, ":over" is assumed. */
35
36 #ifdef HAVE_CONFIG_H
37 # include <config.h>
38 #endif
39
40 #include <stdlib.h>
41 #include <mailutils/libsieve.h>
42
43 struct val_ctr {
44 header_t hdr;
45 size_t limit;
46 size_t count;
47 };
48
49 static int
50 _count_items (void *item, void *data)
51 {
52 char *name = item;
53 struct val_ctr *vp = data;
54 char *val;
55 address_t addr;
56 size_t count = 0;
57
58 if (header_aget_value (vp->hdr, name, &val))
59 return 0;
60 if (address_create (&addr, val) == 0)
61 {
62 address_get_count (addr, &count);
63 address_destroy (&addr);
64 vp->count += count;
65 }
66 free (val);
67 return vp->count >= vp->limit;
68 }
69
70 static int
71 numaddr_test (sieve_machine_t mach, list_t args, list_t tags)
72 {
73 sieve_value_t *h, *v;
74 struct val_ctr vc;
75 int rc;
76
77 if (sieve_get_debug_level (mach) & MU_SIEVE_DEBUG_TRACE)
78 sieve_debug (mach, "NUMADDR\n");
79
80 h = sieve_value_get (args, 0);
81 if (!h)
82 {
83 sieve_error (mach, "numaddr: can't get argument 1");
84 sieve_abort (mach);
85 }
86 v = sieve_value_get (args, 1);
87 if (!v)
88 {
89 sieve_error (mach, "numaddr: can't get argument 2");
90 sieve_abort (mach);
91 }
92
93 message_get_header (sieve_get_message (mach), &vc.hdr);
94 vc.count = 0;
95 vc.limit = v->v.number;
96
97 rc = sieve_vlist_do (h, _count_items, &vc);
98
99 if (sieve_tag_lookup (tags, "under", NULL))
100 rc = !rc;
101 return rc;
102 }
103
104 static sieve_data_type numaddr_req_args[] = {
105 SVT_STRING_LIST,
106 SVT_NUMBER,
107 SVT_VOID
108 };
109
110 static sieve_tag_def_t numaddr_tags[] = {
111 { "over", SVT_VOID },
112 { "under", SVT_VOID },
113 { NULL }
114 };
115
116 static sieve_tag_group_t numaddr_tag_groups[] = {
117 { numaddr_tags, NULL },
118 { NULL }
119 };
120
121
122 int
123 SIEVE_EXPORT(numaddr,init) (sieve_machine_t mach)
124 {
125 return sieve_register_test (mach, "numaddr", numaddr_test,
126 numaddr_req_args, numaddr_tag_groups, 1);
127 }