1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999-2021 Free Software Foundation, Inc.
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 3 of the License, or (at your option) any later version.
8
9 This library 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 GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General
15 Public License along with this library. If not, see
16 <http://www.gnu.org/licenses/>. */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <string.h>
26 #include <sieve-priv.h>
27
28 int
mu_sieve_registry_require(mu_sieve_machine_t mach,const char * name,enum mu_sieve_record type)29 mu_sieve_registry_require (mu_sieve_machine_t mach, const char *name,
30 enum mu_sieve_record type)
31 {
32 mu_sieve_registry_t *reg;
33
34 reg = mu_sieve_registry_lookup (mach, name, type);
35 if (!reg)
36 {
37 void *handle = mu_sieve_load_ext (mach, name);
38 if (!handle)
39 return 1;
40 reg = mu_sieve_registry_lookup (mach, name, type);
41 if (!reg)
42 return 1;
43 reg->handle = handle;
44 }
45
46 reg->required = 1;
47 return 0;
48 }
49
50
51 static void
regunload(void * data)52 regunload (void *data)
53 {
54 mu_sieve_registry_t *reg = data;
55 mu_sieve_unload_ext (reg->handle);
56 }
57
58 static int
regcmp(void const * a,void const * b)59 regcmp (void const *a, void const *b)
60 {
61 mu_sieve_registry_t const *rega = a;
62 mu_sieve_registry_t const *regb = b;
63 if (rega->type != regb->type)
64 return rega->type - regb->type;
65 return strcmp (rega->name, regb->name);
66 }
67
68 mu_sieve_registry_t *
mu_sieve_registry_add(mu_sieve_machine_t mach,const char * name)69 mu_sieve_registry_add (mu_sieve_machine_t mach, const char *name)
70 {
71 mu_sieve_registry_t *reg;
72 int rc;
73
74 if (!mach->registry)
75 {
76 rc = mu_list_create (&mach->registry);
77 if (rc)
78 {
79 mu_sieve_error (mach, "mu_list_create: %s", mu_strerror (rc));
80 mu_sieve_abort (mach);
81 }
82 mu_list_set_destroy_item (mach->registry, regunload);
83 mu_list_set_comparator (mach->registry, regcmp);
84 }
85 reg = mu_sieve_malloc (mach, sizeof (*reg));
86 reg->name = name;
87 reg->handle = NULL;
88 reg->required = 0;
89 memset (®->v, 0, sizeof reg->v);
90 rc = mu_list_append (mach->registry, reg);
91 if (rc)
92 {
93 mu_sieve_error (mach, "mu_list_append: %s", mu_strerror (rc));
94 mu_sieve_abort (mach);
95 }
96 return reg;
97 }
98
99 mu_sieve_registry_t *
mu_sieve_registry_lookup(mu_sieve_machine_t mach,const char * name,enum mu_sieve_record type)100 mu_sieve_registry_lookup (mu_sieve_machine_t mach, const char *name,
101 enum mu_sieve_record type)
102 {
103 mu_sieve_registry_t key, *reg;
104 int rc;
105
106 key.name = name;
107 key.type = type;
108
109 rc = mu_list_locate (mach->registry, &key, (void**) ®);
110 if (rc == MU_ERR_NOENT)
111 return NULL;
112 else if (rc)
113 {
114 mu_sieve_error (mach, _("registry lookup failed: %s"), mu_strerror (rc));
115 mu_sieve_abort (mach);
116 }
117 return reg;
118 }
119
120 void
mu_sieve_register_test_ext(mu_sieve_machine_t mach,const char * name,mu_sieve_handler_t handler,mu_sieve_data_type * req_args,mu_sieve_data_type * opt_args,mu_sieve_tag_group_t * tags,int required)121 mu_sieve_register_test_ext (mu_sieve_machine_t mach,
122 const char *name, mu_sieve_handler_t handler,
123 mu_sieve_data_type *req_args,
124 mu_sieve_data_type *opt_args,
125 mu_sieve_tag_group_t *tags, int required)
126 {
127 mu_sieve_registry_t *reg = mu_sieve_registry_add (mach, name);
128
129 reg->type = mu_sieve_record_test;
130 reg->required = required;
131 reg->v.command.handler = handler;
132 reg->v.command.req_args = req_args;
133 reg->v.command.opt_args = opt_args;
134 reg->v.command.tags = tags;
135 }
136
137 void
mu_sieve_register_test(mu_sieve_machine_t mach,const char * name,mu_sieve_handler_t handler,mu_sieve_data_type * arg_types,mu_sieve_tag_group_t * tags,int required)138 mu_sieve_register_test (mu_sieve_machine_t mach,
139 const char *name, mu_sieve_handler_t handler,
140 mu_sieve_data_type *arg_types,
141 mu_sieve_tag_group_t *tags, int required)
142 {
143 return mu_sieve_register_test_ext (mach, name, handler,
144 arg_types, NULL,
145 tags,
146 required);
147 }
148
149 void
mu_sieve_register_action_ext(mu_sieve_machine_t mach,const char * name,mu_sieve_handler_t handler,mu_sieve_data_type * req_args,mu_sieve_data_type * opt_args,mu_sieve_tag_group_t * tags,int required)150 mu_sieve_register_action_ext (mu_sieve_machine_t mach,
151 const char *name, mu_sieve_handler_t handler,
152 mu_sieve_data_type *req_args,
153 mu_sieve_data_type *opt_args,
154 mu_sieve_tag_group_t *tags, int required)
155 {
156 mu_sieve_registry_t *reg = mu_sieve_registry_add (mach, name);
157
158 reg->type = mu_sieve_record_action;
159 reg->required = required;
160 reg->v.command.handler = handler;
161 reg->v.command.req_args = req_args;
162 reg->v.command.opt_args = opt_args;
163 reg->v.command.tags = tags;
164 }
165
166 void
mu_sieve_register_action(mu_sieve_machine_t mach,const char * name,mu_sieve_handler_t handler,mu_sieve_data_type * arg_types,mu_sieve_tag_group_t * tags,int required)167 mu_sieve_register_action (mu_sieve_machine_t mach,
168 const char *name, mu_sieve_handler_t handler,
169 mu_sieve_data_type *arg_types,
170 mu_sieve_tag_group_t *tags, int required)
171 {
172 return mu_sieve_register_action_ext (mach, name, handler,
173 arg_types, NULL,
174 tags,
175 required);
176 }
177