40 |
#include <stdlib.h> |
#include <stdlib.h> |
41 |
#include <mailutils/libsieve.h> |
#include <mailutils/libsieve.h> |
42 |
|
|
43 |
struct val_ctr { |
struct val_ctr { /* Data passed to the counter function */ |
44 |
header_t hdr; |
header_t hdr; /* Headers of the current message */ |
45 |
size_t limit; |
size_t limit; /* Limit for the number of addresses */ |
46 |
size_t count; |
size_t count; /* Number of addresses counted so far */ |
47 |
}; |
}; |
48 |
|
|
49 |
|
/* Count addresses in a single header value. |
50 |
|
|
51 |
|
Input: |
52 |
|
ITEM is the name of the header to scan. |
53 |
|
DATA is a pointer to the val_ctr structure */ |
54 |
|
Return value: |
55 |
|
non-zero if the limit on the number of addresses has been reached. */ |
56 |
|
|
57 |
static int |
static int |
58 |
_count_items (void *item, void *data) |
_count_items (void *item, void *data) |
59 |
{ |
{ |
74 |
free (val); |
free (val); |
75 |
return vp->count >= vp->limit; |
return vp->count >= vp->limit; |
76 |
} |
} |
77 |
|
|
78 |
|
/* Handler for the numaddr test */ |
79 |
static int |
static int |
80 |
numaddr_test (sieve_machine_t mach, list_t args, list_t tags) |
numaddr_test (sieve_machine_t mach, list_t args, list_t tags) |
81 |
{ |
{ |
86 |
if (sieve_get_debug_level (mach) & MU_SIEVE_DEBUG_TRACE) |
if (sieve_get_debug_level (mach) & MU_SIEVE_DEBUG_TRACE) |
87 |
sieve_debug (mach, "NUMADDR\n"); |
sieve_debug (mach, "NUMADDR\n"); |
88 |
|
|
89 |
|
/* Retrieve required arguments: */ |
90 |
|
/* First argument: list of header names */ |
91 |
h = sieve_value_get (args, 0); |
h = sieve_value_get (args, 0); |
92 |
if (!h) |
if (!h) |
93 |
{ |
{ |
94 |
sieve_error (mach, "numaddr: can't get argument 1"); |
sieve_error (mach, "numaddr: can't get argument 1"); |
95 |
sieve_abort (mach); |
sieve_abort (mach); |
96 |
} |
} |
97 |
|
/* Second argument: Limit on the number of addresses */ |
98 |
v = sieve_value_get (args, 1); |
v = sieve_value_get (args, 1); |
99 |
if (!v) |
if (!v) |
100 |
{ |
{ |
102 |
sieve_abort (mach); |
sieve_abort (mach); |
103 |
} |
} |
104 |
|
|
105 |
|
/* Fill in the val_ctr structure */ |
106 |
message_get_header (sieve_get_message (mach), &vc.hdr); |
message_get_header (sieve_get_message (mach), &vc.hdr); |
107 |
vc.count = 0; |
vc.count = 0; |
108 |
vc.limit = v->v.number; |
vc.limit = v->v.number; |
109 |
|
|
110 |
|
/* Count the addresses */ |
111 |
rc = sieve_vlist_do (h, _count_items, &vc); |
rc = sieve_vlist_do (h, _count_items, &vc); |
112 |
|
|
113 |
|
/* Here rc >= 1 iff the counted number of addresses is greater or equal |
114 |
|
to vc.limit. If `:under' tag was given we reverse the return value */ |
115 |
if (sieve_tag_lookup (tags, "under", NULL)) |
if (sieve_tag_lookup (tags, "under", NULL)) |
116 |
rc = !rc; |
rc = !rc; |
117 |
return rc; |
return rc; |
118 |
} |
} |
119 |
|
|
120 |
|
/* Syntactic definitions for the numaddr test */ |
121 |
|
|
122 |
|
/* Required arguments: */ |
123 |
static sieve_data_type numaddr_req_args[] = { |
static sieve_data_type numaddr_req_args[] = { |
124 |
SVT_STRING_LIST, |
SVT_STRING_LIST, |
125 |
SVT_NUMBER, |
SVT_NUMBER, |
126 |
SVT_VOID |
SVT_VOID |
127 |
}; |
}; |
128 |
|
|
129 |
|
/* Tagged arguments: */ |
130 |
static sieve_tag_def_t numaddr_tags[] = { |
static sieve_tag_def_t numaddr_tags[] = { |
131 |
{ "over", SVT_VOID }, |
{ "over", SVT_VOID }, |
132 |
{ "under", SVT_VOID }, |
{ "under", SVT_VOID }, |
138 |
{ NULL } |
{ NULL } |
139 |
}; |
}; |
140 |
|
|
141 |
|
/* Initialization function. It is the only function exported from this |
142 |
|
module. */ |
143 |
int |
int |
144 |
SIEVE_EXPORT(numaddr,init) (sieve_machine_t mach) |
SIEVE_EXPORT(numaddr,init) (sieve_machine_t mach) |
145 |
{ |
{ |
146 |
return sieve_register_test (mach, "numaddr", numaddr_test, |
return sieve_register_test (mach, "numaddr", numaddr_test, |
147 |
numaddr_req_args, numaddr_tag_groups, 1); |
numaddr_req_args, numaddr_tag_groups, 1); |
148 |
} |
} |