7 /* manipulate MILTER_MACROS structures
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)
27 /* void milter_macros_free(mp)
30 /* int milter_macros_print(print_fn, stream, flags, ptr)
31 /* ATTR_PRINT_MASTER_FN print_fn;
36 /* int milter_macros_scan(scan_fn, fp, flags, ptr)
37 /* ATTR_SCAN_MASTER_FN scan_fn;
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
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.
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,
92 /* Fatal: out of memory.
96 /* The Secure Mailer license must be distributed with this
99 /* Wietse Venema IBM T.J. Watson Research P.O. Box 704 Yorktown
100 /* Heights, NY 10598, USA
103 /* System library. */
105 #include <sys_defs.h>
107 /* Utility library. */
111 #include <mymalloc.h>
114 /* Global library. */
116 #include <mail_proto.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
;
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
,
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
;
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
,
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
)
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
);
232 /* milter_macros_alloc - allocate macros structure with simple initialization */
234 MILTER_MACROS
*milter_macros_alloc(int mode
)
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; \
254 mp
= (MILTER_MACROS
*) mymalloc(sizeof(*mp
));
256 case MILTER_MACROS_ALLOC_ZERO
:
257 milter_macros_init(mp
, 0);
259 case MILTER_MACROS_ALLOC_EMPTY
:
260 milter_macros_init(mp
, mystrdup(""));
263 msg_panic("milter_macros_alloc: unknown mode %d", mode
);
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); \
296 milter_macros_wipe(mp
);