Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / milter / milter_macros.c
blob4e785ad0a63e95abc6803d35933eab127edaefae
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* milter_macros
6 /* SUMMARY
7 /* manipulate MILTER_MACROS structures
8 /* SYNOPSIS
9 /* #include <milter.h>
11 /* MILTER_MACROS *milter_macros_create(conn_macros, helo_macros,
12 /* mail_macros, rcpt_macros,
13 /* data_macros, eoh_macros,
14 /* eod_macros, unk_macros)
15 /* const char *conn_macros;
16 /* const char *helo_macros;
17 /* const char *mail_macros;
18 /* const char *rcpt_macrps;
19 /* const char *data_macros;
20 /* const char *eoh_macros;
21 /* const char *eod_macros;
22 /* const char *unk_macros;
24 /* MILTER_MACROS *milter_macros_alloc(init_mode)
25 /* int init_mode;
27 /* void milter_macros_free(mp)
28 /* MILTER_MACROS *mp;
30 /* int milter_macros_print(print_fn, stream, flags, ptr)
31 /* ATTR_PRINT_MASTER_FN print_fn;
32 /* VSTREAM *stream;
33 /* int flags;
34 /* void *ptr;
36 /* int milter_macros_scan(scan_fn, fp, flags, ptr)
37 /* ATTR_SCAN_MASTER_FN scan_fn;
38 /* VSTREAM *fp;
39 /* int flags;
40 /* void *ptr;
41 /* DESCRIPTION
42 /* Sendmail mail filter (Milter) applications receive sets of
43 /* macro name=value pairs with each SMTP or content event.
44 /* In Postfix, these macro names are stored in MILTER_MACROS
45 /* structures, as one list for each event type. By default,
46 /* the same structure is shared by all Milter applications;
47 /* it is initialized with information from main.cf. With
48 /* Sendmail 8.14 a Milter can override one or more lists of
49 /* macro names. Postfix implements this by giving the Milter
50 /* its own MILTER_MACROS structure and by storing the per-Milter
51 /* information there.
53 /* This module maintains per-event macro name lists as
54 /* mystrdup()'ed values. The user is explicitly allowed to
55 /* update these values directly, as long as the result is
56 /* compatible with mystrdup().
58 /* milter_macros_create() creates a MILTER_MACROS structure
59 /* and initializes it with copies of its string arguments.
60 /* Null pointers are not valid as input.
62 /* milter_macros_alloc() creates am empty MILTER_MACROS structure
63 /* that is initialized according to its init_mode argument.
64 /* .IP MILTER_MACROS_ALLOC_ZERO
65 /* Initialize all structure members as null pointers. This
66 /* mode must be used with milter_macros_scan(), because that
67 /* function blindly overwrites all structure members. No other
68 /* function except milter_macros_free() allows structure members
69 /* with null pointer values.
70 /* .IP MILTER_MACROS_ALLOC_EMPTY
71 /* Initialize all structure members with mystrdup(""). This
72 /* is not as expensive as it appears to be.
73 /* .PP
74 /* milter_macros_free() destroys a MILTER_MACROS structure and
75 /* frees any strings referenced by it.
77 /* milter_macros_print() writes the contents of a MILTER_MACROS
78 /* structure to the named stream using the specified attribute
79 /* print routine. milter_macros_print() is meant to be passed
80 /* as a call-back to attr_print*(), thusly:
82 /* ATTR_TYPE_FUNC, milter_macros_print, (void *) macros,
84 /* milter_macros_scan() reads a MILTER_MACROS structure from
85 /* the named stream using the specified attribute scan routine.
86 /* No attempt is made to free the memory of existing structure
87 /* members. milter_macros_scan() is meant to be passed as a
88 /* call-back to attr_scan*(), thusly:
90 /* ATTR_TYPE_FUNC, milter_macros_scan, (void *) macros,
91 /* DIAGNOSTICS
92 /* Fatal: out of memory.
93 /* LICENSE
94 /* .ad
95 /* .fi
96 /* The Secure Mailer license must be distributed with this
97 /* software.
98 /* AUTHOR(S)
99 /* Wietse Venema IBM T.J. Watson Research P.O. Box 704 Yorktown
100 /* Heights, NY 10598, USA
101 /*--*/
103 /* System library. */
105 #include <sys_defs.h>
107 /* Utility library. */
109 #include <msg.h>
110 #include <attr.h>
111 #include <mymalloc.h>
112 #include <vstring.h>
114 /* Global library. */
116 #include <mail_proto.h>
117 #include <milter.h>
120 * Ad-hoc protocol to send/receive milter macro name lists.
122 #define MAIL_ATTR_MILT_MAC_CONN "conn_macros"
123 #define MAIL_ATTR_MILT_MAC_HELO "helo_macros"
124 #define MAIL_ATTR_MILT_MAC_MAIL "mail_macros"
125 #define MAIL_ATTR_MILT_MAC_RCPT "rcpt_macros"
126 #define MAIL_ATTR_MILT_MAC_DATA "data_macros"
127 #define MAIL_ATTR_MILT_MAC_EOH "eoh_macros"
128 #define MAIL_ATTR_MILT_MAC_EOD "eod_macros"
129 #define MAIL_ATTR_MILT_MAC_UNK "unk_macros"
131 /* milter_macros_print - write macros structure to stream */
133 int milter_macros_print(ATTR_PRINT_MASTER_FN print_fn, VSTREAM *fp,
134 int flags, void *ptr)
136 MILTER_MACROS *mp = (MILTER_MACROS *) ptr;
137 int ret;
140 * The attribute order does not matter, except that it must be the same
141 * as in the milter_macros_scan() function.
143 ret = print_fn(fp, flags | ATTR_FLAG_MORE,
144 ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_CONN, mp->conn_macros,
145 ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_HELO, mp->helo_macros,
146 ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_MAIL, mp->mail_macros,
147 ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_RCPT, mp->rcpt_macros,
148 ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_DATA, mp->data_macros,
149 ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_EOH, mp->eoh_macros,
150 ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_EOD, mp->eod_macros,
151 ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_UNK, mp->unk_macros,
152 ATTR_TYPE_END);
153 return (ret);
156 /* milter_macros_scan - receive macros structure from stream */
158 int milter_macros_scan(ATTR_SCAN_MASTER_FN scan_fn, VSTREAM *fp,
159 int flags, void *ptr)
161 MILTER_MACROS *mp = (MILTER_MACROS *) ptr;
162 int ret;
165 * We could simplify this by moving memory allocation into attr_scan*().
167 VSTRING *conn_macros = vstring_alloc(10);
168 VSTRING *helo_macros = vstring_alloc(10);
169 VSTRING *mail_macros = vstring_alloc(10);
170 VSTRING *rcpt_macros = vstring_alloc(10);
171 VSTRING *data_macros = vstring_alloc(10);
172 VSTRING *eoh_macros = vstring_alloc(10);
173 VSTRING *eod_macros = vstring_alloc(10);
174 VSTRING *unk_macros = vstring_alloc(10);
177 * The attribute order does not matter, except that it must be the same
178 * as in the milter_macros_print() function.
180 ret = scan_fn(fp, flags | ATTR_FLAG_MORE,
181 ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_CONN, conn_macros,
182 ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_HELO, helo_macros,
183 ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_MAIL, mail_macros,
184 ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_RCPT, rcpt_macros,
185 ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_DATA, data_macros,
186 ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_EOH, eoh_macros,
187 ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_EOD, eod_macros,
188 ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_UNK, unk_macros,
189 ATTR_TYPE_END);
192 * Don't optimize for error.
194 mp->conn_macros = vstring_export(conn_macros);
195 mp->helo_macros = vstring_export(helo_macros);
196 mp->mail_macros = vstring_export(mail_macros);
197 mp->rcpt_macros = vstring_export(rcpt_macros);
198 mp->data_macros = vstring_export(data_macros);
199 mp->eoh_macros = vstring_export(eoh_macros);
200 mp->eod_macros = vstring_export(eod_macros);
201 mp->unk_macros = vstring_export(unk_macros);
203 return (ret == 8 ? 1 : -1);
206 /* milter_macros_create - create and initialize macros structure */
208 MILTER_MACROS *milter_macros_create(const char *conn_macros,
209 const char *helo_macros,
210 const char *mail_macros,
211 const char *rcpt_macros,
212 const char *data_macros,
213 const char *eoh_macros,
214 const char *eod_macros,
215 const char *unk_macros)
217 MILTER_MACROS *mp;
219 mp = (MILTER_MACROS *) mymalloc(sizeof(*mp));
220 mp->conn_macros = mystrdup(conn_macros);
221 mp->helo_macros = mystrdup(helo_macros);
222 mp->mail_macros = mystrdup(mail_macros);
223 mp->rcpt_macros = mystrdup(rcpt_macros);
224 mp->data_macros = mystrdup(data_macros);
225 mp->eoh_macros = mystrdup(eoh_macros);
226 mp->eod_macros = mystrdup(eod_macros);
227 mp->unk_macros = mystrdup(unk_macros);
229 return (mp);
232 /* milter_macros_alloc - allocate macros structure with simple initialization */
234 MILTER_MACROS *milter_macros_alloc(int mode)
236 MILTER_MACROS *mp;
239 * This macro was originally in milter.h, but no-one else needed it.
241 #define milter_macros_init(mp, expr) do { \
242 MILTER_MACROS *__mp = (mp); \
243 char *__expr = (expr); \
244 __mp->conn_macros = __expr; \
245 __mp->helo_macros = __expr; \
246 __mp->mail_macros = __expr; \
247 __mp->rcpt_macros = __expr; \
248 __mp->data_macros = __expr; \
249 __mp->eoh_macros = __expr; \
250 __mp->eod_macros = __expr; \
251 __mp->unk_macros = __expr; \
252 } while (0)
254 mp = (MILTER_MACROS *) mymalloc(sizeof(*mp));
255 switch (mode) {
256 case MILTER_MACROS_ALLOC_ZERO:
257 milter_macros_init(mp, 0);
258 break;
259 case MILTER_MACROS_ALLOC_EMPTY:
260 milter_macros_init(mp, mystrdup(""));
261 break;
262 default:
263 msg_panic("milter_macros_alloc: unknown mode %d", mode);
265 return (mp);
268 /* milter_macros_free - destroy memory for MILTER_MACROS structure */
270 void milter_macros_free(MILTER_MACROS *mp)
274 * This macro was originally in milter.h, but no-one else needed it.
276 #define milter_macros_wipe(mp) do { \
277 MILTER_MACROS *__mp = mp; \
278 if (__mp->conn_macros) \
279 myfree(__mp->conn_macros); \
280 if (__mp->helo_macros) \
281 myfree(__mp->helo_macros); \
282 if (__mp->mail_macros) \
283 myfree(__mp->mail_macros); \
284 if (__mp->rcpt_macros) \
285 myfree(__mp->rcpt_macros); \
286 if (__mp->data_macros) \
287 myfree(__mp->data_macros); \
288 if (__mp->eoh_macros) \
289 myfree(__mp->eoh_macros); \
290 if (__mp->eod_macros) \
291 myfree(__mp->eod_macros); \
292 if (__mp->unk_macros) \
293 myfree(__mp->unk_macros); \
294 } while (0)
296 milter_macros_wipe(mp);
297 myfree((char *) mp);