xref: /freebsd/contrib/sendmail/src/milter.c (revision 1e413cf93298b5b97441a21d9a50fdcd0ee9945e)
1 /*
2  * Copyright (c) 1999-2006 Sendmail, Inc. and its suppliers.
3  *	All rights reserved.
4  *
5  * By using this file, you agree to the terms and conditions set
6  * forth in the LICENSE file which can be found at the top level of
7  * the sendmail distribution.
8  *
9  */
10 
11 #include <sendmail.h>
12 
13 SM_RCSID("@(#)$Id: milter.c,v 8.269 2007/06/06 17:26:12 ca Exp $")
14 
15 #if MILTER
16 # include <sm/sendmail.h>
17 # include <libmilter/mfapi.h>
18 # include <libmilter/mfdef.h>
19 
20 # include <errno.h>
21 # include <sm/time.h>
22 # include <sys/uio.h>
23 
24 # if NETINET || NETINET6
25 #  include <arpa/inet.h>
26 #  if MILTER_NO_NAGLE
27 #   include <netinet/tcp.h>
28 #  endif /* MILTER_NO_NAGLE */
29 # endif /* NETINET || NETINET6 */
30 
31 # include <sm/fdset.h>
32 
33 static void	milter_connect_timeout __P((int));
34 static void	milter_error __P((struct milter *, ENVELOPE *));
35 static int	milter_open __P((struct milter *, bool, ENVELOPE *));
36 static void	milter_parse_timeouts __P((char *, struct milter *));
37 static char	*milter_sysread __P((struct milter *, char *, ssize_t, time_t,
38 			ENVELOPE *, const char *));
39 static char	*milter_read __P((struct milter *, char *, ssize_t *, time_t,
40 			ENVELOPE *, const char *));
41 static char	*milter_write __P((struct milter *, int, char *, ssize_t,
42 			time_t, ENVELOPE *, const char *));
43 static char	*milter_send_command __P((struct milter *, int, void *,
44 			ssize_t, ENVELOPE *, char *, const char *));
45 static char	*milter_command __P((int, void *, ssize_t, char **,
46 			ENVELOPE *, char *, const char *, bool));
47 static char	*milter_body __P((struct milter *, ENVELOPE *, char *));
48 static int	milter_reopen_df __P((ENVELOPE *));
49 static int	milter_reset_df __P((ENVELOPE *));
50 static void	milter_quit_filter __P((struct milter *, ENVELOPE *));
51 static void	milter_abort_filter __P((struct milter *, ENVELOPE *));
52 static void	milter_send_macros __P((struct milter *, char **, int,
53 			ENVELOPE *));
54 static int	milter_negotiate __P((struct milter *, ENVELOPE *,
55 			milters_T *));
56 static void	milter_per_connection_check __P((ENVELOPE *));
57 static char	*milter_headers __P((struct milter *, ENVELOPE *, char *));
58 static void	milter_addheader __P((struct milter *, char *, ssize_t,
59 			ENVELOPE *));
60 static void	milter_insheader __P((struct milter *, char *, ssize_t,
61 			ENVELOPE *));
62 static void	milter_changeheader __P((struct milter *, char *, ssize_t,
63 			ENVELOPE *));
64 static void	milter_chgfrom __P((char *, ssize_t, ENVELOPE *));
65 static void	milter_addrcpt __P((char *, ssize_t, ENVELOPE *));
66 static void	milter_addrcpt_par __P((char *, ssize_t, ENVELOPE *));
67 static void	milter_delrcpt __P((char *, ssize_t, ENVELOPE *));
68 static int	milter_replbody __P((char *, ssize_t, bool, ENVELOPE *));
69 static int	milter_set_macros __P((char *, char **, char *, int));
70 
71 
72 /* milter states */
73 # define SMFS_CLOSED		'C'	/* closed for all further actions */
74 # define SMFS_OPEN		'O'	/* connected to remote milter filter */
75 # define SMFS_INMSG		'M'	/* currently servicing a message */
76 # define SMFS_DONE		'D'	/* done with current message */
77 # define SMFS_CLOSABLE		'Q'	/* done with current connection */
78 # define SMFS_ERROR		'E'	/* error state */
79 # define SMFS_READY		'R'	/* ready for action */
80 # define SMFS_SKIP		'S'	/* skip body */
81 
82 static char *MilterConnectMacros[MAXFILTERMACROS + 1];
83 static char *MilterHeloMacros[MAXFILTERMACROS + 1];
84 static char *MilterEnvFromMacros[MAXFILTERMACROS + 1];
85 static char *MilterEnvRcptMacros[MAXFILTERMACROS + 1];
86 static char *MilterDataMacros[MAXFILTERMACROS + 1];
87 static char *MilterEOMMacros[MAXFILTERMACROS + 1];
88 static char *MilterEOHMacros[MAXFILTERMACROS + 1];
89 static size_t MilterMaxDataSize = MILTER_MAX_DATA_SIZE;
90 
91 # define MILTER_CHECK_DONE_MSG() \
92 	if (*state == SMFIR_REPLYCODE || \
93 	    *state == SMFIR_REJECT || \
94 	    *state == SMFIR_DISCARD || \
95 	    *state == SMFIR_TEMPFAIL) \
96 	{ \
97 		/* Abort the filters to let them know we are done with msg */ \
98 		milter_abort(e); \
99 	}
100 
101 # define MILTER_CHECK_ERROR(initial, action) \
102 	if (!initial && tTd(71, 100)) \
103 	{ \
104 		if (e->e_quarmsg == NULL) \
105 		{ \
106 			e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, \
107 							 "filter failure"); \
108 			macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), \
109 				  e->e_quarmsg); \
110 		} \
111 	} \
112 	else if (tTd(71, 101)) \
113 	{ \
114 		if (e->e_quarmsg == NULL) \
115 		{ \
116 			e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, \
117 							 "filter failure"); \
118 			macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), \
119 				  e->e_quarmsg); \
120 		} \
121 	} \
122 	else if (bitnset(SMF_TEMPFAIL, m->mf_flags)) \
123 		*state = SMFIR_TEMPFAIL; \
124 	else if (bitnset(SMF_TEMPDROP, m->mf_flags)) \
125 		*state = SMFIR_SHUTDOWN; \
126 	else if (bitnset(SMF_REJECT, m->mf_flags)) \
127 		*state = SMFIR_REJECT; \
128 	else \
129 		action;
130 
131 # define MILTER_CHECK_REPLYCODE(default) \
132 	if (response == NULL || \
133 	    strlen(response) + 1 != (size_t) rlen || \
134 	    rlen < 3 || \
135 	    (response[0] != '4' && response[0] != '5') || \
136 	    !isascii(response[1]) || !isdigit(response[1]) || \
137 	    !isascii(response[2]) || !isdigit(response[2])) \
138 	{ \
139 		if (response != NULL) \
140 			sm_free(response); /* XXX */ \
141 		response = newstr(default); \
142 	} \
143 	else \
144 	{ \
145 		char *ptr = response; \
146  \
147 		/* Check for unprotected %'s in the string */ \
148 		while (*ptr != '\0') \
149 		{ \
150 			if (*ptr == '%' && *++ptr != '%') \
151 			{ \
152 				sm_free(response); /* XXX */ \
153 				response = newstr(default); \
154 				break; \
155 			} \
156 			ptr++; \
157 		} \
158 	}
159 
160 # define MILTER_DF_ERROR(msg) \
161 { \
162 	int save_errno = errno; \
163  \
164 	if (tTd(64, 5)) \
165 	{ \
166 		sm_dprintf(msg, dfname, sm_errstring(save_errno)); \
167 		sm_dprintf("\n"); \
168 	} \
169 	if (MilterLogLevel > 0) \
170 		sm_syslog(LOG_ERR, e->e_id, msg, dfname, sm_errstring(save_errno)); \
171 	if (SuperSafe == SAFE_REALLY) \
172 	{ \
173 		if (e->e_dfp != NULL) \
174 		{ \
175 			(void) sm_io_close(e->e_dfp, SM_TIME_DEFAULT); \
176 			e->e_dfp = NULL; \
177 		} \
178 		e->e_flags &= ~EF_HAS_DF; \
179 	} \
180 	errno = save_errno; \
181 }
182 
183 /*
184 **  MILTER_TIMEOUT -- make sure socket is ready in time
185 **
186 **	Parameters:
187 **		routine -- routine name for debug/logging
188 **		secs -- number of seconds in timeout
189 **		write -- waiting to read or write?
190 **		started -- whether this is part of a previous sequence
191 **
192 **	Assumes 'm' is a milter structure for the current socket.
193 */
194 
195 # define MILTER_TIMEOUT(routine, secs, write, started, function) \
196 { \
197 	int ret; \
198 	int save_errno; \
199 	fd_set fds; \
200 	struct timeval tv; \
201  \
202 	if (SM_FD_SETSIZE > 0 && m->mf_sock >= SM_FD_SETSIZE) \
203 	{ \
204 		if (tTd(64, 5)) \
205 			sm_dprintf("milter_%s(%s): socket %d is larger than FD_SETSIZE %d\n", \
206 				   (routine), m->mf_name, m->mf_sock, \
207 				   SM_FD_SETSIZE); \
208 		if (MilterLogLevel > 0) \
209 			sm_syslog(LOG_ERR, e->e_id, \
210 				  "Milter (%s): socket(%s) %d is larger than FD_SETSIZE %d", \
211 				  m->mf_name, (routine), m->mf_sock, \
212 				  SM_FD_SETSIZE); \
213 		milter_error(m, e); \
214 		return NULL; \
215 	} \
216  \
217 	do \
218 	{ \
219 		FD_ZERO(&fds); \
220 		SM_FD_SET(m->mf_sock, &fds); \
221 		tv.tv_sec = (secs); \
222 		tv.tv_usec = 0; \
223 		ret = select(m->mf_sock + 1, \
224 			     (write) ? NULL : &fds, \
225 			     (write) ? &fds : NULL, \
226 			     NULL, &tv); \
227 	} while (ret < 0 && errno == EINTR); \
228  \
229 	switch (ret) \
230 	{ \
231 	  case 0: \
232 		if (tTd(64, 5)) \
233 			sm_dprintf("milter_%s(%s): timeout, where=%s\n", \
234 				(routine), m->mf_name, (function)); \
235 		if (MilterLogLevel > 0) \
236 			sm_syslog(LOG_ERR, e->e_id, \
237 				  "Milter (%s): timeout %s data %s, where=%s", \
238 				  m->mf_name, \
239 				  started ? "during" : "before", \
240 				  (routine), (function)); \
241 		milter_error(m, e); \
242 		return NULL; \
243  \
244 	  case -1: \
245 		save_errno = errno; \
246 		if (tTd(64, 5)) \
247 			sm_dprintf("milter_%s(%s): select: %s\n", (routine), \
248 				   m->mf_name, sm_errstring(save_errno)); \
249 		if (MilterLogLevel > 0) \
250 		{ \
251 			sm_syslog(LOG_ERR, e->e_id, \
252 				  "Milter (%s): select(%s): %s", \
253 				  m->mf_name, (routine), \
254 				  sm_errstring(save_errno)); \
255 		} \
256 		milter_error(m, e); \
257 		return NULL; \
258  \
259 	  default: \
260 		if (SM_FD_ISSET(m->mf_sock, &fds)) \
261 			break; \
262 		if (tTd(64, 5)) \
263 			sm_dprintf("milter_%s(%s): socket not ready\n", \
264 				(routine), m->mf_name); \
265 		if (MilterLogLevel > 0) \
266 		{ \
267 			sm_syslog(LOG_ERR, e->e_id, \
268 				  "Milter (%s): socket(%s) not ready", \
269 				  m->mf_name, (routine)); \
270 		} \
271 		milter_error(m, e); \
272 		return NULL; \
273 	} \
274 }
275 
276 /*
277 **  Low level functions
278 */
279 
280 /*
281 **  MILTER_READ -- read from a remote milter filter
282 **
283 **	Parameters:
284 **		m -- milter to read from.
285 **		cmd -- return param for command read.
286 **		rlen -- return length of response string.
287 **		to -- timeout in seconds.
288 **		e -- current envelope.
289 **
290 **	Returns:
291 **		response string (may be NULL)
292 */
293 
294 static char *
295 milter_sysread(m, buf, sz, to, e, where)
296 	struct milter *m;
297 	char *buf;
298 	ssize_t sz;
299 	time_t to;
300 	ENVELOPE *e;
301 	const char *where;
302 {
303 	time_t readstart = 0;
304 	ssize_t len, curl;
305 	bool started = false;
306 
307 	curl = 0;
308 
309 	if (to > 0)
310 		readstart = curtime();
311 
312 	for (;;)
313 	{
314 		if (to > 0)
315 		{
316 			time_t now;
317 
318 			now = curtime();
319 			if (now - readstart >= to)
320 			{
321 				if (tTd(64, 5))
322 					sm_dprintf("milter_sys_read (%s): timeout %s data read in %s",
323 						  m->mf_name,
324 						  started ? "during" : "before",
325 						  where);
326 				if (MilterLogLevel > 0)
327 					sm_syslog(LOG_ERR, e->e_id,
328 						  "Milter (%s): timeout %s data read in %s",
329 						  m->mf_name,
330 						  started ? "during" : "before",
331 						  where);
332 				milter_error(m, e);
333 				return NULL;
334 			}
335 			to -= now - readstart;
336 			readstart = now;
337 			MILTER_TIMEOUT("read", to, false, started, where);
338 		}
339 
340 		len = read(m->mf_sock, buf + curl, sz - curl);
341 
342 		if (len < 0)
343 		{
344 			int save_errno = errno;
345 
346 			if (tTd(64, 5))
347 				sm_dprintf("milter_sys_read(%s): read returned %ld: %s\n",
348 					m->mf_name, (long) len,
349 					sm_errstring(save_errno));
350 			if (MilterLogLevel > 0)
351 				sm_syslog(LOG_ERR, e->e_id,
352 					  "Milter (%s): read returned %ld: %s",
353 					  m->mf_name, (long) len,
354 					  sm_errstring(save_errno));
355 			milter_error(m, e);
356 			return NULL;
357 		}
358 
359 		started = true;
360 		curl += len;
361 		if (len == 0 || curl >= sz)
362 			break;
363 
364 	}
365 
366 	if (curl != sz)
367 	{
368 		if (tTd(64, 5))
369 			sm_dprintf("milter_sys_read(%s): cmd read returned %ld, expecting %ld\n",
370 				m->mf_name, (long) curl, (long) sz);
371 		if (MilterLogLevel > 0)
372 			sm_syslog(LOG_ERR, e->e_id,
373 				  "milter_sys_read(%s): cmd read returned %ld, expecting %ld",
374 				  m->mf_name, (long) curl, (long) sz);
375 		milter_error(m, e);
376 		return NULL;
377 	}
378 	return buf;
379 }
380 
381 static char *
382 milter_read(m, cmd, rlen, to, e, where)
383 	struct milter *m;
384 	char *cmd;
385 	ssize_t *rlen;
386 	time_t to;
387 	ENVELOPE *e;
388 	const char *where;
389 {
390 	time_t readstart = 0;
391 	ssize_t expl;
392 	mi_int32 i;
393 # if MILTER_NO_NAGLE && defined(TCP_CORK)
394 	int cork = 0;
395 # endif /* MILTER_NO_NAGLE && defined(TCP_CORK) */
396 	char *buf;
397 	char data[MILTER_LEN_BYTES + 1];
398 
399 	if (m->mf_sock < 0)
400 	{
401 		if (MilterLogLevel > 0)
402 			sm_syslog(LOG_ERR, e->e_id,
403 				  "milter_read(%s): socket closed, where=%s",
404 				  m->mf_name, where);
405 		milter_error(m, e);
406 		return NULL;
407 	}
408 
409 	*rlen = 0;
410 	*cmd = '\0';
411 
412 	if (to > 0)
413 		readstart = curtime();
414 
415 # if MILTER_NO_NAGLE && defined(TCP_CORK)
416 	setsockopt(m->mf_sock, IPPROTO_TCP, TCP_CORK, (char *)&cork,
417 		   sizeof(cork));
418 # endif /* MILTER_NO_NAGLE && defined(TCP_CORK) */
419 
420 	if (milter_sysread(m, data, sizeof(data), to, e, where) == NULL)
421 		return NULL;
422 
423 # if MILTER_NO_NAGLE && defined(TCP_CORK)
424 	cork = 1;
425 	setsockopt(m->mf_sock, IPPROTO_TCP, TCP_CORK, (char *)&cork,
426 		   sizeof(cork));
427 # endif /* MILTER_NO_NAGLE && defined(TCP_CORK) */
428 
429 	/* reset timeout */
430 	if (to > 0)
431 	{
432 		time_t now;
433 
434 		now = curtime();
435 		if (now - readstart >= to)
436 		{
437 			if (tTd(64, 5))
438 				sm_dprintf("milter_read(%s): timeout before data read, where=%s\n",
439 					m->mf_name, where);
440 			if (MilterLogLevel > 0)
441 				sm_syslog(LOG_ERR, e->e_id,
442 					  "Milter read(%s): timeout before data read, where=%s",
443 					  m->mf_name, where);
444 			milter_error(m, e);
445 			return NULL;
446 		}
447 		to -= now - readstart;
448 	}
449 
450 	*cmd = data[MILTER_LEN_BYTES];
451 	data[MILTER_LEN_BYTES] = '\0';
452 	(void) memcpy(&i, data, MILTER_LEN_BYTES);
453 	expl = ntohl(i) - 1;
454 
455 	if (tTd(64, 25))
456 		sm_dprintf("milter_read(%s): expecting %ld bytes\n",
457 			m->mf_name, (long) expl);
458 
459 	if (expl < 0)
460 	{
461 		if (tTd(64, 5))
462 			sm_dprintf("milter_read(%s): read size %ld out of range, where=%s\n",
463 				m->mf_name, (long) expl, where);
464 		if (MilterLogLevel > 0)
465 			sm_syslog(LOG_ERR, e->e_id,
466 				  "milter_read(%s): read size %ld out of range, where=%s",
467 				  m->mf_name, (long) expl, where);
468 		milter_error(m, e);
469 		return NULL;
470 	}
471 
472 	if (expl == 0)
473 		return NULL;
474 
475 	buf = (char *) xalloc(expl);
476 
477 	if (milter_sysread(m, buf, expl, to, e, where) == NULL)
478 	{
479 		sm_free(buf); /* XXX */
480 		return NULL;
481 	}
482 
483 	if (tTd(64, 50))
484 		sm_dprintf("milter_read(%s): Returning %*s\n",
485 			m->mf_name, (int) expl, buf);
486 	*rlen = expl;
487 	return buf;
488 }
489 
490 /*
491 **  MILTER_WRITE -- write to a remote milter filter
492 **
493 **	Parameters:
494 **		m -- milter to read from.
495 **		cmd -- command to send.
496 **		buf -- optional command data.
497 **		len -- length of buf.
498 **		to -- timeout in seconds.
499 **		e -- current envelope.
500 **
501 **	Returns:
502 **		buf if successful, NULL otherwise
503 **		Not actually used anywhere but function prototype
504 **			must match milter_read()
505 */
506 
507 static char *
508 milter_write(m, cmd, buf, len, to, e, where)
509 	struct milter *m;
510 	int cmd;
511 	char *buf;
512 	ssize_t len;
513 	time_t to;
514 	ENVELOPE *e;
515 	const char *where;
516 {
517 	time_t writestart = (time_t) 0;
518 	ssize_t sl, i;
519 	int num_vectors;
520 	mi_int32 nl;
521 	char command = (char) cmd;
522 	char data[MILTER_LEN_BYTES + 1];
523 	bool started = false;
524 	struct iovec vector[2];
525 
526 	/*
527 	**  At most two buffers will be written, though
528 	**  only one may actually be used (see num_vectors).
529 	**  The first is the size/command and the second is the command data.
530 	*/
531 
532 	if (len < 0 || len > MilterMaxDataSize)
533 	{
534 		if (tTd(64, 5))
535 			sm_dprintf("milter_write(%s): length %ld out of range\n",
536 				m->mf_name, (long) len);
537 		if (MilterLogLevel > 0)
538 			sm_syslog(LOG_ERR, e->e_id,
539 				  "milter_write(%s): length %ld out of range",
540 				  m->mf_name, (long) len);
541 		milter_error(m, e);
542 		return NULL;
543 	}
544 	if (m->mf_sock < 0)
545 	{
546 		if (MilterLogLevel > 0)
547 			sm_syslog(LOG_ERR, e->e_id,
548 				  "milter_write(%s): socket closed",
549 				  m->mf_name);
550 		milter_error(m, e);
551 		return NULL;
552 	}
553 
554 	if (tTd(64, 20))
555 		sm_dprintf("milter_write(%s): cmd %c, len %ld\n",
556 			   m->mf_name, command, (long) len);
557 
558 	nl = htonl(len + 1);	/* add 1 for the command char */
559 	(void) memcpy(data, (char *) &nl, MILTER_LEN_BYTES);
560 	data[MILTER_LEN_BYTES] = command;
561 	sl = MILTER_LEN_BYTES + 1;
562 
563 	/* set up the vector for the size / command */
564 	vector[0].iov_base = (void *) data;
565 	vector[0].iov_len  = sl;
566 
567 	/*
568 	**  Determine if there is command data.  If so, there will be two
569 	**  vectors.  If not, there will be only one.  The vectors are set
570 	**  up here and 'num_vectors' and 'sl' are set appropriately.
571 	*/
572 
573 	/* NOTE:  len<0 has already been checked for.  Pedantic */
574 	if (len <= 0 || buf == NULL)
575 	{
576 		/* There is no command data -- only a size / command data */
577 		num_vectors = 1;
578 	}
579 	else
580 	{
581 		/*
582 		**  There is both size / command and command data.
583 		**  Set up the vector for the command data.
584 		*/
585 
586 		num_vectors = 2;
587 		sl += len;
588 		vector[1].iov_base = (void *) buf;
589 		vector[1].iov_len  = len;
590 
591 		if (tTd(64, 50))
592 			sm_dprintf("milter_write(%s): Sending %*s\n",
593 				   m->mf_name, (int) len, buf);
594 	}
595 
596 	if (to > 0)
597 	{
598 		writestart = curtime();
599 		MILTER_TIMEOUT("write", to, true, started, where);
600 	}
601 
602 	/* write the vector(s) */
603 	i = writev(m->mf_sock, vector, num_vectors);
604 	if (i != sl)
605 	{
606 		int save_errno = errno;
607 
608 		if (tTd(64, 5))
609 			sm_dprintf("milter_write(%s): write(%c) returned %ld, expected %ld: %s\n",
610 				   m->mf_name, command, (long) i, (long) sl,
611 				   sm_errstring(save_errno));
612 		if (MilterLogLevel > 0)
613 			sm_syslog(LOG_ERR, e->e_id,
614 				  "Milter (%s): write(%c) returned %ld, expected %ld: %s",
615 				  m->mf_name, command, (long) i, (long) sl,
616 				  sm_errstring(save_errno));
617 		milter_error(m, e);
618 		return NULL;
619 	}
620 	return buf;
621 }
622 
623 /*
624 **  Utility functions
625 */
626 
627 /*
628 **  MILTER_OPEN -- connect to remote milter filter
629 **
630 **	Parameters:
631 **		m -- milter to connect to.
632 **		parseonly -- parse but don't connect.
633 **		e -- current envelope.
634 **
635 **	Returns:
636 **		connected socket if successful && !parseonly,
637 **		0 upon parse success if parseonly,
638 **		-1 otherwise.
639 */
640 
641 static jmp_buf	MilterConnectTimeout;
642 
643 static int
644 milter_open(m, parseonly, e)
645 	struct milter *m;
646 	bool parseonly;
647 	ENVELOPE *e;
648 {
649 	int sock = 0;
650 	SOCKADDR_LEN_T addrlen = 0;
651 	int addrno = 0;
652 	int save_errno;
653 	char *p;
654 	char *colon;
655 	char *at;
656 	struct hostent *hp = NULL;
657 	SOCKADDR addr;
658 
659 	if (m->mf_conn == NULL || m->mf_conn[0] == '\0')
660 	{
661 		if (tTd(64, 5))
662 			sm_dprintf("X%s: empty or missing socket information\n",
663 				   m->mf_name);
664 		if (parseonly)
665 			syserr("X%s: empty or missing socket information",
666 			       m->mf_name);
667 		else if (MilterLogLevel > 0)
668 			sm_syslog(LOG_ERR, e->e_id,
669 				  "Milter (%s): empty or missing socket information",
670 				  m->mf_name);
671 		milter_error(m, e);
672 		return -1;
673 	}
674 
675 	/* protocol:filename or protocol:port@host */
676 	memset(&addr, '\0', sizeof(addr));
677 	p = m->mf_conn;
678 	colon = strchr(p, ':');
679 	if (colon != NULL)
680 	{
681 		*colon = '\0';
682 
683 		if (*p == '\0')
684 		{
685 # if NETUNIX
686 			/* default to AF_UNIX */
687 			addr.sa.sa_family = AF_UNIX;
688 # else /* NETUNIX */
689 #  if NETINET
690 			/* default to AF_INET */
691 			addr.sa.sa_family = AF_INET;
692 #  else /* NETINET */
693 #   if NETINET6
694 			/* default to AF_INET6 */
695 			addr.sa.sa_family = AF_INET6;
696 #   else /* NETINET6 */
697 			/* no protocols available */
698 			if (MilterLogLevel > 0)
699 				sm_syslog(LOG_ERR, e->e_id,
700 					  "Milter (%s): no valid socket protocols available",
701 					  m->mf_name);
702 			milter_error(m, e);
703 			return -1;
704 #   endif /* NETINET6 */
705 #  endif /* NETINET */
706 # endif /* NETUNIX */
707 		}
708 # if NETUNIX
709 		else if (sm_strcasecmp(p, "unix") == 0 ||
710 			 sm_strcasecmp(p, "local") == 0)
711 			addr.sa.sa_family = AF_UNIX;
712 # endif /* NETUNIX */
713 # if NETINET
714 		else if (sm_strcasecmp(p, "inet") == 0)
715 			addr.sa.sa_family = AF_INET;
716 # endif /* NETINET */
717 # if NETINET6
718 		else if (sm_strcasecmp(p, "inet6") == 0)
719 			addr.sa.sa_family = AF_INET6;
720 # endif /* NETINET6 */
721 		else
722 		{
723 # ifdef EPROTONOSUPPORT
724 			errno = EPROTONOSUPPORT;
725 # else /* EPROTONOSUPPORT */
726 			errno = EINVAL;
727 # endif /* EPROTONOSUPPORT */
728 			if (tTd(64, 5))
729 				sm_dprintf("X%s: unknown socket type %s\n",
730 					m->mf_name, p);
731 			if (parseonly)
732 				syserr("X%s: unknown socket type %s",
733 				       m->mf_name, p);
734 			else if (MilterLogLevel > 0)
735 				sm_syslog(LOG_ERR, e->e_id,
736 					  "Milter (%s): unknown socket type %s",
737 					  m->mf_name, p);
738 			milter_error(m, e);
739 			return -1;
740 		}
741 		*colon++ = ':';
742 	}
743 	else
744 	{
745 		/* default to AF_UNIX */
746 		addr.sa.sa_family = AF_UNIX;
747 		colon = p;
748 	}
749 
750 # if NETUNIX
751 	if (addr.sa.sa_family == AF_UNIX)
752 	{
753 		long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_EXECOK;
754 
755 		at = colon;
756 		if (strlen(colon) >= sizeof(addr.sunix.sun_path))
757 		{
758 			if (tTd(64, 5))
759 				sm_dprintf("X%s: local socket name %s too long\n",
760 					m->mf_name, colon);
761 			errno = EINVAL;
762 			if (parseonly)
763 				syserr("X%s: local socket name %s too long",
764 				       m->mf_name, colon);
765 			else if (MilterLogLevel > 0)
766 				sm_syslog(LOG_ERR, e->e_id,
767 					  "Milter (%s): local socket name %s too long",
768 					  m->mf_name, colon);
769 			milter_error(m, e);
770 			return -1;
771 		}
772 		errno = safefile(colon, RunAsUid, RunAsGid, RunAsUserName, sff,
773 				 S_IRUSR|S_IWUSR, NULL);
774 
775 		/* if just parsing .cf file, socket doesn't need to exist */
776 		if (parseonly && errno == ENOENT)
777 		{
778 			if (OpMode == MD_DAEMON ||
779 			    OpMode == MD_FGDAEMON)
780 				(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
781 						     "WARNING: X%s: local socket name %s missing\n",
782 						     m->mf_name, colon);
783 		}
784 		else if (errno != 0)
785 		{
786 			/* if not safe, don't create */
787 			save_errno = errno;
788 			if (tTd(64, 5))
789 				sm_dprintf("X%s: local socket name %s unsafe\n",
790 					m->mf_name, colon);
791 			errno = save_errno;
792 			if (parseonly)
793 			{
794 				if (OpMode == MD_DAEMON ||
795 				    OpMode == MD_FGDAEMON ||
796 				    OpMode == MD_SMTP)
797 					syserr("X%s: local socket name %s unsafe",
798 					       m->mf_name, colon);
799 			}
800 			else if (MilterLogLevel > 0)
801 				sm_syslog(LOG_ERR, e->e_id,
802 					  "Milter (%s): local socket name %s unsafe",
803 					  m->mf_name, colon);
804 			milter_error(m, e);
805 			return -1;
806 		}
807 
808 		(void) sm_strlcpy(addr.sunix.sun_path, colon,
809 			       sizeof(addr.sunix.sun_path));
810 		addrlen = sizeof(struct sockaddr_un);
811 	}
812 	else
813 # endif /* NETUNIX */
814 # if NETINET || NETINET6
815 	if (false
816 #  if NETINET
817 		 || addr.sa.sa_family == AF_INET
818 #  endif /* NETINET */
819 #  if NETINET6
820 		 || addr.sa.sa_family == AF_INET6
821 #  endif /* NETINET6 */
822 		 )
823 	{
824 		unsigned short port;
825 
826 		/* Parse port@host */
827 		at = strchr(colon, '@');
828 		if (at == NULL)
829 		{
830 			if (tTd(64, 5))
831 				sm_dprintf("X%s: bad address %s (expected port@host)\n",
832 					m->mf_name, colon);
833 			if (parseonly)
834 				syserr("X%s: bad address %s (expected port@host)",
835 				       m->mf_name, colon);
836 			else if (MilterLogLevel > 0)
837 				sm_syslog(LOG_ERR, e->e_id,
838 					  "Milter (%s): bad address %s (expected port@host)",
839 					  m->mf_name, colon);
840 			milter_error(m, e);
841 			return -1;
842 		}
843 		*at = '\0';
844 		if (isascii(*colon) && isdigit(*colon))
845 			port = htons((unsigned short) atoi(colon));
846 		else
847 		{
848 #  ifdef NO_GETSERVBYNAME
849 			if (tTd(64, 5))
850 				sm_dprintf("X%s: invalid port number %s\n",
851 					m->mf_name, colon);
852 			if (parseonly)
853 				syserr("X%s: invalid port number %s",
854 				       m->mf_name, colon);
855 			else if (MilterLogLevel > 0)
856 				sm_syslog(LOG_ERR, e->e_id,
857 					  "Milter (%s): invalid port number %s",
858 					  m->mf_name, colon);
859 			milter_error(m, e);
860 			return -1;
861 #  else /* NO_GETSERVBYNAME */
862 			struct servent *sp;
863 
864 			sp = getservbyname(colon, "tcp");
865 			if (sp == NULL)
866 			{
867 				save_errno = errno;
868 				if (tTd(64, 5))
869 					sm_dprintf("X%s: unknown port name %s\n",
870 						m->mf_name, colon);
871 				errno = save_errno;
872 				if (parseonly)
873 					syserr("X%s: unknown port name %s",
874 					       m->mf_name, colon);
875 				else if (MilterLogLevel > 0)
876 					sm_syslog(LOG_ERR, e->e_id,
877 						  "Milter (%s): unknown port name %s",
878 						  m->mf_name, colon);
879 				milter_error(m, e);
880 				return -1;
881 			}
882 			port = sp->s_port;
883 #  endif /* NO_GETSERVBYNAME */
884 		}
885 		*at++ = '@';
886 		if (*at == '[')
887 		{
888 			char *end;
889 
890 			end = strchr(at, ']');
891 			if (end != NULL)
892 			{
893 				bool found = false;
894 #  if NETINET
895 				unsigned long hid = INADDR_NONE;
896 #  endif /* NETINET */
897 #  if NETINET6
898 				struct sockaddr_in6 hid6;
899 #  endif /* NETINET6 */
900 
901 				*end = '\0';
902 #  if NETINET
903 				if (addr.sa.sa_family == AF_INET &&
904 				    (hid = inet_addr(&at[1])) != INADDR_NONE)
905 				{
906 					addr.sin.sin_addr.s_addr = hid;
907 					addr.sin.sin_port = port;
908 					found = true;
909 				}
910 #  endif /* NETINET */
911 #  if NETINET6
912 				(void) memset(&hid6, '\0', sizeof(hid6));
913 				if (addr.sa.sa_family == AF_INET6 &&
914 				    anynet_pton(AF_INET6, &at[1],
915 						&hid6.sin6_addr) == 1)
916 				{
917 					addr.sin6.sin6_addr = hid6.sin6_addr;
918 					addr.sin6.sin6_port = port;
919 					found = true;
920 				}
921 #  endif /* NETINET6 */
922 				*end = ']';
923 				if (!found)
924 				{
925 					if (tTd(64, 5))
926 						sm_dprintf("X%s: Invalid numeric domain spec \"%s\"\n",
927 							m->mf_name, at);
928 					if (parseonly)
929 						syserr("X%s: Invalid numeric domain spec \"%s\"",
930 						       m->mf_name, at);
931 					else if (MilterLogLevel > 0)
932 						sm_syslog(LOG_ERR, e->e_id,
933 							  "Milter (%s): Invalid numeric domain spec \"%s\"",
934 							  m->mf_name, at);
935 					milter_error(m, e);
936 					return -1;
937 				}
938 			}
939 			else
940 			{
941 				if (tTd(64, 5))
942 					sm_dprintf("X%s: Invalid numeric domain spec \"%s\"\n",
943 						m->mf_name, at);
944 				if (parseonly)
945 					syserr("X%s: Invalid numeric domain spec \"%s\"",
946 					       m->mf_name, at);
947 				else if (MilterLogLevel > 0)
948 					sm_syslog(LOG_ERR, e->e_id,
949 						  "Milter (%s): Invalid numeric domain spec \"%s\"",
950 						  m->mf_name, at);
951 				milter_error(m, e);
952 				return -1;
953 			}
954 		}
955 		else
956 		{
957 			hp = sm_gethostbyname(at, addr.sa.sa_family);
958 			if (hp == NULL)
959 			{
960 				save_errno = errno;
961 				if (tTd(64, 5))
962 					sm_dprintf("X%s: Unknown host name %s\n",
963 						   m->mf_name, at);
964 				errno = save_errno;
965 				if (parseonly)
966 					syserr("X%s: Unknown host name %s",
967 					       m->mf_name, at);
968 				else if (MilterLogLevel > 0)
969 					sm_syslog(LOG_ERR, e->e_id,
970 						  "Milter (%s): Unknown host name %s",
971 						  m->mf_name, at);
972 				milter_error(m, e);
973 				return -1;
974 			}
975 			addr.sa.sa_family = hp->h_addrtype;
976 			switch (hp->h_addrtype)
977 			{
978 #  if NETINET
979 			  case AF_INET:
980 				memmove(&addr.sin.sin_addr,
981 					hp->h_addr, INADDRSZ);
982 				addr.sin.sin_port = port;
983 				addrlen = sizeof(struct sockaddr_in);
984 				addrno = 1;
985 				break;
986 #  endif /* NETINET */
987 
988 #  if NETINET6
989 			  case AF_INET6:
990 				memmove(&addr.sin6.sin6_addr,
991 					hp->h_addr, IN6ADDRSZ);
992 				addr.sin6.sin6_port = port;
993 				addrlen = sizeof(struct sockaddr_in6);
994 				addrno = 1;
995 				break;
996 #  endif /* NETINET6 */
997 
998 			  default:
999 				if (tTd(64, 5))
1000 					sm_dprintf("X%s: Unknown protocol for %s (%d)\n",
1001 						   m->mf_name, at,
1002 						   hp->h_addrtype);
1003 				if (parseonly)
1004 					syserr("X%s: Unknown protocol for %s (%d)",
1005 					       m->mf_name, at, hp->h_addrtype);
1006 				else if (MilterLogLevel > 0)
1007 					sm_syslog(LOG_ERR, e->e_id,
1008 						  "Milter (%s): Unknown protocol for %s (%d)",
1009 						  m->mf_name, at,
1010 						  hp->h_addrtype);
1011 				milter_error(m, e);
1012 #  if NETINET6
1013 				freehostent(hp);
1014 #  endif /* NETINET6 */
1015 				return -1;
1016 			}
1017 		}
1018 	}
1019 	else
1020 # endif /* NETINET || NETINET6 */
1021 	{
1022 		if (tTd(64, 5))
1023 			sm_dprintf("X%s: unknown socket protocol\n",
1024 				   m->mf_name);
1025 		if (parseonly)
1026 			syserr("X%s: unknown socket protocol", m->mf_name);
1027 		else if (MilterLogLevel > 0)
1028 			sm_syslog(LOG_ERR, e->e_id,
1029 				  "Milter (%s): unknown socket protocol",
1030 				  m->mf_name);
1031 		milter_error(m, e);
1032 		return -1;
1033 	}
1034 
1035 	/* just parsing through? */
1036 	if (parseonly)
1037 	{
1038 		m->mf_state = SMFS_READY;
1039 # if NETINET6
1040 		if (hp != NULL)
1041 			freehostent(hp);
1042 # endif /* NETINET6 */
1043 		return 0;
1044 	}
1045 
1046 	/* sanity check */
1047 	if (m->mf_state != SMFS_READY &&
1048 	    m->mf_state != SMFS_CLOSED)
1049 	{
1050 		/* shouldn't happen */
1051 		if (tTd(64, 1))
1052 			sm_dprintf("Milter (%s): Trying to open filter in state %c\n",
1053 				   m->mf_name, (char) m->mf_state);
1054 		milter_error(m, e);
1055 # if NETINET6
1056 		if (hp != NULL)
1057 			freehostent(hp);
1058 # endif /* NETINET6 */
1059 		return -1;
1060 	}
1061 
1062 	/* nope, actually connecting */
1063 	for (;;)
1064 	{
1065 		sock = socket(addr.sa.sa_family, SOCK_STREAM, 0);
1066 		if (sock < 0)
1067 		{
1068 			save_errno = errno;
1069 			if (tTd(64, 5))
1070 				sm_dprintf("Milter (%s): error creating socket: %s\n",
1071 					   m->mf_name,
1072 					   sm_errstring(save_errno));
1073 			if (MilterLogLevel > 0)
1074 				sm_syslog(LOG_ERR, e->e_id,
1075 					  "Milter (%s): error creating socket: %s",
1076 					  m->mf_name, sm_errstring(save_errno));
1077 			milter_error(m, e);
1078 # if NETINET6
1079 			if (hp != NULL)
1080 				freehostent(hp);
1081 # endif /* NETINET6 */
1082 			return -1;
1083 		}
1084 
1085 		if (setjmp(MilterConnectTimeout) == 0)
1086 		{
1087 			SM_EVENT *ev = NULL;
1088 			int i;
1089 
1090 			if (m->mf_timeout[SMFTO_CONNECT] > 0)
1091 				ev = sm_setevent(m->mf_timeout[SMFTO_CONNECT],
1092 						 milter_connect_timeout, 0);
1093 
1094 			i = connect(sock, (struct sockaddr *) &addr, addrlen);
1095 			save_errno = errno;
1096 			if (ev != NULL)
1097 				sm_clrevent(ev);
1098 			errno = save_errno;
1099 			if (i >= 0)
1100 				break;
1101 		}
1102 
1103 		/* couldn't connect.... try next address */
1104 		save_errno = errno;
1105 		p = CurHostName;
1106 		CurHostName = at;
1107 		if (tTd(64, 5))
1108 			sm_dprintf("milter_open (%s): open %s failed: %s\n",
1109 				   m->mf_name, at, sm_errstring(save_errno));
1110 		if (MilterLogLevel > 13)
1111 			sm_syslog(LOG_INFO, e->e_id,
1112 				  "Milter (%s): open %s failed: %s",
1113 				  m->mf_name, at, sm_errstring(save_errno));
1114 		CurHostName = p;
1115 		(void) close(sock);
1116 
1117 		/* try next address */
1118 		if (hp != NULL && hp->h_addr_list[addrno] != NULL)
1119 		{
1120 			switch (addr.sa.sa_family)
1121 			{
1122 # if NETINET
1123 			  case AF_INET:
1124 				memmove(&addr.sin.sin_addr,
1125 					hp->h_addr_list[addrno++],
1126 					INADDRSZ);
1127 				break;
1128 # endif /* NETINET */
1129 
1130 # if NETINET6
1131 			  case AF_INET6:
1132 				memmove(&addr.sin6.sin6_addr,
1133 					hp->h_addr_list[addrno++],
1134 					IN6ADDRSZ);
1135 				break;
1136 # endif /* NETINET6 */
1137 
1138 			  default:
1139 				if (tTd(64, 5))
1140 					sm_dprintf("X%s: Unknown protocol for %s (%d)\n",
1141 						   m->mf_name, at,
1142 						   hp->h_addrtype);
1143 				if (MilterLogLevel > 0)
1144 					sm_syslog(LOG_ERR, e->e_id,
1145 						  "Milter (%s): Unknown protocol for %s (%d)",
1146 						  m->mf_name, at,
1147 						  hp->h_addrtype);
1148 				milter_error(m, e);
1149 # if NETINET6
1150 				freehostent(hp);
1151 # endif /* NETINET6 */
1152 				return -1;
1153 			}
1154 			continue;
1155 		}
1156 		p = CurHostName;
1157 		CurHostName = at;
1158 		if (tTd(64, 5))
1159 			sm_dprintf("X%s: error connecting to filter: %s\n",
1160 				   m->mf_name, sm_errstring(save_errno));
1161 		if (MilterLogLevel > 0)
1162 			sm_syslog(LOG_ERR, e->e_id,
1163 				  "Milter (%s): error connecting to filter: %s",
1164 				  m->mf_name, sm_errstring(save_errno));
1165 		CurHostName = p;
1166 		milter_error(m, e);
1167 # if NETINET6
1168 		if (hp != NULL)
1169 			freehostent(hp);
1170 # endif /* NETINET6 */
1171 		return -1;
1172 	}
1173 	m->mf_state = SMFS_OPEN;
1174 # if NETINET6
1175 	if (hp != NULL)
1176 	{
1177 		freehostent(hp);
1178 		hp = NULL;
1179 	}
1180 # endif /* NETINET6 */
1181 # if MILTER_NO_NAGLE && !defined(TCP_CORK)
1182 	{
1183 		int nodelay = 1;
1184 
1185 		setsockopt(m->mf_sock, IPPROTO_TCP, TCP_NODELAY,
1186 			   (char *)&nodelay, sizeof(nodelay));
1187 	}
1188 # endif /* MILTER_NO_NAGLE && !defined(TCP_CORK) */
1189 	return sock;
1190 }
1191 
1192 static void
1193 milter_connect_timeout(ignore)
1194 	int ignore;
1195 {
1196 	/*
1197 	**  NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER.  DO NOT ADD
1198 	**	ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
1199 	**	DOING.
1200 	*/
1201 
1202 	errno = ETIMEDOUT;
1203 	longjmp(MilterConnectTimeout, 1);
1204 }
1205 
1206 /*
1207 **  MILTER_SETUP -- setup structure for a mail filter
1208 **
1209 **	Parameters:
1210 **		line -- the options line.
1211 **
1212 **	Returns:
1213 **		none
1214 */
1215 
1216 void
1217 milter_setup(line)
1218 	char *line;
1219 {
1220 	char fcode;
1221 	char *p;
1222 	struct milter *m;
1223 	STAB *s;
1224 
1225 	/* collect the filter name */
1226 	for (p = line;
1227 	     *p != '\0' && *p != ',' && !(isascii(*p) && isspace(*p));
1228 	     p++)
1229 		continue;
1230 	if (*p != '\0')
1231 		*p++ = '\0';
1232 	if (line[0] == '\0')
1233 	{
1234 		syserr("name required for mail filter");
1235 		return;
1236 	}
1237 	m = (struct milter *) xalloc(sizeof(*m));
1238 	memset((char *) m, '\0', sizeof(*m));
1239 	m->mf_name = newstr(line);
1240 	m->mf_state = SMFS_READY;
1241 	m->mf_sock = -1;
1242 	m->mf_timeout[SMFTO_CONNECT] = (time_t) 300;
1243 	m->mf_timeout[SMFTO_WRITE] = (time_t) 10;
1244 	m->mf_timeout[SMFTO_READ] = (time_t) 10;
1245 	m->mf_timeout[SMFTO_EOM] = (time_t) 300;
1246 #if _FFR_MILTER_CHECK
1247 	m->mf_mta_prot_version = SMFI_PROT_VERSION;
1248 	m->mf_mta_prot_flags = SMFI_CURR_PROT;
1249 	m->mf_mta_actions = SMFI_CURR_ACTS;
1250 #endif /* _FFR_MILTER_CHECK */
1251 
1252 	/* now scan through and assign info from the fields */
1253 	while (*p != '\0')
1254 	{
1255 		char *delimptr;
1256 
1257 		while (*p != '\0' &&
1258 		       (*p == ',' || (isascii(*p) && isspace(*p))))
1259 			p++;
1260 
1261 		/* p now points to field code */
1262 		fcode = *p;
1263 		while (*p != '\0' && *p != '=' && *p != ',')
1264 			p++;
1265 		if (*p++ != '=')
1266 		{
1267 			syserr("X%s: `=' expected", m->mf_name);
1268 			return;
1269 		}
1270 		while (isascii(*p) && isspace(*p))
1271 			p++;
1272 
1273 		/* p now points to the field body */
1274 		p = munchstring(p, &delimptr, ',');
1275 
1276 		/* install the field into the filter struct */
1277 		switch (fcode)
1278 		{
1279 		  case 'S':		/* socket */
1280 			if (p == NULL)
1281 				m->mf_conn = NULL;
1282 			else
1283 				m->mf_conn = newstr(p);
1284 			break;
1285 
1286 		  case 'F':		/* Milter flags configured on MTA */
1287 			for (; *p != '\0'; p++)
1288 			{
1289 				if (!(isascii(*p) && isspace(*p)))
1290 					setbitn(bitidx(*p), m->mf_flags);
1291 			}
1292 			break;
1293 
1294 		  case 'T':		/* timeouts */
1295 			milter_parse_timeouts(p, m);
1296 			break;
1297 
1298 #if _FFR_MILTER_CHECK
1299 		  case 'a':
1300 			m->mf_mta_actions = strtoul(p, NULL, 0);
1301 			break;
1302 		  case 'f':
1303 			m->mf_mta_prot_flags = strtoul(p, NULL, 0);
1304 			break;
1305 		  case 'v':
1306 			m->mf_mta_prot_version = strtoul(p, NULL, 0);
1307 			break;
1308 #endif /* _FFR_MILTER_CHECK */
1309 
1310 		  default:
1311 			syserr("X%s: unknown filter equate %c=",
1312 			       m->mf_name, fcode);
1313 			break;
1314 		}
1315 		p = delimptr;
1316 	}
1317 
1318 	/* early check for errors */
1319 	(void) milter_open(m, true, CurEnv);
1320 
1321 	/* enter the filter into the symbol table */
1322 	s = stab(m->mf_name, ST_MILTER, ST_ENTER);
1323 	if (s->s_milter != NULL)
1324 		syserr("X%s: duplicate filter definition", m->mf_name);
1325 	else
1326 		s->s_milter = m;
1327 }
1328 
1329 /*
1330 **  MILTER_CONFIG -- parse option list into an array and check config
1331 **
1332 **	Called when reading configuration file.
1333 **
1334 **	Parameters:
1335 **		spec -- the filter list.
1336 **		list -- the array to fill in.
1337 **		max -- the maximum number of entries in list.
1338 **
1339 **	Returns:
1340 **		none
1341 */
1342 
1343 void
1344 milter_config(spec, list, max)
1345 	char *spec;
1346 	struct milter **list;
1347 	int max;
1348 {
1349 	int numitems = 0;
1350 	char *p;
1351 
1352 	/* leave one for the NULL signifying the end of the list */
1353 	max--;
1354 
1355 	for (p = spec; p != NULL; )
1356 	{
1357 		STAB *s;
1358 
1359 		while (isascii(*p) && isspace(*p))
1360 			p++;
1361 		if (*p == '\0')
1362 			break;
1363 		spec = p;
1364 
1365 		if (numitems >= max)
1366 		{
1367 			syserr("Too many filters defined, %d max", max);
1368 			if (max > 0)
1369 				list[0] = NULL;
1370 			return;
1371 		}
1372 		p = strpbrk(p, ";,");
1373 		if (p != NULL)
1374 			*p++ = '\0';
1375 
1376 		s = stab(spec, ST_MILTER, ST_FIND);
1377 		if (s == NULL)
1378 		{
1379 			syserr("InputFilter %s not defined", spec);
1380 			ExitStat = EX_CONFIG;
1381 			return;
1382 		}
1383 		list[numitems++] = s->s_milter;
1384 	}
1385 	list[numitems] = NULL;
1386 
1387 	/* if not set, set to LogLevel */
1388 	if (MilterLogLevel == -1)
1389 		MilterLogLevel = LogLevel;
1390 }
1391 
1392 /*
1393 **  MILTER_PARSE_TIMEOUTS -- parse timeout list
1394 **
1395 **	Called when reading configuration file.
1396 **
1397 **	Parameters:
1398 **		spec -- the timeout list.
1399 **		m -- milter to set.
1400 **
1401 **	Returns:
1402 **		none
1403 */
1404 
1405 static void
1406 milter_parse_timeouts(spec, m)
1407 	char *spec;
1408 	struct milter *m;
1409 {
1410 	char fcode;
1411 	int tcode;
1412 	char *p;
1413 
1414 	p = spec;
1415 
1416 	/* now scan through and assign info from the fields */
1417 	while (*p != '\0')
1418 	{
1419 		char *delimptr;
1420 
1421 		while (*p != '\0' &&
1422 		       (*p == ';' || (isascii(*p) && isspace(*p))))
1423 			p++;
1424 
1425 		/* p now points to field code */
1426 		fcode = *p;
1427 		while (*p != '\0' && *p != ':')
1428 			p++;
1429 		if (*p++ != ':')
1430 		{
1431 			syserr("X%s, T=: `:' expected", m->mf_name);
1432 			return;
1433 		}
1434 		while (isascii(*p) && isspace(*p))
1435 			p++;
1436 
1437 		/* p now points to the field body */
1438 		p = munchstring(p, &delimptr, ';');
1439 		tcode = -1;
1440 
1441 		/* install the field into the filter struct */
1442 		switch (fcode)
1443 		{
1444 		  case 'C':
1445 			tcode = SMFTO_CONNECT;
1446 			break;
1447 
1448 		  case 'S':
1449 			tcode = SMFTO_WRITE;
1450 			break;
1451 
1452 		  case 'R':
1453 			tcode = SMFTO_READ;
1454 			break;
1455 
1456 		  case 'E':
1457 			tcode = SMFTO_EOM;
1458 			break;
1459 
1460 		  default:
1461 			if (tTd(64, 5))
1462 				sm_dprintf("X%s: %c unknown\n",
1463 					   m->mf_name, fcode);
1464 			syserr("X%s: unknown filter timeout %c",
1465 			       m->mf_name, fcode);
1466 			break;
1467 		}
1468 		if (tcode >= 0)
1469 		{
1470 			m->mf_timeout[tcode] = convtime(p, 's');
1471 			if (tTd(64, 5))
1472 				sm_dprintf("X%s: %c=%ld\n",
1473 					   m->mf_name, fcode,
1474 					   (u_long) m->mf_timeout[tcode]);
1475 		}
1476 		p = delimptr;
1477 	}
1478 }
1479 
1480 /*
1481 **  MILTER_SET_MACROS -- set milter macros
1482 **
1483 **	Parameters:
1484 **		name -- name of milter.
1485 **		macros -- where to store macros.
1486 **		val -- the value of the option.
1487 **		nummac -- current number of macros
1488 **
1489 **	Returns:
1490 **		new number of macros
1491 */
1492 
1493 static int
1494 milter_set_macros(name, macros, val, nummac)
1495 	char *name;
1496 	char **macros;
1497 	char *val;
1498 	int nummac;
1499 {
1500 	char *p;
1501 
1502 	p = newstr(val);
1503 	while (*p != '\0')
1504 	{
1505 		char *macro;
1506 
1507 		/* Skip leading commas, spaces */
1508 		while (*p != '\0' &&
1509 		       (*p == ',' || (isascii(*p) && isspace(*p))))
1510 			p++;
1511 
1512 		if (*p == '\0')
1513 			break;
1514 
1515 		/* Find end of macro */
1516 		macro = p;
1517 		while (*p != '\0' && *p != ',' &&
1518 		       isascii(*p) && !isspace(*p))
1519 			p++;
1520 		if (*p != '\0')
1521 			*p++ = '\0';
1522 
1523 		if (nummac >= MAXFILTERMACROS)
1524 		{
1525 			syserr("milter_set_option: too many macros in Milter.%s (max %d)",
1526 			       name, MAXFILTERMACROS);
1527 			macros[nummac] = NULL;
1528 			return -1;
1529 		}
1530 		macros[nummac++] = macro;
1531 	}
1532 	macros[nummac] = NULL;
1533 	return nummac;
1534 }
1535 
1536 /*
1537 **  MILTER_SET_OPTION -- set an individual milter option
1538 **
1539 **	Parameters:
1540 **		name -- the name of the option.
1541 **		val -- the value of the option.
1542 **		sticky -- if set, don't let other setoptions override
1543 **			this value.
1544 **
1545 **	Returns:
1546 **		none.
1547 */
1548 
1549 /* set if Milter sub-option is stuck */
1550 static BITMAP256	StickyMilterOpt;
1551 
1552 static struct milteropt
1553 {
1554 	char		*mo_name;	/* long name of milter option */
1555 	unsigned char	mo_code;	/* code for option */
1556 } MilterOptTab[] =
1557 {
1558 # define MO_MACROS_CONNECT		SMFIM_CONNECT
1559 	{ "macros.connect",		MO_MACROS_CONNECT		},
1560 # define MO_MACROS_HELO			SMFIM_HELO
1561 	{ "macros.helo",		MO_MACROS_HELO			},
1562 # define MO_MACROS_ENVFROM		SMFIM_ENVFROM
1563 	{ "macros.envfrom",		MO_MACROS_ENVFROM		},
1564 # define MO_MACROS_ENVRCPT		SMFIM_ENVRCPT
1565 	{ "macros.envrcpt",		MO_MACROS_ENVRCPT		},
1566 # define MO_MACROS_DATA			SMFIM_DATA
1567 	{ "macros.data",		MO_MACROS_DATA			},
1568 # define MO_MACROS_EOM			SMFIM_EOM
1569 	{ "macros.eom",			MO_MACROS_EOM			},
1570 # define MO_MACROS_EOH			SMFIM_EOH
1571 	{ "macros.eoh",			MO_MACROS_EOH			},
1572 
1573 # define MO_LOGLEVEL			0x07
1574 	{ "loglevel",			MO_LOGLEVEL			},
1575 # if _FFR_MAXDATASIZE
1576 #  define MO_MAXDATASIZE		0x08
1577 	{ "maxdatasize",		MO_MAXDATASIZE			},
1578 # endif /* _FFR_MAXDATASIZE */
1579 	{ NULL,				(unsigned char)-1		},
1580 };
1581 
1582 void
1583 milter_set_option(name, val, sticky)
1584 	char *name;
1585 	char *val;
1586 	bool sticky;
1587 {
1588 	int nummac, r;
1589 	struct milteropt *mo;
1590 	char **macros = NULL;
1591 
1592 	nummac = 0;
1593 	if (tTd(37, 2) || tTd(64, 5))
1594 		sm_dprintf("milter_set_option(%s = %s)", name, val);
1595 
1596 	if (name == NULL)
1597 	{
1598 		syserr("milter_set_option: invalid Milter option, must specify suboption");
1599 		return;
1600 	}
1601 
1602 	for (mo = MilterOptTab; mo->mo_name != NULL; mo++)
1603 	{
1604 		if (sm_strcasecmp(mo->mo_name, name) == 0)
1605 			break;
1606 	}
1607 
1608 	if (mo->mo_name == NULL)
1609 	{
1610 		syserr("milter_set_option: invalid Milter option %s", name);
1611 		return;
1612 	}
1613 
1614 	/*
1615 	**  See if this option is preset for us.
1616 	*/
1617 
1618 	if (!sticky && bitnset(mo->mo_code, StickyMilterOpt))
1619 	{
1620 		if (tTd(37, 2) || tTd(64,5))
1621 			sm_dprintf(" (ignored)\n");
1622 		return;
1623 	}
1624 
1625 	if (tTd(37, 2) || tTd(64,5))
1626 		sm_dprintf("\n");
1627 
1628 	switch (mo->mo_code)
1629 	{
1630 	  case MO_LOGLEVEL:
1631 		MilterLogLevel = atoi(val);
1632 		break;
1633 
1634 #if _FFR_MAXDATASIZE
1635 	  case MO_MAXDATASIZE:
1636 		MilterMaxDataSize = (size_t)atol(val);
1637 		break;
1638 #endif /* _FFR_MAXDATASIZE */
1639 
1640 	  case MO_MACROS_CONNECT:
1641 		if (macros == NULL)
1642 			macros = MilterConnectMacros;
1643 		/* FALLTHROUGH */
1644 
1645 	  case MO_MACROS_HELO:
1646 		if (macros == NULL)
1647 			macros = MilterHeloMacros;
1648 		/* FALLTHROUGH */
1649 
1650 	  case MO_MACROS_ENVFROM:
1651 		if (macros == NULL)
1652 			macros = MilterEnvFromMacros;
1653 		/* FALLTHROUGH */
1654 
1655 	  case MO_MACROS_ENVRCPT:
1656 		if (macros == NULL)
1657 			macros = MilterEnvRcptMacros;
1658 		/* FALLTHROUGH */
1659 
1660 	  case MO_MACROS_EOH:
1661 		if (macros == NULL)
1662 			macros = MilterEOHMacros;
1663 		/* FALLTHROUGH */
1664 
1665 	  case MO_MACROS_EOM:
1666 		if (macros == NULL)
1667 			macros = MilterEOMMacros;
1668 		/* FALLTHROUGH */
1669 
1670 	  case MO_MACROS_DATA:
1671 		if (macros == NULL)
1672 			macros = MilterDataMacros;
1673 
1674 		r = milter_set_macros(name, macros, val, nummac);
1675 		if (r >= 0)
1676 			nummac = r;
1677 		break;
1678 
1679 	  default:
1680 		syserr("milter_set_option: invalid Milter option %s", name);
1681 		break;
1682 	}
1683 	if (sticky)
1684 		setbitn(mo->mo_code, StickyMilterOpt);
1685 }
1686 
1687 /*
1688 **  MILTER_REOPEN_DF -- open & truncate the data file (for replbody)
1689 **
1690 **	Parameters:
1691 **		e -- current envelope.
1692 **
1693 **	Returns:
1694 **		0 if succesful, -1 otherwise
1695 */
1696 
1697 static int
1698 milter_reopen_df(e)
1699 	ENVELOPE *e;
1700 {
1701 	char dfname[MAXPATHLEN];
1702 
1703 	(void) sm_strlcpy(dfname, queuename(e, DATAFL_LETTER), sizeof(dfname));
1704 
1705 	/*
1706 	**  In SuperSafe == SAFE_REALLY mode, e->e_dfp is a read-only FP so
1707 	**  close and reopen writable (later close and reopen
1708 	**  read only again).
1709 	**
1710 	**  In SuperSafe != SAFE_REALLY mode, e->e_dfp still points at the
1711 	**  buffered file I/O descriptor, still open for writing so there
1712 	**  isn't any work to do here (except checking for consistency).
1713 	*/
1714 
1715 	if (SuperSafe == SAFE_REALLY)
1716 	{
1717 		/* close read-only data file */
1718 		if (bitset(EF_HAS_DF, e->e_flags) && e->e_dfp != NULL)
1719 		{
1720 			(void) sm_io_close(e->e_dfp, SM_TIME_DEFAULT);
1721 			e->e_flags &= ~EF_HAS_DF;
1722 		}
1723 
1724 		/* open writable */
1725 		if ((e->e_dfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, dfname,
1726 					   SM_IO_RDWR_B, NULL)) == NULL)
1727 		{
1728 			MILTER_DF_ERROR("milter_reopen_df: sm_io_open %s: %s");
1729 			return -1;
1730 		}
1731 	}
1732 	else if (e->e_dfp == NULL)
1733 	{
1734 		/* shouldn't happen */
1735 		errno = ENOENT;
1736 		MILTER_DF_ERROR("milter_reopen_df: NULL e_dfp (%s: %s)");
1737 		return -1;
1738 	}
1739 	return 0;
1740 }
1741 
1742 /*
1743 **  MILTER_RESET_DF -- re-open read-only the data file (for replbody)
1744 **
1745 **	Parameters:
1746 **		e -- current envelope.
1747 **
1748 **	Returns:
1749 **		0 if succesful, -1 otherwise
1750 */
1751 
1752 static int
1753 milter_reset_df(e)
1754 	ENVELOPE *e;
1755 {
1756 	int afd;
1757 	char dfname[MAXPATHLEN];
1758 
1759 	(void) sm_strlcpy(dfname, queuename(e, DATAFL_LETTER), sizeof(dfname));
1760 
1761 	if (sm_io_flush(e->e_dfp, SM_TIME_DEFAULT) != 0 ||
1762 	    sm_io_error(e->e_dfp))
1763 	{
1764 		MILTER_DF_ERROR("milter_reset_df: error writing/flushing %s: %s");
1765 		return -1;
1766 	}
1767 	else if (SuperSafe != SAFE_REALLY)
1768 	{
1769 		/* skip next few clauses */
1770 		/* EMPTY */
1771 	}
1772 	else if ((afd = sm_io_getinfo(e->e_dfp, SM_IO_WHAT_FD, NULL)) >= 0
1773 		 && fsync(afd) < 0)
1774 	{
1775 		MILTER_DF_ERROR("milter_reset_df: error sync'ing %s: %s");
1776 		return -1;
1777 	}
1778 	else if (sm_io_close(e->e_dfp, SM_TIME_DEFAULT) < 0)
1779 	{
1780 		MILTER_DF_ERROR("milter_reset_df: error closing %s: %s");
1781 		return -1;
1782 	}
1783 	else if ((e->e_dfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, dfname,
1784 					SM_IO_RDONLY_B, NULL)) == NULL)
1785 	{
1786 		MILTER_DF_ERROR("milter_reset_df: error reopening %s: %s");
1787 		return -1;
1788 	}
1789 	else
1790 		e->e_flags |= EF_HAS_DF;
1791 	return 0;
1792 }
1793 
1794 /*
1795 **  MILTER_QUIT_FILTER -- close down a single filter
1796 **
1797 **	Parameters:
1798 **		m -- milter structure of filter to close down.
1799 **		e -- current envelope.
1800 **
1801 **	Returns:
1802 **		none
1803 */
1804 
1805 static void
1806 milter_quit_filter(m, e)
1807 	struct milter *m;
1808 	ENVELOPE *e;
1809 {
1810 	if (tTd(64, 10))
1811 		sm_dprintf("milter_quit_filter(%s)\n", m->mf_name);
1812 	if (MilterLogLevel > 18)
1813 		sm_syslog(LOG_INFO, e->e_id, "Milter (%s): quit filter",
1814 			  m->mf_name);
1815 
1816 	/* Never replace error state */
1817 	if (m->mf_state == SMFS_ERROR)
1818 		return;
1819 
1820 	if (m->mf_sock < 0 ||
1821 	    m->mf_state == SMFS_CLOSED ||
1822 	    m->mf_state == SMFS_READY)
1823 	{
1824 		m->mf_sock = -1;
1825 		m->mf_state = SMFS_CLOSED;
1826 		return;
1827 	}
1828 
1829 	(void) milter_write(m, SMFIC_QUIT, (char *) NULL, 0,
1830 			    m->mf_timeout[SMFTO_WRITE], e, "quit_filter");
1831 	if (m->mf_sock >= 0)
1832 	{
1833 		(void) close(m->mf_sock);
1834 		m->mf_sock = -1;
1835 	}
1836 	if (m->mf_state != SMFS_ERROR)
1837 		m->mf_state = SMFS_CLOSED;
1838 }
1839 
1840 /*
1841 **  MILTER_ABORT_FILTER -- tell filter to abort current message
1842 **
1843 **	Parameters:
1844 **		m -- milter structure of filter to abort.
1845 **		e -- current envelope.
1846 **
1847 **	Returns:
1848 **		none
1849 */
1850 
1851 static void
1852 milter_abort_filter(m, e)
1853 	struct milter *m;
1854 	ENVELOPE *e;
1855 {
1856 	if (tTd(64, 10))
1857 		sm_dprintf("milter_abort_filter(%s)\n", m->mf_name);
1858 	if (MilterLogLevel > 10)
1859 		sm_syslog(LOG_INFO, e->e_id, "Milter (%s): abort filter",
1860 			  m->mf_name);
1861 
1862 	if (m->mf_sock < 0 ||
1863 	    m->mf_state != SMFS_INMSG)
1864 		return;
1865 
1866 	(void) milter_write(m, SMFIC_ABORT, (char *) NULL, 0,
1867 			    m->mf_timeout[SMFTO_WRITE], e, "abort_filter");
1868 	if (m->mf_state != SMFS_ERROR)
1869 		m->mf_state = SMFS_DONE;
1870 }
1871 
1872 /*
1873 **  MILTER_SEND_MACROS -- provide macros to the filters
1874 **
1875 **	Parameters:
1876 **		m -- milter to send macros to.
1877 **		macros -- macros to send for filter smfi_getsymval().
1878 **		cmd -- which command the macros are associated with.
1879 **		e -- current envelope (for macro access).
1880 **
1881 **	Returns:
1882 **		none
1883 */
1884 
1885 static void
1886 milter_send_macros(m, macros, cmd, e)
1887 	struct milter *m;
1888 	char **macros;
1889 	int cmd;
1890 	ENVELOPE *e;
1891 {
1892 	int i;
1893 	int mid;
1894 	char command = (char) cmd;
1895 	char *v;
1896 	char *buf, *bp;
1897 	char exp[MAXLINE];
1898 	ssize_t s;
1899 
1900 	/* sanity check */
1901 	if (macros == NULL || macros[0] == NULL)
1902 		return;
1903 
1904 	/* put together data */
1905 	s = 1;			/* for the command character */
1906 	for (i = 0; macros[i] != NULL; i++)
1907 	{
1908 		mid = macid(macros[i]);
1909 		if (mid == 0)
1910 			continue;
1911 		v = macvalue(mid, e);
1912 		if (v == NULL)
1913 			continue;
1914 		expand(v, exp, sizeof(exp), e);
1915 		s += strlen(macros[i]) + 1 + strlen(exp) + 1;
1916 	}
1917 
1918 	if (s < 0)
1919 		return;
1920 
1921 	buf = (char *) xalloc(s);
1922 	bp = buf;
1923 	*bp++ = command;
1924 	for (i = 0; macros[i] != NULL; i++)
1925 	{
1926 		mid = macid(macros[i]);
1927 		if (mid == 0)
1928 			continue;
1929 		v = macvalue(mid, e);
1930 		if (v == NULL)
1931 			continue;
1932 		expand(v, exp, sizeof(exp), e);
1933 
1934 		if (tTd(64, 10))
1935 			sm_dprintf("milter_send_macros(%s, %c): %s=%s\n",
1936 				m->mf_name, command, macros[i], exp);
1937 
1938 		(void) sm_strlcpy(bp, macros[i], s - (bp - buf));
1939 		bp += strlen(bp) + 1;
1940 		(void) sm_strlcpy(bp, exp, s - (bp - buf));
1941 		bp += strlen(bp) + 1;
1942 	}
1943 	(void) milter_write(m, SMFIC_MACRO, buf, s,
1944 			    m->mf_timeout[SMFTO_WRITE], e, "send_macros");
1945 	sm_free(buf);
1946 }
1947 
1948 /*
1949 **  MILTER_SEND_COMMAND -- send a command and return the response for a filter
1950 **
1951 **	Parameters:
1952 **		m -- current milter filter
1953 **		cmd -- command to send.
1954 **		data -- optional command data.
1955 **		sz -- length of buf.
1956 **		e -- current envelope (for e->e_id).
1957 **		state -- return state word.
1958 **
1959 **	Returns:
1960 **		response string (may be NULL)
1961 */
1962 
1963 static char *
1964 milter_send_command(m, cmd, data, sz, e, state, where)
1965 	struct milter *m;
1966 	int cmd;
1967 	void *data;
1968 	ssize_t sz;
1969 	ENVELOPE *e;
1970 	char *state;
1971 	const char *where;
1972 {
1973 	char rcmd;
1974 	ssize_t rlen;
1975 	unsigned long skipflag;
1976 	unsigned long norespflag = 0;
1977 	char command = (char) cmd;
1978 	char *action;
1979 	char *defresponse;
1980 	char *response;
1981 
1982 	if (tTd(64, 10))
1983 		sm_dprintf("milter_send_command(%s): cmd %c len %ld\n",
1984 			m->mf_name, (char) command, (long) sz);
1985 
1986 	/* find skip flag and default failure */
1987 	switch (command)
1988 	{
1989 	  case SMFIC_CONNECT:
1990 		skipflag = SMFIP_NOCONNECT;
1991 		norespflag = SMFIP_NR_CONN;
1992 		action = "connect";
1993 		defresponse = "554 Command rejected";
1994 		break;
1995 
1996 	  case SMFIC_HELO:
1997 		skipflag = SMFIP_NOHELO;
1998 		norespflag = SMFIP_NR_HELO;
1999 		action = "helo";
2000 		defresponse = "550 Command rejected";
2001 		break;
2002 
2003 	  case SMFIC_MAIL:
2004 		skipflag = SMFIP_NOMAIL;
2005 		norespflag = SMFIP_NR_MAIL;
2006 		action = "mail";
2007 		defresponse = "550 5.7.1 Command rejected";
2008 		break;
2009 
2010 	  case SMFIC_RCPT:
2011 		skipflag = SMFIP_NORCPT;
2012 		norespflag = SMFIP_NR_RCPT;
2013 		action = "rcpt";
2014 		defresponse = "550 5.7.1 Command rejected";
2015 		break;
2016 
2017 	  case SMFIC_HEADER:
2018 		skipflag = SMFIP_NOHDRS;
2019 		norespflag = SMFIP_NR_HDR;
2020 		action = "header";
2021 		defresponse = "550 5.7.1 Command rejected";
2022 		break;
2023 
2024 	  case SMFIC_BODY:
2025 		skipflag = SMFIP_NOBODY;
2026 		norespflag = SMFIP_NR_BODY;
2027 		action = "body";
2028 		defresponse = "554 5.7.1 Command rejected";
2029 		break;
2030 
2031 	  case SMFIC_EOH:
2032 		skipflag = SMFIP_NOEOH;
2033 		norespflag = SMFIP_NR_EOH;
2034 		action = "eoh";
2035 		defresponse = "550 5.7.1 Command rejected";
2036 		break;
2037 
2038 	  case SMFIC_UNKNOWN:
2039 		skipflag = SMFIP_NOUNKNOWN;
2040 		norespflag = SMFIP_NR_UNKN;
2041 		action = "unknown";
2042 		defresponse = "550 5.7.1 Command rejected";
2043 		break;
2044 
2045 	  case SMFIC_DATA:
2046 		skipflag = SMFIP_NODATA;
2047 		norespflag = SMFIP_NR_DATA;
2048 		action = "data";
2049 		defresponse = "550 5.7.1 Command rejected";
2050 		break;
2051 
2052 	  case SMFIC_BODYEOB:
2053 	  case SMFIC_OPTNEG:
2054 	  case SMFIC_MACRO:
2055 	  case SMFIC_ABORT:
2056 	  case SMFIC_QUIT:
2057 		/* NOTE: not handled by milter_send_command() */
2058 		/* FALLTHROUGH */
2059 
2060 	  default:
2061 		skipflag = 0;
2062 		action = "default";
2063 		defresponse = "550 5.7.1 Command rejected";
2064 		break;
2065 	}
2066 
2067 	if (tTd(64, 10))
2068 		sm_dprintf("milter_send_command(%s): skip=%lx, pflags=%x\n",
2069 			m->mf_name, skipflag, m->mf_pflags);
2070 
2071 	/* check if filter wants this command */
2072 	if (skipflag != 0 && bitset(skipflag, m->mf_pflags))
2073 		return NULL;
2074 
2075 	/* send the command to the filter */
2076 	(void) milter_write(m, command, data, sz,
2077 			    m->mf_timeout[SMFTO_WRITE], e, where);
2078 	if (m->mf_state == SMFS_ERROR)
2079 	{
2080 		MILTER_CHECK_ERROR(false, return NULL);
2081 		return NULL;
2082 	}
2083 
2084 	/* check if filter sends response to this command */
2085 	if (norespflag != 0 && bitset(norespflag, m->mf_pflags))
2086 		return NULL;
2087 
2088 	/* get the response from the filter */
2089 	response = milter_read(m, &rcmd, &rlen,
2090 			       m->mf_timeout[SMFTO_READ], e, where);
2091 	if (m->mf_state == SMFS_ERROR)
2092 	{
2093 		MILTER_CHECK_ERROR(false, return NULL);
2094 		return NULL;
2095 	}
2096 
2097 	if (tTd(64, 10))
2098 		sm_dprintf("milter_send_command(%s): returned %c\n",
2099 			   m->mf_name, (char) rcmd);
2100 
2101 	switch (rcmd)
2102 	{
2103 	  case SMFIR_REPLYCODE:
2104 		MILTER_CHECK_REPLYCODE(defresponse);
2105 		if (MilterLogLevel > 10)
2106 			sm_syslog(LOG_INFO, e->e_id,
2107 				  "milter=%s, action=%s, reject=%s",
2108 				  m->mf_name, action, response);
2109 		*state = rcmd;
2110 		break;
2111 
2112 	  case SMFIR_REJECT:
2113 		if (MilterLogLevel > 10)
2114 			sm_syslog(LOG_INFO, e->e_id,
2115 				  "milter=%s, action=%s, reject",
2116 				  m->mf_name, action);
2117 		*state = rcmd;
2118 		break;
2119 
2120 	  case SMFIR_DISCARD:
2121 		if (MilterLogLevel > 10)
2122 			sm_syslog(LOG_INFO, e->e_id,
2123 				  "milter=%s, action=%s, discard",
2124 				  m->mf_name, action);
2125 		*state = rcmd;
2126 		break;
2127 
2128 	  case SMFIR_TEMPFAIL:
2129 		if (MilterLogLevel > 10)
2130 			sm_syslog(LOG_INFO, e->e_id,
2131 				  "milter=%s, action=%s, tempfail",
2132 				  m->mf_name, action);
2133 		*state = rcmd;
2134 		break;
2135 
2136 	  case SMFIR_ACCEPT:
2137 		/* this filter is done with message/connection */
2138 		if (command == SMFIC_HELO ||
2139 		    command == SMFIC_CONNECT)
2140 			m->mf_state = SMFS_CLOSABLE;
2141 		else
2142 			m->mf_state = SMFS_DONE;
2143 		if (MilterLogLevel > 10)
2144 			sm_syslog(LOG_INFO, e->e_id,
2145 				  "milter=%s, action=%s, accepted",
2146 				  m->mf_name, action);
2147 		break;
2148 
2149 	  case SMFIR_CONTINUE:
2150 		/* if MAIL command is ok, filter is in message state */
2151 		if (command == SMFIC_MAIL)
2152 			m->mf_state = SMFS_INMSG;
2153 		if (MilterLogLevel > 12)
2154 			sm_syslog(LOG_INFO, e->e_id,
2155 				  "milter=%s, action=%s, continue",
2156 				  m->mf_name, action);
2157 		break;
2158 
2159 	  case SMFIR_SKIP:
2160 		if (MilterLogLevel > 12)
2161 			sm_syslog(LOG_INFO, e->e_id,
2162 				  "milter=%s, action=%s, skip",
2163 				  m->mf_name, action);
2164 		m->mf_state = SMFS_SKIP;
2165 		break;
2166 
2167 	  default:
2168 		/* Invalid response to command */
2169 		if (MilterLogLevel > 0)
2170 			sm_syslog(LOG_ERR, e->e_id,
2171 				  "milter_send_command(%s): action=%s returned bogus response %c",
2172 				  m->mf_name, action, rcmd);
2173 		milter_error(m, e);
2174 		break;
2175 	}
2176 
2177 	if (*state != SMFIR_REPLYCODE && response != NULL)
2178 	{
2179 		sm_free(response); /* XXX */
2180 		response = NULL;
2181 	}
2182 	return response;
2183 }
2184 
2185 /*
2186 **  MILTER_COMMAND -- send a command and return the response for each filter
2187 **
2188 **	Parameters:
2189 **		cmd -- command to send.
2190 **		data -- optional command data.
2191 **		sz -- length of buf.
2192 **		macros -- macros to send for filter smfi_getsymval().
2193 **		e -- current envelope (for macro access).
2194 **		state -- return state word.
2195 **		where -- description of calling function (logging).
2196 **		cmd_error -- did the SMTP command cause an error?
2197 **
2198 **	Returns:
2199 **		response string (may be NULL)
2200 */
2201 
2202 static char *
2203 milter_command(cmd, data, sz, macros, e, state, where, cmd_error)
2204 	int cmd;
2205 	void *data;
2206 	ssize_t sz;
2207 	char **macros;
2208 	ENVELOPE *e;
2209 	char *state;
2210 	const char *where;
2211 	bool cmd_error;
2212 {
2213 	int i;
2214 	char command = (char) cmd;
2215 	char *response = NULL;
2216 	time_t tn = 0;
2217 
2218 	if (tTd(64, 10))
2219 		sm_dprintf("milter_command: cmd %c len %ld\n",
2220 			command, (long) sz);
2221 
2222 	*state = SMFIR_CONTINUE;
2223 	for (i = 0; InputFilters[i] != NULL; i++)
2224 	{
2225 		struct milter *m = InputFilters[i];
2226 
2227 		/* previous problem? */
2228 		if (m->mf_state == SMFS_ERROR)
2229 		{
2230 			MILTER_CHECK_ERROR(false, continue);
2231 			break;
2232 		}
2233 
2234 		/* sanity check */
2235 		if (m->mf_sock < 0 ||
2236 		    (m->mf_state != SMFS_OPEN && m->mf_state != SMFS_INMSG))
2237 			continue;
2238 
2239 		/* send macros (regardless of whether we send command) */
2240 		if (macros != NULL && macros[0] != NULL)
2241 		{
2242 			milter_send_macros(m, macros, command, e);
2243 			if (m->mf_state == SMFS_ERROR)
2244 			{
2245 				MILTER_CHECK_ERROR(false, continue);
2246 				break;
2247 			}
2248 		}
2249 
2250 		if (MilterLogLevel > 21)
2251 			tn = curtime();
2252 
2253 		/*
2254 		**  send the command if
2255 		**	there is no error
2256 		**	or it's RCPT and the client asked for it:
2257 		**	!cmd_error ||
2258 		**	where == "rcpt" && m->mf_pflags & SMFIP_RCPT_REJ != 0
2259 		**  negate that condition and use continue
2260 		*/
2261 
2262 		if (cmd_error &&
2263 		    (strcmp(where, "rcpt") != 0 ||
2264 		     (m->mf_pflags & SMFIP_RCPT_REJ) == 0))
2265 			continue;
2266 
2267 		response = milter_send_command(m, command, data, sz, e, state,
2268 						where);
2269 
2270 		if (MilterLogLevel > 21)
2271 		{
2272 			/* log the time it took for the command per filter */
2273 			sm_syslog(LOG_INFO, e->e_id,
2274 				  "Milter (%s): time command (%c), %d",
2275 				  m->mf_name, command, (int) (tn - curtime()));
2276 		}
2277 
2278 		if (*state != SMFIR_CONTINUE)
2279 			break;
2280 	}
2281 	return response;
2282 }
2283 
2284 static int milter_getsymlist __P((struct milter *, char *, int, int));
2285 
2286 static int
2287 milter_getsymlist(m, buf, rlen, offset)
2288 	struct milter *m;
2289 	char *buf;
2290 	int rlen;
2291 	int offset;
2292 {
2293 	int i, r, nummac;
2294 	mi_int32 v;
2295 
2296 	SM_ASSERT(m != NULL);
2297 	SM_ASSERT(buf != NULL);
2298 
2299 	while (offset + MILTER_LEN_BYTES < rlen)
2300 	{
2301 		size_t len;
2302 		char **macros;
2303 
2304 		nummac = 0;
2305 		(void) memcpy((char *) &v, buf + offset, MILTER_LEN_BYTES);
2306 		i = ntohl(v);
2307 		if (i < SMFIM_FIRST || i > SMFIM_LAST)
2308 			return -1;
2309 		offset += MILTER_LEN_BYTES;
2310 		macros = NULL;
2311 
2312 		switch (i)
2313 		{
2314 		  case MO_MACROS_CONNECT:
2315 			if (macros == NULL)
2316 				macros = MilterConnectMacros;
2317 			/* FALLTHROUGH */
2318 
2319 		  case MO_MACROS_HELO:
2320 			if (macros == NULL)
2321 				macros = MilterHeloMacros;
2322 			/* FALLTHROUGH */
2323 
2324 		  case MO_MACROS_ENVFROM:
2325 			if (macros == NULL)
2326 				macros = MilterEnvFromMacros;
2327 			/* FALLTHROUGH */
2328 
2329 		  case MO_MACROS_ENVRCPT:
2330 			if (macros == NULL)
2331 				macros = MilterEnvRcptMacros;
2332 			/* FALLTHROUGH */
2333 
2334 		  case MO_MACROS_EOM:
2335 			if (macros == NULL)
2336 				macros = MilterEOMMacros;
2337 			/* FALLTHROUGH */
2338 
2339 		  case MO_MACROS_EOH:
2340 			if (macros == NULL)
2341 				macros = MilterEOHMacros;
2342 			/* FALLTHROUGH */
2343 
2344 		  case MO_MACROS_DATA:
2345 			if (macros == NULL)
2346 				macros = MilterDataMacros;
2347 
2348 			len = strlen(buf + offset);
2349 			if (len > 0)
2350 			{
2351 				r = milter_set_macros(m->mf_name, macros,
2352 						buf + offset, nummac);
2353 				if (r >= 0)
2354 					nummac = r;
2355 			}
2356 			break;
2357 
2358 		  default:
2359 			return -1;
2360 		}
2361 		if (len == 0)
2362 			return -1;
2363 		offset += len + 1;
2364 	}
2365 
2366 	return 0;
2367 }
2368 
2369 /*
2370 **  MILTER_NEGOTIATE -- get version and flags from filter
2371 **
2372 **	Parameters:
2373 **		m -- milter filter structure.
2374 **		e -- current envelope.
2375 **		milters -- milters structure.
2376 **
2377 **	Returns:
2378 **		0 on success, -1 otherwise
2379 */
2380 
2381 static int
2382 milter_negotiate(m, e, milters)
2383 	struct milter *m;
2384 	ENVELOPE *e;
2385 	milters_T *milters;
2386 {
2387 	char rcmd;
2388 	mi_int32 fvers, fflags, pflags;
2389 	mi_int32 mta_prot_vers, mta_prot_flags, mta_actions;
2390 	ssize_t rlen;
2391 	char *response;
2392 	char data[MILTER_OPTLEN];
2393 
2394 	/* sanity check */
2395 	if (m->mf_sock < 0 || m->mf_state != SMFS_OPEN)
2396 	{
2397 		if (MilterLogLevel > 0)
2398 			sm_syslog(LOG_ERR, e->e_id,
2399 				  "Milter (%s): negotiate, impossible state",
2400 				  m->mf_name);
2401 		milter_error(m, e);
2402 		return -1;
2403 	}
2404 
2405 #if _FFR_MILTER_CHECK
2406 	mta_prot_vers = m->mf_mta_prot_version;
2407 	mta_prot_flags = m->mf_mta_prot_flags;
2408 	mta_actions = m->mf_mta_actions;
2409 #else /* _FFR_MILTER_CHECK */
2410 	mta_prot_vers = SMFI_PROT_VERSION;
2411 	mta_prot_flags = SMFI_CURR_PROT;
2412 	mta_actions = SMFI_CURR_ACTS;
2413 #endif /* _FFR_MILTER_CHECK */
2414 
2415 	fvers = htonl(mta_prot_vers);
2416 	pflags = htonl(mta_prot_flags);
2417 	fflags = htonl(mta_actions);
2418 	(void) memcpy(data, (char *) &fvers, MILTER_LEN_BYTES);
2419 	(void) memcpy(data + MILTER_LEN_BYTES,
2420 		      (char *) &fflags, MILTER_LEN_BYTES);
2421 	(void) memcpy(data + (MILTER_LEN_BYTES * 2),
2422 		      (char *) &pflags, MILTER_LEN_BYTES);
2423 	(void) milter_write(m, SMFIC_OPTNEG, data, sizeof(data),
2424 			    m->mf_timeout[SMFTO_WRITE], e, "negotiate");
2425 
2426 	if (m->mf_state == SMFS_ERROR)
2427 		return -1;
2428 
2429 	if (tTd(64, 5))
2430 		sm_dprintf("milter_negotiate(%s): send: version %lu, fflags 0x%lx, pflags 0x%lx\n",
2431 			m->mf_name, ntohl(fvers), ntohl(fflags), ntohl(pflags));
2432 
2433 	response = milter_read(m, &rcmd, &rlen, m->mf_timeout[SMFTO_READ], e,
2434 				"negotiate");
2435 	if (m->mf_state == SMFS_ERROR)
2436 		return -1;
2437 
2438 	if (rcmd != SMFIC_OPTNEG)
2439 	{
2440 		if (tTd(64, 5))
2441 			sm_dprintf("milter_negotiate(%s): returned %c instead of %c\n",
2442 				m->mf_name, rcmd, SMFIC_OPTNEG);
2443 		if (MilterLogLevel > 0)
2444 			sm_syslog(LOG_ERR, e->e_id,
2445 				  "Milter (%s): negotiate: returned %c instead of %c",
2446 				  m->mf_name, rcmd, SMFIC_OPTNEG);
2447 		if (response != NULL)
2448 			sm_free(response); /* XXX */
2449 		milter_error(m, e);
2450 		return -1;
2451 	}
2452 
2453 	/* Make sure we have enough bytes for the version */
2454 	if (response == NULL || rlen < MILTER_LEN_BYTES)
2455 	{
2456 		if (tTd(64, 5))
2457 			sm_dprintf("milter_negotiate(%s): did not return valid info\n",
2458 				m->mf_name);
2459 		if (MilterLogLevel > 0)
2460 			sm_syslog(LOG_ERR, e->e_id,
2461 				  "Milter (%s): negotiate: did not return valid info",
2462 				  m->mf_name);
2463 		if (response != NULL)
2464 			sm_free(response); /* XXX */
2465 		milter_error(m, e);
2466 		return -1;
2467 	}
2468 
2469 	/* extract information */
2470 	(void) memcpy((char *) &fvers, response, MILTER_LEN_BYTES);
2471 
2472 	/* Now make sure we have enough for the feature bitmap */
2473 	if (rlen < MILTER_OPTLEN)
2474 	{
2475 		if (tTd(64, 5))
2476 			sm_dprintf("milter_negotiate(%s): did not return enough info\n",
2477 				m->mf_name);
2478 		if (MilterLogLevel > 0)
2479 			sm_syslog(LOG_ERR, e->e_id,
2480 				  "Milter (%s): negotiate: did not return enough info",
2481 				  m->mf_name);
2482 		if (response != NULL)
2483 			sm_free(response); /* XXX */
2484 		milter_error(m, e);
2485 		return -1;
2486 	}
2487 
2488 	(void) memcpy((char *) &fflags, response + MILTER_LEN_BYTES,
2489 		      MILTER_LEN_BYTES);
2490 	(void) memcpy((char *) &pflags, response + (MILTER_LEN_BYTES * 2),
2491 		      MILTER_LEN_BYTES);
2492 
2493 	m->mf_fvers = ntohl(fvers);
2494 	m->mf_fflags = ntohl(fflags);
2495 	m->mf_pflags = ntohl(pflags);
2496 
2497 	/* check for version compatibility */
2498 	if (m->mf_fvers == 1 ||
2499 	    m->mf_fvers > SMFI_VERSION)
2500 	{
2501 		if (tTd(64, 5))
2502 			sm_dprintf("milter_negotiate(%s): version %d != MTA milter version %d\n",
2503 				m->mf_name, m->mf_fvers, SMFI_VERSION);
2504 		if (MilterLogLevel > 0)
2505 			sm_syslog(LOG_ERR, e->e_id,
2506 				  "Milter (%s): negotiate: version %d != MTA milter version %d",
2507 				  m->mf_name, m->mf_fvers, SMFI_VERSION);
2508 		milter_error(m, e);
2509 		goto error;
2510 	}
2511 
2512 	/* check for filter feature mismatch */
2513 	if ((m->mf_fflags & mta_actions) != m->mf_fflags)
2514 	{
2515 		if (tTd(64, 5))
2516 			sm_dprintf("milter_negotiate(%s): filter abilities 0x%x != MTA milter abilities 0x%lx\n",
2517 				m->mf_name, m->mf_fflags,
2518 				(unsigned long) mta_actions);
2519 		if (MilterLogLevel > 0)
2520 			sm_syslog(LOG_ERR, e->e_id,
2521 				  "Milter (%s): negotiate: filter abilities 0x%x != MTA milter abilities 0x%lx",
2522 				  m->mf_name, m->mf_fflags,
2523 				  (unsigned long) mta_actions);
2524 		milter_error(m, e);
2525 		goto error;
2526 	}
2527 
2528 	/* check for protocol feature mismatch */
2529 	if ((m->mf_pflags & mta_prot_flags) != m->mf_pflags)
2530 	{
2531 		if (tTd(64, 5))
2532 			sm_dprintf("milter_negotiate(%s): protocol abilities 0x%x != MTA milter abilities 0x%lx\n",
2533 				m->mf_name, m->mf_pflags,
2534 				(unsigned long) mta_prot_flags);
2535 		if (MilterLogLevel > 0)
2536 			sm_syslog(LOG_ERR, e->e_id,
2537 				  "Milter (%s): negotiate: protocol abilities 0x%x != MTA milter abilities 0x%lx",
2538 				  m->mf_name, m->mf_pflags,
2539 				  (unsigned long) mta_prot_flags);
2540 		milter_error(m, e);
2541 		goto error;
2542 	}
2543 
2544 	if (m->mf_fvers <= 2)
2545 		m->mf_pflags |= SMFIP_NOUNKNOWN;
2546 	if (m->mf_fvers <= 3)
2547 		m->mf_pflags |= SMFIP_NODATA;
2548 
2549 	if (rlen > MILTER_OPTLEN)
2550 	{
2551 		milter_getsymlist(m, response, rlen, MILTER_OPTLEN);
2552 	}
2553 
2554 	if (bitset(SMFIF_DELRCPT, m->mf_fflags))
2555 		milters->mis_flags |= MIS_FL_DEL_RCPT;
2556 	if (!bitset(SMFIP_NORCPT, m->mf_pflags) &&
2557 	    !bitset(SMFIP_NR_RCPT, m->mf_pflags))
2558 		milters->mis_flags |= MIS_FL_REJ_RCPT;
2559 
2560 	if (tTd(64, 5))
2561 		sm_dprintf("milter_negotiate(%s): received: version %u, fflags 0x%x, pflags 0x%x\n",
2562 			m->mf_name, m->mf_fvers, m->mf_fflags, m->mf_pflags);
2563 	return 0;
2564 
2565   error:
2566 	if (response != NULL)
2567 		sm_free(response); /* XXX */
2568 	return -1;
2569 }
2570 
2571 /*
2572 **  MILTER_PER_CONNECTION_CHECK -- checks on per-connection commands
2573 **
2574 **	Reduce code duplication by putting these checks in one place
2575 **
2576 **	Parameters:
2577 **		e -- current envelope.
2578 **
2579 **	Returns:
2580 **		none
2581 */
2582 
2583 static void
2584 milter_per_connection_check(e)
2585 	ENVELOPE *e;
2586 {
2587 	int i;
2588 
2589 	/* see if we are done with any of the filters */
2590 	for (i = 0; InputFilters[i] != NULL; i++)
2591 	{
2592 		struct milter *m = InputFilters[i];
2593 
2594 		if (m->mf_state == SMFS_CLOSABLE)
2595 			milter_quit_filter(m, e);
2596 	}
2597 }
2598 
2599 /*
2600 **  MILTER_ERROR -- Put a milter filter into error state
2601 **
2602 **	Parameters:
2603 **		m -- the broken filter.
2604 **		e -- current envelope.
2605 **
2606 **	Returns:
2607 **		none
2608 */
2609 
2610 static void
2611 milter_error(m, e)
2612 	struct milter *m;
2613 	ENVELOPE *e;
2614 {
2615 	/*
2616 	**  We could send a quit here but we may have gotten here due to
2617 	**  an I/O error so we don't want to try to make things worse.
2618 	*/
2619 
2620 	if (m->mf_sock >= 0)
2621 	{
2622 		(void) close(m->mf_sock);
2623 		m->mf_sock = -1;
2624 	}
2625 	m->mf_state = SMFS_ERROR;
2626 
2627 	if (MilterLogLevel > 0)
2628 		sm_syslog(LOG_INFO, e->e_id, "Milter (%s): to error state",
2629 			  m->mf_name);
2630 }
2631 
2632 /*
2633 **  MILTER_HEADERS -- send headers to a single milter filter
2634 **
2635 **	Parameters:
2636 **		m -- current filter.
2637 **		e -- current envelope.
2638 **		state -- return state from response.
2639 **
2640 **	Returns:
2641 **		response string (may be NULL)
2642 */
2643 
2644 static char *
2645 milter_headers(m, e, state)
2646 	struct milter *m;
2647 	ENVELOPE *e;
2648 	char *state;
2649 {
2650 	char *response = NULL;
2651 	HDR *h;
2652 
2653 	if (MilterLogLevel > 17)
2654 		sm_syslog(LOG_INFO, e->e_id, "Milter (%s): headers, send",
2655 			  m->mf_name);
2656 
2657 	for (h = e->e_header; h != NULL; h = h->h_link)
2658 	{
2659 		int len_n, len_v, len_t, len_f;
2660 		char *buf, *hv;
2661 
2662 		/* don't send over deleted headers */
2663 		if (h->h_value == NULL)
2664 		{
2665 			/* strip H_USER so not counted in milter_changeheader() */
2666 			h->h_flags &= ~H_USER;
2667 			continue;
2668 		}
2669 
2670 		/* skip auto-generated */
2671 		if (!bitset(H_USER, h->h_flags))
2672 			continue;
2673 
2674 		if (tTd(64, 10))
2675 			sm_dprintf("milter_headers: %s:%s\n",
2676 				h->h_field, h->h_value);
2677 		if (MilterLogLevel > 21)
2678 			sm_syslog(LOG_INFO, e->e_id, "Milter (%s): header, %s",
2679 				  m->mf_name, h->h_field);
2680 
2681 		if (bitset(SMFIP_HDR_LEADSPC, m->mf_pflags)
2682 		    || *(h->h_value) != ' ')
2683 			hv = h->h_value;
2684 		else
2685 			hv = h->h_value + 1;
2686 		len_f = strlen(h->h_field) + 1;
2687 		len_t = len_f + strlen(hv) + 1;
2688 		if (len_t < 0)
2689 			continue;
2690 		buf = (char *) xalloc(len_t);
2691 
2692 		/*
2693 		**  Note: currently the call to dequote_internal_chars()
2694 		**  is not required as h_field is supposed to be 7-bit US-ASCII.
2695 		*/
2696 
2697 		len_n = dequote_internal_chars(h->h_field, buf, len_f);
2698 		SM_ASSERT(len_n < len_f);
2699 		len_v = dequote_internal_chars(hv, buf + len_n + 1,
2700 						len_t - len_n - 1);
2701 		SM_ASSERT(len_t >= len_n + 1 + len_v + 1);
2702 		len_t = len_n + 1 + len_v + 1;
2703 
2704 		/* send it over */
2705 		response = milter_send_command(m, SMFIC_HEADER, buf,
2706 					       len_t, e, state, "header");
2707 		sm_free(buf);
2708 		if (m->mf_state == SMFS_ERROR ||
2709 		    m->mf_state == SMFS_DONE ||
2710 		    *state != SMFIR_CONTINUE)
2711 			break;
2712 	}
2713 	if (MilterLogLevel > 17)
2714 		sm_syslog(LOG_INFO, e->e_id, "Milter (%s): headers, sent",
2715 			  m->mf_name);
2716 	return response;
2717 }
2718 
2719 /*
2720 **  MILTER_BODY -- send the body to a filter
2721 **
2722 **	Parameters:
2723 **		m -- current filter.
2724 **		e -- current envelope.
2725 **		state -- return state from response.
2726 **
2727 **	Returns:
2728 **		response string (may be NULL)
2729 */
2730 
2731 static char *
2732 milter_body(m, e, state)
2733 	struct milter *m;
2734 	ENVELOPE *e;
2735 	char *state;
2736 {
2737 	char bufchar = '\0';
2738 	char prevchar = '\0';
2739 	int c;
2740 	char *response = NULL;
2741 	char *bp;
2742 	char buf[MILTER_CHUNK_SIZE];
2743 
2744 	if (tTd(64, 10))
2745 		sm_dprintf("milter_body\n");
2746 
2747 	if (bfrewind(e->e_dfp) < 0)
2748 	{
2749 		ExitStat = EX_IOERR;
2750 		*state = SMFIR_TEMPFAIL;
2751 		syserr("milter_body: %s/%cf%s: rewind error",
2752 		       qid_printqueue(e->e_qgrp, e->e_qdir),
2753 		       DATAFL_LETTER, e->e_id);
2754 		return NULL;
2755 	}
2756 
2757 	if (MilterLogLevel > 17)
2758 		sm_syslog(LOG_INFO, e->e_id, "Milter (%s): body, send",
2759 			  m->mf_name);
2760 	bp = buf;
2761 	while ((c = sm_io_getc(e->e_dfp, SM_TIME_DEFAULT)) != SM_IO_EOF)
2762 	{
2763 		/*  Change LF to CRLF */
2764 		if (c == '\n')
2765 		{
2766 #if !_FFR_MILTER_CONVERT_ALL_LF_TO_CRLF
2767 			/* Not a CRLF already? */
2768 			if (prevchar != '\r')
2769 #endif /* !_FFR_MILTER_CONVERT_ALL_LF_TO_CRLF */
2770 			{
2771 				/* Room for CR now? */
2772 				if (bp + 2 > &buf[sizeof(buf)])
2773 				{
2774 					/* No room, buffer LF */
2775 					bufchar = c;
2776 
2777 					/* and send CR now */
2778 					c = '\r';
2779 				}
2780 				else
2781 				{
2782 					/* Room to do it now */
2783 					*bp++ = '\r';
2784 					prevchar = '\r';
2785 				}
2786 			}
2787 		}
2788 		*bp++ = (char) c;
2789 		prevchar = c;
2790 		if (bp >= &buf[sizeof(buf)])
2791 		{
2792 			/* send chunk */
2793 			response = milter_send_command(m, SMFIC_BODY, buf,
2794 						       bp - buf, e, state,
2795 							"body chunk");
2796 			bp = buf;
2797 			if (bufchar != '\0')
2798 			{
2799 				*bp++ = bufchar;
2800 				bufchar = '\0';
2801 				prevchar = bufchar;
2802 			}
2803 		}
2804 		if (m->mf_state == SMFS_ERROR ||
2805 		    m->mf_state == SMFS_DONE ||
2806 		    m->mf_state == SMFS_SKIP ||
2807 		    *state != SMFIR_CONTINUE)
2808 			break;
2809 	}
2810 
2811 	/* check for read errors */
2812 	if (sm_io_error(e->e_dfp))
2813 	{
2814 		ExitStat = EX_IOERR;
2815 		if (*state == SMFIR_CONTINUE ||
2816 		    *state == SMFIR_ACCEPT ||
2817 		    m->mf_state == SMFS_SKIP)
2818 		{
2819 			*state = SMFIR_TEMPFAIL;
2820 			if (response != NULL)
2821 			{
2822 				sm_free(response); /* XXX */
2823 				response = NULL;
2824 			}
2825 		}
2826 		syserr("milter_body: %s/%cf%s: read error",
2827 		       qid_printqueue(e->e_qgrp, e->e_qdir),
2828 		       DATAFL_LETTER, e->e_id);
2829 		return response;
2830 	}
2831 
2832 	/* send last body chunk */
2833 	if (bp > buf &&
2834 	    m->mf_state != SMFS_ERROR &&
2835 	    m->mf_state != SMFS_DONE &&
2836 	    m->mf_state != SMFS_SKIP &&
2837 	    *state == SMFIR_CONTINUE)
2838 	{
2839 		/* send chunk */
2840 		response = milter_send_command(m, SMFIC_BODY, buf, bp - buf,
2841 					       e, state, "last body chunk");
2842 		bp = buf;
2843 	}
2844 	if (MilterLogLevel > 17)
2845 		sm_syslog(LOG_INFO, e->e_id, "Milter (%s): body, sent",
2846 			  m->mf_name);
2847 	if (m->mf_state == SMFS_SKIP)
2848 	{
2849 		*state = SMFIR_CONTINUE;
2850 		m->mf_state = SMFS_READY;
2851 	}
2852 
2853 	return response;
2854 }
2855 
2856 /*
2857 **  Actions
2858 */
2859 
2860 /*
2861 **  ADDLEADINGSPACE -- Add a leading space to a string
2862 **
2863 **	Parameters:
2864 **		str -- string
2865 **		rp -- resource pool for allocations
2866 **
2867 **	Returns:
2868 **		pointer to new string
2869 */
2870 
2871 static char *addleadingspace __P((char *, SM_RPOOL_T *));
2872 
2873 static char *
2874 addleadingspace(str, rp)
2875 	char *str;
2876 	SM_RPOOL_T *rp;
2877 {
2878 	size_t l;
2879 	char *new;
2880 
2881 	SM_ASSERT(str != NULL);
2882 	l = strlen(str);
2883 	SM_ASSERT(l + 2 > l);
2884 	new = sm_rpool_malloc_x(rp, l + 2);
2885 	new[0] = ' ';
2886 	new[1] = '\0';
2887 	sm_strlcpy(new + 1, str, l + 1);
2888 	return new;
2889 }
2890 
2891 /*
2892 **  MILTER_ADDHEADER -- Add the supplied header to the message
2893 **
2894 **	Parameters:
2895 **		m -- current filter.
2896 **		response -- encoded form of header/value.
2897 **		rlen -- length of response.
2898 **		e -- current envelope.
2899 **
2900 **	Returns:
2901 **		none
2902 */
2903 
2904 static void
2905 milter_addheader(m, response, rlen, e)
2906 	struct milter *m;
2907 	char *response;
2908 	ssize_t rlen;
2909 	ENVELOPE *e;
2910 {
2911 	int mh_v_len;
2912 	char *val, *mh_value;
2913 	HDR *h;
2914 
2915 	if (tTd(64, 10))
2916 		sm_dprintf("milter_addheader: ");
2917 
2918 	/* sanity checks */
2919 	if (response == NULL)
2920 	{
2921 		if (tTd(64, 10))
2922 			sm_dprintf("NULL response\n");
2923 		return;
2924 	}
2925 
2926 	if (rlen < 2 || strlen(response) + 1 >= (size_t) rlen)
2927 	{
2928 		if (tTd(64, 10))
2929 			sm_dprintf("didn't follow protocol (total len %d != rlen %d)\n",
2930 				   (int) strlen(response), (int) (rlen - 1));
2931 		return;
2932 	}
2933 
2934 	/* Find separating NUL */
2935 	val = response + strlen(response) + 1;
2936 
2937 	/* another sanity check */
2938 	if (strlen(response) + strlen(val) + 2 != (size_t) rlen)
2939 	{
2940 		if (tTd(64, 10))
2941 			sm_dprintf("didn't follow protocol (part len)\n");
2942 		return;
2943 	}
2944 
2945 	if (*response == '\0')
2946 	{
2947 		if (tTd(64, 10))
2948 			sm_dprintf("empty field name\n");
2949 		return;
2950 	}
2951 
2952 	for (h = e->e_header; h != NULL; h = h->h_link)
2953 	{
2954 		if (sm_strcasecmp(h->h_field, response) == 0 &&
2955 		    !bitset(H_USER, h->h_flags) &&
2956 		    !bitset(H_TRACE, h->h_flags))
2957 			break;
2958 	}
2959 
2960 	mh_v_len = 0;
2961 	mh_value = quote_internal_chars(val, NULL, &mh_v_len);
2962 
2963 	/* add to e_msgsize */
2964 	e->e_msgsize += strlen(response) + 2 + strlen(val);
2965 
2966 	if (h != NULL)
2967 	{
2968 		if (tTd(64, 10))
2969 			sm_dprintf("Replace default header %s value with %s\n",
2970 				   h->h_field, mh_value);
2971 		if (MilterLogLevel > 8)
2972 			sm_syslog(LOG_INFO, e->e_id,
2973 				  "Milter change: default header %s value with %s",
2974 				  h->h_field, mh_value);
2975 		if (bitset(SMFIP_HDR_LEADSPC, m->mf_pflags))
2976 			h->h_value = mh_value;
2977 		else
2978 		{
2979 			h->h_value = addleadingspace (mh_value, e->e_rpool);
2980 			SM_FREE(mh_value);
2981 		}
2982 		h->h_flags |= H_USER;
2983 	}
2984 	else
2985 	{
2986 		if (tTd(64, 10))
2987 			sm_dprintf("Add %s: %s\n", response, mh_value);
2988 		if (MilterLogLevel > 8)
2989 			sm_syslog(LOG_INFO, e->e_id,
2990 				  "Milter add: header: %s: %s",
2991 				  response, mh_value);
2992 		addheader(newstr(response), mh_value, H_USER, e,
2993 			!bitset(SMFIP_HDR_LEADSPC, m->mf_pflags));
2994 		SM_FREE(mh_value);
2995 	}
2996 }
2997 
2998 /*
2999 **  MILTER_INSHEADER -- Insert the supplied header
3000 **
3001 **	Parameters:
3002 **		m -- current filter.
3003 **		response -- encoded form of header/value.
3004 **		rlen -- length of response.
3005 **		e -- current envelope.
3006 **
3007 **	Returns:
3008 **		none
3009 **
3010 **	Notes:
3011 **		Unlike milter_addheader(), this does not attempt to determine
3012 **		if the header already exists in the envelope, even a
3013 **		deleted version.  It just blindly inserts.
3014 */
3015 
3016 static void
3017 milter_insheader(m, response, rlen, e)
3018 	struct milter *m;
3019 	char *response;
3020 	ssize_t rlen;
3021 	ENVELOPE *e;
3022 {
3023 	mi_int32 idx, i;
3024 	int mh_v_len;
3025 	char *field, *val, *mh_value;
3026 
3027 	if (tTd(64, 10))
3028 		sm_dprintf("milter_insheader: ");
3029 
3030 	/* sanity checks */
3031 	if (response == NULL)
3032 	{
3033 		if (tTd(64, 10))
3034 			sm_dprintf("NULL response\n");
3035 		return;
3036 	}
3037 
3038 	if (rlen < 2 || strlen(response) + 1 >= (size_t) rlen)
3039 	{
3040 		if (tTd(64, 10))
3041 			sm_dprintf("didn't follow protocol (total len)\n");
3042 		return;
3043 	}
3044 
3045 	/* decode */
3046 	(void) memcpy((char *) &i, response, MILTER_LEN_BYTES);
3047 	idx = ntohl(i);
3048 	field = response + MILTER_LEN_BYTES;
3049 	val = field + strlen(field) + 1;
3050 
3051 	/* another sanity check */
3052 	if (MILTER_LEN_BYTES + strlen(field) + 1 +
3053 	    strlen(val) + 1 != (size_t) rlen)
3054 	{
3055 		if (tTd(64, 10))
3056 			sm_dprintf("didn't follow protocol (part len)\n");
3057 		return;
3058 	}
3059 
3060 	if (*field == '\0')
3061 	{
3062 		if (tTd(64, 10))
3063 			sm_dprintf("empty field name\n");
3064 		return;
3065 	}
3066 
3067 	/* add to e_msgsize */
3068 	e->e_msgsize += strlen(response) + 2 + strlen(val);
3069 
3070 	if (tTd(64, 10))
3071 		sm_dprintf("Insert (%d) %s: %s\n", idx, field, val);
3072 	if (MilterLogLevel > 8)
3073 		sm_syslog(LOG_INFO, e->e_id,
3074 			  "Milter insert (%d): header: %s: %s",
3075 			  idx, field, val);
3076 	mh_v_len = 0;
3077 	mh_value = quote_internal_chars(val, NULL, &mh_v_len);
3078 	insheader(idx, newstr(field), mh_value, H_USER, e,
3079 		!bitset(SMFIP_HDR_LEADSPC, m->mf_pflags));
3080 	SM_FREE(mh_value);
3081 }
3082 
3083 /*
3084 **  MILTER_CHANGEHEADER -- Change the supplied header in the message
3085 **
3086 **	Parameters:
3087 **		m -- current filter.
3088 **		response -- encoded form of header/index/value.
3089 **		rlen -- length of response.
3090 **		e -- current envelope.
3091 **
3092 **	Returns:
3093 **		none
3094 */
3095 
3096 static void
3097 milter_changeheader(m, response, rlen, e)
3098 	struct milter *m;
3099 	char *response;
3100 	ssize_t rlen;
3101 	ENVELOPE *e;
3102 {
3103 	mi_int32 i, index;
3104 	int mh_v_len;
3105 	char *field, *val, *mh_value;
3106 	HDR *h, *sysheader;
3107 
3108 	if (tTd(64, 10))
3109 		sm_dprintf("milter_changeheader: ");
3110 
3111 	/* sanity checks */
3112 	if (response == NULL)
3113 	{
3114 		if (tTd(64, 10))
3115 			sm_dprintf("NULL response\n");
3116 		return;
3117 	}
3118 
3119 	if (rlen < 2 || strlen(response) + 1 >= (size_t) rlen)
3120 	{
3121 		if (tTd(64, 10))
3122 			sm_dprintf("didn't follow protocol (total len)\n");
3123 		return;
3124 	}
3125 
3126 	/* Find separating NUL */
3127 	(void) memcpy((char *) &i, response, MILTER_LEN_BYTES);
3128 	index = ntohl(i);
3129 	field = response + MILTER_LEN_BYTES;
3130 	val = field + strlen(field) + 1;
3131 
3132 	/* another sanity check */
3133 	if (MILTER_LEN_BYTES + strlen(field) + 1 +
3134 	    strlen(val) + 1 != (size_t) rlen)
3135 	{
3136 		if (tTd(64, 10))
3137 			sm_dprintf("didn't follow protocol (part len)\n");
3138 		return;
3139 	}
3140 
3141 	if (*field == '\0')
3142 	{
3143 		if (tTd(64, 10))
3144 			sm_dprintf("empty field name\n");
3145 		return;
3146 	}
3147 
3148 	mh_v_len = 0;
3149 	mh_value = quote_internal_chars(val, NULL, &mh_v_len);
3150 
3151 	sysheader = NULL;
3152 	for (h = e->e_header; h != NULL; h = h->h_link)
3153 	{
3154 		if (sm_strcasecmp(h->h_field, field) == 0)
3155 		{
3156 			if (bitset(H_USER, h->h_flags) && --index <= 0)
3157 			{
3158 				sysheader = NULL;
3159 				break;
3160 			}
3161 			else if (!bitset(H_USER, h->h_flags) &&
3162 				 !bitset(H_TRACE, h->h_flags))
3163 			{
3164 				/*
3165 				**  DRUMS msg-fmt draft says can only have
3166 				**  multiple occurences of trace fields,
3167 				**  so make sure we replace any non-trace,
3168 				**  non-user field.
3169 				*/
3170 
3171 				sysheader = h;
3172 			}
3173 		}
3174 	}
3175 
3176 	/* if not found as user-provided header at index, use sysheader */
3177 	if (h == NULL)
3178 		h = sysheader;
3179 
3180 	if (h == NULL)
3181 	{
3182 		if (*val == '\0')
3183 		{
3184 			if (tTd(64, 10))
3185 				sm_dprintf("Delete (noop) %s\n", field);
3186 			if (MilterLogLevel > 8)
3187 				sm_syslog(LOG_INFO, e->e_id,
3188 					"Milter delete (noop): header: %s"
3189 					, field);
3190 		}
3191 		else
3192 		{
3193 			/* treat modify value with no existing header as add */
3194 			if (tTd(64, 10))
3195 				sm_dprintf("Add %s: %s\n", field, mh_value);
3196 			if (MilterLogLevel > 8)
3197 				sm_syslog(LOG_INFO, e->e_id,
3198 					"Milter change (add): header: %s: %s"
3199 					, field, mh_value);
3200 			addheader(newstr(field), mh_value, H_USER, e,
3201 				!bitset(SMFIP_HDR_LEADSPC, m->mf_pflags));
3202 		}
3203 		return;
3204 	}
3205 
3206 	if (tTd(64, 10))
3207 	{
3208 		if (*val == '\0')
3209 		{
3210 			sm_dprintf("Delete%s %s:%s\n",
3211 				   h == sysheader ? " (default header)" : "",
3212 				   field,
3213 				   h->h_value == NULL ? "<NULL>" : h->h_value);
3214 		}
3215 		else
3216 		{
3217 			sm_dprintf("Change%s %s: from %s to %s\n",
3218 				   h == sysheader ? " (default header)" : "",
3219 				   field,
3220 				   h->h_value == NULL ? "<NULL>" : h->h_value,
3221 				   mh_value);
3222 		}
3223 	}
3224 
3225 	if (MilterLogLevel > 8)
3226 	{
3227 		if (*val == '\0')
3228 		{
3229 			sm_syslog(LOG_INFO, e->e_id,
3230 				  "Milter delete: header%s %s:%s",
3231 				  h == sysheader ? " (default header)" : "",
3232 				  field,
3233 				  h->h_value == NULL ? "<NULL>" : h->h_value);
3234 		}
3235 		else
3236 		{
3237 			sm_syslog(LOG_INFO, e->e_id,
3238 				  "Milter change: header%s %s: from %s to %s",
3239 				  h == sysheader ? " (default header)" : "",
3240 				  field,
3241 				  h->h_value == NULL ? "<NULL>" : h->h_value,
3242 				  mh_value);
3243 		}
3244 	}
3245 
3246 	if (h != sysheader && h->h_value != NULL)
3247 	{
3248 		size_t l;
3249 
3250 		l = strlen(h->h_value);
3251 		if (l > e->e_msgsize)
3252 			e->e_msgsize = 0;
3253 		else
3254 			e->e_msgsize -= l;
3255 		/* rpool, don't free: sm_free(h->h_value); XXX */
3256 	}
3257 
3258 	if (*val == '\0')
3259 	{
3260 		/* Remove "Field: " from message size */
3261 		if (h != sysheader)
3262 		{
3263 			size_t l;
3264 
3265 			l = strlen(h->h_field) + 2;
3266 			if (l > e->e_msgsize)
3267 				e->e_msgsize = 0;
3268 			else
3269 				e->e_msgsize -= l;
3270 		}
3271 		h->h_value = NULL;
3272 		SM_FREE(mh_value);
3273 	}
3274 	else
3275 	{
3276 		if (bitset(SMFIP_HDR_LEADSPC, m->mf_pflags))
3277 			h->h_value = mh_value;
3278 		else
3279 		{
3280 			h->h_value = addleadingspace (mh_value, e->e_rpool);
3281 			SM_FREE(mh_value);
3282 		}
3283 		h->h_flags |= H_USER;
3284 		e->e_msgsize += strlen(h->h_value);
3285 	}
3286 }
3287 
3288 /*
3289 **  MILTER_SPLIT_RESPONSE -- Split response into fields.
3290 **
3291 **	Parameters:
3292 **		response -- encoded repsonse.
3293 **		rlen -- length of response.
3294 **		pargc -- number of arguments (ouput)
3295 **
3296 **	Returns:
3297 **		array of pointers to the individual strings
3298 */
3299 
3300 static char **milter_split_response __P((char *, ssize_t, int *));
3301 
3302 static char **
3303 milter_split_response(response, rlen, pargc)
3304 	char *response;
3305 	ssize_t rlen;
3306 	int *pargc;
3307 {
3308 	char **s;
3309 	size_t i;
3310 	int elem, nelem;
3311 
3312 	SM_ASSERT(response != NULL);
3313 	SM_ASSERT(pargc != NULL);
3314 	*pargc = 0;
3315 	if (rlen < 2 || strlen(response) >= (size_t) rlen)
3316 	{
3317 		if (tTd(64, 10))
3318 			sm_dprintf("didn't follow protocol (total len %d != rlen %d)\n",
3319 				   (int) strlen(response), (int) (rlen - 1));
3320 		return NULL;
3321 	}
3322 
3323 	nelem = 0;
3324 	for (i = 0; i < rlen; i++)
3325 	{
3326 		if (response[i] == '\0')
3327 			++nelem;
3328 	}
3329 	if (nelem == 0)
3330 		return NULL;
3331 
3332 	/* last entry is only for the name */
3333 	s = (char **)malloc(nelem * (sizeof(*s)));
3334 	if (s == NULL)
3335 		return NULL;
3336 	s[0] = response;
3337 	for (i = 0, elem = 0; i < rlen && elem < nelem; i++)
3338 	{
3339 		if (response[i] == '\0')
3340 		{
3341 			++elem;
3342 			if (i + 1 >= rlen)
3343 				s[elem] = NULL;
3344 			else
3345 				s[elem] = &(response[i + 1]);
3346 		}
3347 	}
3348 	*pargc = nelem;
3349 
3350 	if (tTd(64, 10))
3351 	{
3352 		for (elem = 0; elem < nelem; elem++)
3353 			sm_dprintf("argv[%d]=\"%s\"\n", elem, s[elem]);
3354 	}
3355 
3356 	/* overwrite last entry (already done above, just paranoia) */
3357 	s[elem] = NULL;
3358 	return s;
3359 }
3360 
3361 /*
3362 **  MILTER_CHGFROM -- Change the envelope sender address
3363 **
3364 **	Parameters:
3365 **		response -- encoded form of recipient address.
3366 **		rlen -- length of response.
3367 **		e -- current envelope.
3368 **
3369 **	Returns:
3370 **		none
3371 */
3372 
3373 static void
3374 milter_chgfrom(response, rlen, e)
3375 	char *response;
3376 	ssize_t rlen;
3377 	ENVELOPE *e;
3378 {
3379 	int olderrors, argc;
3380 	char **argv;
3381 
3382 	if (tTd(64, 10))
3383 		sm_dprintf("milter_chgfrom: ");
3384 
3385 	/* sanity checks */
3386 	if (response == NULL)
3387 	{
3388 		if (tTd(64, 10))
3389 			sm_dprintf("NULL response\n");
3390 		return;
3391 	}
3392 
3393 	if (*response == '\0' ||
3394 	    strlen(response) + 1 > (size_t) rlen)
3395 	{
3396 		if (tTd(64, 10))
3397 			sm_dprintf("didn't follow protocol (total len %d != rlen %d)\n",
3398 				   (int) strlen(response), (int) (rlen - 1));
3399 		return;
3400 	}
3401 
3402 	if (tTd(64, 10))
3403 		sm_dprintf("%s\n", response);
3404 	if (MilterLogLevel > 8)
3405 		sm_syslog(LOG_INFO, e->e_id, "Milter chgfrom: %s", response);
3406 	argv = milter_split_response(response, rlen, &argc);
3407 	if (argc < 1 || argc > 2)
3408 	{
3409 		if (tTd(64, 10))
3410 			sm_dprintf("didn't follow protocol argc=%d\n", argc);
3411 		return;
3412 	}
3413 
3414 	olderrors = Errors;
3415 	setsender(argv[0], e, NULL, '\0', false);
3416 	if (argc == 2)
3417 	{
3418 		reset_mail_esmtp_args(e);
3419 
3420 		/*
3421 		**  need "features" here: how to get those? via e?
3422 		**  "fake" it for now: allow everything.
3423 		*/
3424 
3425 		parse_esmtp_args(e, NULL, argv[0], argv[1], "MAIL", NULL,
3426 				mail_esmtp_args);
3427 	}
3428 	Errors = olderrors;
3429 	return;
3430 }
3431 
3432 /*
3433 **  MILTER_ADDRCPT_PAR -- Add the supplied recipient to the message
3434 **
3435 **	Parameters:
3436 **		response -- encoded form of recipient address.
3437 **		rlen -- length of response.
3438 **		e -- current envelope.
3439 **
3440 **	Returns:
3441 **		none
3442 */
3443 
3444 static void
3445 milter_addrcpt_par(response, rlen, e)
3446 	char *response;
3447 	ssize_t rlen;
3448 	ENVELOPE *e;
3449 {
3450 	int olderrors, argc;
3451 	char *delimptr;
3452 	char **argv;
3453 	ADDRESS *a;
3454 
3455 	if (tTd(64, 10))
3456 		sm_dprintf("milter_addrcpt_par: ");
3457 
3458 	/* sanity checks */
3459 	if (response == NULL)
3460 	{
3461 		if (tTd(64, 10))
3462 			sm_dprintf("NULL response\n");
3463 		return;
3464 	}
3465 
3466 	if (tTd(64, 10))
3467 		sm_dprintf("%s\n", response);
3468 	if (MilterLogLevel > 8)
3469 		sm_syslog(LOG_INFO, e->e_id, "Milter add: rcpt: %s", response);
3470 
3471 	argv = milter_split_response(response, rlen, &argc);
3472 	if (argc < 1 || argc > 2)
3473 	{
3474 		if (tTd(64, 10))
3475 			sm_dprintf("didn't follow protocol argc=%d\n", argc);
3476 		return;
3477 	}
3478 	olderrors = Errors;
3479 
3480 	/* how to set ESMTP arguments? */
3481 	a = parseaddr(argv[0], NULLADDR, RF_COPYALL, ' ', &delimptr, e, true);
3482 
3483 	if (a != NULL && olderrors == Errors)
3484 	{
3485 		parse_esmtp_args(e, a, argv[0], argv[1], "RCPT", NULL,
3486 				rcpt_esmtp_args);
3487 		if (olderrors == Errors)
3488 			a = recipient(a, &e->e_sendqueue, 0, e);
3489 		else
3490 			sm_dprintf("olderrors=%d, Errors=%d\n",
3491 				olderrors, Errors);
3492 	}
3493 	else
3494 	{
3495 		sm_dprintf("a=%p, olderrors=%d, Errors=%d\n",
3496 			a, olderrors, Errors);
3497 	}
3498 
3499 	Errors = olderrors;
3500 	return;
3501 }
3502 
3503 /*
3504 **  MILTER_ADDRCPT -- Add the supplied recipient to the message
3505 **
3506 **	Parameters:
3507 **		response -- encoded form of recipient address.
3508 **		rlen -- length of response.
3509 **		e -- current envelope.
3510 **
3511 **	Returns:
3512 **		none
3513 */
3514 
3515 static void
3516 milter_addrcpt(response, rlen, e)
3517 	char *response;
3518 	ssize_t rlen;
3519 	ENVELOPE *e;
3520 {
3521 	int olderrors;
3522 
3523 	if (tTd(64, 10))
3524 		sm_dprintf("milter_addrcpt: ");
3525 
3526 	/* sanity checks */
3527 	if (response == NULL)
3528 	{
3529 		if (tTd(64, 10))
3530 			sm_dprintf("NULL response\n");
3531 		return;
3532 	}
3533 
3534 	if (*response == '\0' ||
3535 	    strlen(response) + 1 != (size_t) rlen)
3536 	{
3537 		if (tTd(64, 10))
3538 			sm_dprintf("didn't follow protocol (total len %d != rlen %d)\n",
3539 				   (int) strlen(response), (int) (rlen - 1));
3540 		return;
3541 	}
3542 
3543 	if (tTd(64, 10))
3544 		sm_dprintf("%s\n", response);
3545 	if (MilterLogLevel > 8)
3546 		sm_syslog(LOG_INFO, e->e_id, "Milter add: rcpt: %s", response);
3547 	olderrors = Errors;
3548 	(void) sendtolist(response, NULLADDR, &e->e_sendqueue, 0, e);
3549 	Errors = olderrors;
3550 	return;
3551 }
3552 
3553 /*
3554 **  MILTER_DELRCPT -- Delete the supplied recipient from the message
3555 **
3556 **	Parameters:
3557 **		response -- encoded form of recipient address.
3558 **		rlen -- length of response.
3559 **		e -- current envelope.
3560 **
3561 **	Returns:
3562 **		none
3563 */
3564 
3565 static void
3566 milter_delrcpt(response, rlen, e)
3567 	char *response;
3568 	ssize_t rlen;
3569 	ENVELOPE *e;
3570 {
3571 	if (tTd(64, 10))
3572 		sm_dprintf("milter_delrcpt: ");
3573 
3574 	/* sanity checks */
3575 	if (response == NULL)
3576 	{
3577 		if (tTd(64, 10))
3578 			sm_dprintf("NULL response\n");
3579 		return;
3580 	}
3581 
3582 	if (*response == '\0' ||
3583 	    strlen(response) + 1 != (size_t) rlen)
3584 	{
3585 		if (tTd(64, 10))
3586 			sm_dprintf("didn't follow protocol (total len %d != rlen %d)\n",
3587 				   (int) strlen(response), (int) (rlen - 1));
3588 		return;
3589 	}
3590 
3591 	if (tTd(64, 10))
3592 		sm_dprintf("%s\n", response);
3593 	if (MilterLogLevel > 8)
3594 		sm_syslog(LOG_INFO, e->e_id, "Milter delete: rcpt %s",
3595 			  response);
3596 	(void) removefromlist(response, &e->e_sendqueue, e);
3597 	return;
3598 }
3599 
3600 /*
3601 **  MILTER_REPLBODY -- Replace the current data file with new body
3602 **
3603 **	Parameters:
3604 **		response -- encoded form of new body.
3605 **		rlen -- length of response.
3606 **		newfilter -- if first time called by a new filter
3607 **		e -- current envelope.
3608 **
3609 **	Returns:
3610 **		0 upon success, -1 upon failure
3611 */
3612 
3613 static int
3614 milter_replbody(response, rlen, newfilter, e)
3615 	char *response;
3616 	ssize_t rlen;
3617 	bool newfilter;
3618 	ENVELOPE *e;
3619 {
3620 	static char prevchar;
3621 	int i;
3622 
3623 	if (tTd(64, 10))
3624 		sm_dprintf("milter_replbody\n");
3625 
3626 	/* If a new filter, reset previous character and truncate data file */
3627 	if (newfilter)
3628 	{
3629 		off_t prevsize;
3630 		char dfname[MAXPATHLEN];
3631 
3632 		(void) sm_strlcpy(dfname, queuename(e, DATAFL_LETTER),
3633 				  sizeof(dfname));
3634 
3635 		/* Reset prevchar */
3636 		prevchar = '\0';
3637 
3638 		/* Get the current data file information */
3639 		prevsize = sm_io_getinfo(e->e_dfp, SM_IO_WHAT_SIZE, NULL);
3640 		if (prevsize < 0)
3641 			prevsize = 0;
3642 
3643 		/* truncate current data file */
3644 		if (sm_io_getinfo(e->e_dfp, SM_IO_WHAT_ISTYPE, BF_FILE_TYPE))
3645 		{
3646 			if (sm_io_setinfo(e->e_dfp, SM_BF_TRUNCATE, NULL) < 0)
3647 			{
3648 				MILTER_DF_ERROR("milter_replbody: sm_io truncate %s: %s");
3649 				return -1;
3650 			}
3651 		}
3652 		else
3653 		{
3654 			int err;
3655 
3656 			err = sm_io_error(e->e_dfp);
3657 			(void) sm_io_flush(e->e_dfp, SM_TIME_DEFAULT);
3658 
3659 			/*
3660 			**  Clear error if tried to fflush()
3661 			**  a read-only file pointer and
3662 			**  there wasn't a previous error.
3663 			*/
3664 
3665 			if (err == 0)
3666 				sm_io_clearerr(e->e_dfp);
3667 
3668 			/* errno is set implicitly by fseek() before return */
3669 			err = sm_io_seek(e->e_dfp, SM_TIME_DEFAULT,
3670 					 0, SEEK_SET);
3671 			if (err < 0)
3672 			{
3673 				MILTER_DF_ERROR("milter_replbody: sm_io_seek %s: %s");
3674 				return -1;
3675 			}
3676 # if NOFTRUNCATE
3677 			/* XXX: Not much we can do except rewind it */
3678 			errno = EINVAL;
3679 			MILTER_DF_ERROR("milter_replbody: ftruncate not available on this platform (%s:%s)");
3680 			return -1;
3681 # else /* NOFTRUNCATE */
3682 			err = ftruncate(sm_io_getinfo(e->e_dfp,
3683 						      SM_IO_WHAT_FD, NULL),
3684 					0);
3685 			if (err < 0)
3686 			{
3687 				MILTER_DF_ERROR("milter_replbody: sm_io ftruncate %s: %s");
3688 				return -1;
3689 			}
3690 # endif /* NOFTRUNCATE */
3691 		}
3692 
3693 		if (prevsize > e->e_msgsize)
3694 			e->e_msgsize = 0;
3695 		else
3696 			e->e_msgsize -= prevsize;
3697 	}
3698 
3699 	if (newfilter && MilterLogLevel > 8)
3700 		sm_syslog(LOG_INFO, e->e_id, "Milter message: body replaced");
3701 
3702 	if (response == NULL)
3703 	{
3704 		/* Flush the buffered '\r' */
3705 		if (prevchar == '\r')
3706 		{
3707 			(void) sm_io_putc(e->e_dfp, SM_TIME_DEFAULT, prevchar);
3708 			e->e_msgsize++;
3709 		}
3710 		return 0;
3711 	}
3712 
3713 	for (i = 0; i < rlen; i++)
3714 	{
3715 		/* Buffered char from last chunk */
3716 		if (i == 0 && prevchar == '\r')
3717 		{
3718 			/* Not CRLF, output prevchar */
3719 			if (response[i] != '\n')
3720 			{
3721 				(void) sm_io_putc(e->e_dfp, SM_TIME_DEFAULT,
3722 						  prevchar);
3723 				e->e_msgsize++;
3724 			}
3725 			prevchar = '\0';
3726 		}
3727 
3728 		/* Turn CRLF into LF */
3729 		if (response[i] == '\r')
3730 		{
3731 			/* check if at end of chunk */
3732 			if (i + 1 < rlen)
3733 			{
3734 				/* If LF, strip CR */
3735 				if (response[i + 1] == '\n')
3736 					i++;
3737 			}
3738 			else
3739 			{
3740 				/* check next chunk */
3741 				prevchar = '\r';
3742 				continue;
3743 			}
3744 		}
3745 		(void) sm_io_putc(e->e_dfp, SM_TIME_DEFAULT, response[i]);
3746 		e->e_msgsize++;
3747 	}
3748 	return 0;
3749 }
3750 
3751 /*
3752 **  MTA callouts
3753 */
3754 
3755 /*
3756 **  MILTER_INIT -- open and negotiate with all of the filters
3757 **
3758 **	Parameters:
3759 **		e -- current envelope.
3760 **		state -- return state from response.
3761 **		milters -- milters structure.
3762 **
3763 **	Returns:
3764 **		true iff at least one filter is active
3765 */
3766 
3767 /* ARGSUSED */
3768 bool
3769 milter_init(e, state, milters)
3770 	ENVELOPE *e;
3771 	char *state;
3772 	milters_T *milters;
3773 {
3774 	int i;
3775 
3776 	if (tTd(64, 10))
3777 		sm_dprintf("milter_init\n");
3778 
3779 	memset(milters, '\0', sizeof(*milters));
3780 	*state = SMFIR_CONTINUE;
3781 	if (InputFilters[0] == NULL)
3782 	{
3783 		if (MilterLogLevel > 10)
3784 			sm_syslog(LOG_INFO, e->e_id,
3785 				  "Milter: no active filter");
3786 		return false;
3787 	}
3788 
3789 	for (i = 0; InputFilters[i] != NULL; i++)
3790 	{
3791 		struct milter *m = InputFilters[i];
3792 
3793 		m->mf_sock = milter_open(m, false, e);
3794 		if (m->mf_state == SMFS_ERROR)
3795 		{
3796 			MILTER_CHECK_ERROR(true, continue);
3797 			break;
3798 		}
3799 
3800 		if (m->mf_sock < 0 ||
3801 		    milter_negotiate(m, e, milters) < 0 ||
3802 		    m->mf_state == SMFS_ERROR)
3803 		{
3804 			if (tTd(64, 5))
3805 				sm_dprintf("milter_init(%s): failed to %s\n",
3806 					   m->mf_name,
3807 					   m->mf_sock < 0 ? "open" :
3808 							    "negotiate");
3809 			if (MilterLogLevel > 0)
3810 				sm_syslog(LOG_ERR, e->e_id,
3811 					  "Milter (%s): init failed to %s",
3812 					  m->mf_name,
3813 					  m->mf_sock < 0 ? "open" :
3814 							   "negotiate");
3815 
3816 			/* if negotation failure, close socket */
3817 			milter_error(m, e);
3818 			MILTER_CHECK_ERROR(true, continue);
3819 			continue;
3820 		}
3821 		if (MilterLogLevel > 9)
3822 			sm_syslog(LOG_INFO, e->e_id,
3823 				  "Milter (%s): init success to %s",
3824 				  m->mf_name,
3825 				  m->mf_sock < 0 ? "open" : "negotiate");
3826 	}
3827 
3828 	/*
3829 	**  If something temp/perm failed with one of the filters,
3830 	**  we won't be using any of them, so clear any existing
3831 	**  connections.
3832 	*/
3833 
3834 	if (*state != SMFIR_CONTINUE)
3835 		milter_quit(e);
3836 
3837 	return true;
3838 }
3839 
3840 /*
3841 **  MILTER_CONNECT -- send connection info to milter filters
3842 **
3843 **	Parameters:
3844 **		hostname -- hostname of remote machine.
3845 **		addr -- address of remote machine.
3846 **		e -- current envelope.
3847 **		state -- return state from response.
3848 **
3849 **	Returns:
3850 **		response string (may be NULL)
3851 */
3852 
3853 char *
3854 milter_connect(hostname, addr, e, state)
3855 	char *hostname;
3856 	SOCKADDR addr;
3857 	ENVELOPE *e;
3858 	char *state;
3859 {
3860 	char family;
3861 	unsigned short port;
3862 	char *buf, *bp;
3863 	char *response;
3864 	char *sockinfo = NULL;
3865 	ssize_t s;
3866 # if NETINET6
3867 	char buf6[INET6_ADDRSTRLEN];
3868 # endif /* NETINET6 */
3869 
3870 	if (tTd(64, 10))
3871 		sm_dprintf("milter_connect(%s)\n", hostname);
3872 	if (MilterLogLevel > 9)
3873 		sm_syslog(LOG_INFO, e->e_id, "Milter: connect to filters");
3874 
3875 	/* gather data */
3876 	switch (addr.sa.sa_family)
3877 	{
3878 # if NETUNIX
3879 	  case AF_UNIX:
3880 		family = SMFIA_UNIX;
3881 		port = htons(0);
3882 		sockinfo = addr.sunix.sun_path;
3883 		break;
3884 # endif /* NETUNIX */
3885 
3886 # if NETINET
3887 	  case AF_INET:
3888 		family = SMFIA_INET;
3889 		port = addr.sin.sin_port;
3890 		sockinfo = (char *) inet_ntoa(addr.sin.sin_addr);
3891 		break;
3892 # endif /* NETINET */
3893 
3894 # if NETINET6
3895 	  case AF_INET6:
3896 		if (IN6_IS_ADDR_V4MAPPED(&addr.sin6.sin6_addr))
3897 			family = SMFIA_INET;
3898 		else
3899 			family = SMFIA_INET6;
3900 		port = addr.sin6.sin6_port;
3901 		sockinfo = anynet_ntop(&addr.sin6.sin6_addr, buf6,
3902 				       sizeof(buf6));
3903 		if (sockinfo == NULL)
3904 			sockinfo = "";
3905 		break;
3906 # endif /* NETINET6 */
3907 
3908 	  default:
3909 		family = SMFIA_UNKNOWN;
3910 		break;
3911 	}
3912 
3913 	s = strlen(hostname) + 1 + sizeof(family);
3914 	if (family != SMFIA_UNKNOWN)
3915 		s += sizeof(port) + strlen(sockinfo) + 1;
3916 
3917 	buf = (char *) xalloc(s);
3918 	bp = buf;
3919 
3920 	/* put together data */
3921 	(void) memcpy(bp, hostname, strlen(hostname));
3922 	bp += strlen(hostname);
3923 	*bp++ = '\0';
3924 	(void) memcpy(bp, &family, sizeof(family));
3925 	bp += sizeof(family);
3926 	if (family != SMFIA_UNKNOWN)
3927 	{
3928 		(void) memcpy(bp, &port, sizeof(port));
3929 		bp += sizeof(port);
3930 
3931 		/* include trailing '\0' */
3932 		(void) memcpy(bp, sockinfo, strlen(sockinfo) + 1);
3933 	}
3934 
3935 	response = milter_command(SMFIC_CONNECT, buf, s, MilterConnectMacros,
3936 				e, state, "connect", false);
3937 	sm_free(buf); /* XXX */
3938 
3939 	/*
3940 	**  If this message connection is done for,
3941 	**  close the filters.
3942 	*/
3943 
3944 	if (*state != SMFIR_CONTINUE)
3945 	{
3946 		if (MilterLogLevel > 9)
3947 			sm_syslog(LOG_INFO, e->e_id, "Milter: connect, ending");
3948 		milter_quit(e);
3949 	}
3950 	else
3951 		milter_per_connection_check(e);
3952 
3953 	/*
3954 	**  SMFIR_REPLYCODE can't work with connect due to
3955 	**  the requirements of SMTP.  Therefore, ignore the
3956 	**  reply code text but keep the state it would reflect.
3957 	*/
3958 
3959 	if (*state == SMFIR_REPLYCODE)
3960 	{
3961 		if (response != NULL &&
3962 		    *response == '4')
3963 		{
3964 			if (strncmp(response, "421 ", 4) == 0)
3965 				*state = SMFIR_SHUTDOWN;
3966 			else
3967 				*state = SMFIR_TEMPFAIL;
3968 		}
3969 		else
3970 			*state = SMFIR_REJECT;
3971 		if (response != NULL)
3972 		{
3973 			sm_free(response); /* XXX */
3974 			response = NULL;
3975 		}
3976 	}
3977 	return response;
3978 }
3979 
3980 /*
3981 **  MILTER_HELO -- send SMTP HELO/EHLO command info to milter filters
3982 **
3983 **	Parameters:
3984 **		helo -- argument to SMTP HELO/EHLO command.
3985 **		e -- current envelope.
3986 **		state -- return state from response.
3987 **
3988 **	Returns:
3989 **		response string (may be NULL)
3990 */
3991 
3992 char *
3993 milter_helo(helo, e, state)
3994 	char *helo;
3995 	ENVELOPE *e;
3996 	char *state;
3997 {
3998 	int i;
3999 	char *response;
4000 
4001 	if (tTd(64, 10))
4002 		sm_dprintf("milter_helo(%s)\n", helo);
4003 
4004 	/* HELO/EHLO can come at any point */
4005 	for (i = 0; InputFilters[i] != NULL; i++)
4006 	{
4007 		struct milter *m = InputFilters[i];
4008 
4009 		switch (m->mf_state)
4010 		{
4011 		  case SMFS_INMSG:
4012 			/* abort in message filters */
4013 			milter_abort_filter(m, e);
4014 			/* FALLTHROUGH */
4015 
4016 		  case SMFS_DONE:
4017 			/* reset done filters */
4018 			m->mf_state = SMFS_OPEN;
4019 			break;
4020 		}
4021 	}
4022 
4023 	response = milter_command(SMFIC_HELO, helo, strlen(helo) + 1,
4024 				  MilterHeloMacros, e, state, "helo", false);
4025 	milter_per_connection_check(e);
4026 	return response;
4027 }
4028 
4029 /*
4030 **  MILTER_ENVFROM -- send SMTP MAIL command info to milter filters
4031 **
4032 **	Parameters:
4033 **		args -- SMTP MAIL command args (args[0] == sender).
4034 **		e -- current envelope.
4035 **		state -- return state from response.
4036 **
4037 **	Returns:
4038 **		response string (may be NULL)
4039 */
4040 
4041 char *
4042 milter_envfrom(args, e, state)
4043 	char **args;
4044 	ENVELOPE *e;
4045 	char *state;
4046 {
4047 	int i;
4048 	char *buf, *bp;
4049 	char *response;
4050 	ssize_t s;
4051 
4052 	if (tTd(64, 10))
4053 	{
4054 		sm_dprintf("milter_envfrom:");
4055 		for (i = 0; args[i] != NULL; i++)
4056 			sm_dprintf(" %s", args[i]);
4057 		sm_dprintf("\n");
4058 	}
4059 
4060 	/* sanity check */
4061 	if (args[0] == NULL)
4062 	{
4063 		*state = SMFIR_REJECT;
4064 		if (MilterLogLevel > 10)
4065 			sm_syslog(LOG_INFO, e->e_id,
4066 				  "Milter: reject, no sender");
4067 		return NULL;
4068 	}
4069 
4070 	/* new message, so ... */
4071 	for (i = 0; InputFilters[i] != NULL; i++)
4072 	{
4073 		struct milter *m = InputFilters[i];
4074 
4075 		switch (m->mf_state)
4076 		{
4077 		  case SMFS_INMSG:
4078 			/* abort in message filters */
4079 			milter_abort_filter(m, e);
4080 			/* FALLTHROUGH */
4081 
4082 		  case SMFS_DONE:
4083 			/* reset done filters */
4084 			m->mf_state = SMFS_OPEN;
4085 			break;
4086 		}
4087 	}
4088 
4089 	/* put together data */
4090 	s = 0;
4091 	for (i = 0; args[i] != NULL; i++)
4092 		s += strlen(args[i]) + 1;
4093 
4094 	if (s < 0)
4095 	{
4096 		*state = SMFIR_TEMPFAIL;
4097 		return NULL;
4098 	}
4099 
4100 	buf = (char *) xalloc(s);
4101 	bp = buf;
4102 	for (i = 0; args[i] != NULL; i++)
4103 	{
4104 		(void) sm_strlcpy(bp, args[i], s - (bp - buf));
4105 		bp += strlen(bp) + 1;
4106 	}
4107 
4108 	if (MilterLogLevel > 14)
4109 		sm_syslog(LOG_INFO, e->e_id, "Milter: sender: %s", buf);
4110 
4111 	/* send it over */
4112 	response = milter_command(SMFIC_MAIL, buf, s, MilterEnvFromMacros,
4113 				e, state, "mail", false);
4114 	sm_free(buf); /* XXX */
4115 
4116 	/*
4117 	**  If filter rejects/discards a per message command,
4118 	**  abort the other filters since we are done with the
4119 	**  current message.
4120 	*/
4121 
4122 	MILTER_CHECK_DONE_MSG();
4123 	if (MilterLogLevel > 10 && *state == SMFIR_REJECT)
4124 		sm_syslog(LOG_INFO, e->e_id, "Milter: reject, sender");
4125 	return response;
4126 }
4127 
4128 /*
4129 **  MILTER_ENVRCPT -- send SMTP RCPT command info to milter filters
4130 **
4131 **	Parameters:
4132 **		args -- SMTP MAIL command args (args[0] == recipient).
4133 **		e -- current envelope.
4134 **		state -- return state from response.
4135 **		rcpt_error -- does RCPT have an error?
4136 **
4137 **	Returns:
4138 **		response string (may be NULL)
4139 */
4140 
4141 char *
4142 milter_envrcpt(args, e, state, rcpt_error)
4143 	char **args;
4144 	ENVELOPE *e;
4145 	char *state;
4146 	bool rcpt_error;
4147 {
4148 	int i;
4149 	char *buf, *bp;
4150 	char *response;
4151 	ssize_t s;
4152 
4153 	if (tTd(64, 10))
4154 	{
4155 		sm_dprintf("milter_envrcpt:");
4156 		for (i = 0; args[i] != NULL; i++)
4157 			sm_dprintf(" %s", args[i]);
4158 		sm_dprintf("\n");
4159 	}
4160 
4161 	/* sanity check */
4162 	if (args[0] == NULL)
4163 	{
4164 		*state = SMFIR_REJECT;
4165 		if (MilterLogLevel > 10)
4166 			sm_syslog(LOG_INFO, e->e_id, "Milter: reject, no rcpt");
4167 		return NULL;
4168 	}
4169 
4170 	/* put together data */
4171 	s = 0;
4172 	for (i = 0; args[i] != NULL; i++)
4173 		s += strlen(args[i]) + 1;
4174 
4175 	if (s < 0)
4176 	{
4177 		*state = SMFIR_TEMPFAIL;
4178 		return NULL;
4179 	}
4180 
4181 	buf = (char *) xalloc(s);
4182 	bp = buf;
4183 	for (i = 0; args[i] != NULL; i++)
4184 	{
4185 		(void) sm_strlcpy(bp, args[i], s - (bp - buf));
4186 		bp += strlen(bp) + 1;
4187 	}
4188 
4189 	if (MilterLogLevel > 14)
4190 		sm_syslog(LOG_INFO, e->e_id, "Milter: rcpts: %s", buf);
4191 
4192 	/* send it over */
4193 	response = milter_command(SMFIC_RCPT, buf, s, MilterEnvRcptMacros,
4194 				e, state, "rcpt", rcpt_error);
4195 	sm_free(buf); /* XXX */
4196 	return response;
4197 }
4198 
4199 /*
4200 **  MILTER_DATA_CMD -- send SMTP DATA command info to milter filters
4201 **
4202 **	Parameters:
4203 **		e -- current envelope.
4204 **		state -- return state from response.
4205 **
4206 **	Returns:
4207 **		response string (may be NULL)
4208 */
4209 
4210 char *
4211 milter_data_cmd(e, state)
4212 	ENVELOPE *e;
4213 	char *state;
4214 {
4215 	if (tTd(64, 10))
4216 		sm_dprintf("milter_data_cmd\n");
4217 
4218 	/* send it over */
4219 	return milter_command(SMFIC_DATA, NULL, 0, MilterDataMacros, e, state,
4220 				"data", false);
4221 }
4222 
4223 /*
4224 **  MILTER_DATA -- send message headers/body and gather final message results
4225 **
4226 **	Parameters:
4227 **		e -- current envelope.
4228 **		state -- return state from response.
4229 **
4230 **	Returns:
4231 **		response string (may be NULL)
4232 **
4233 **	Side effects:
4234 **		- Uses e->e_dfp for access to the body
4235 **		- Can call the various milter action routines to
4236 **		  modify the envelope or message.
4237 */
4238 
4239 # define MILTER_CHECK_RESULTS() \
4240 	if (*state == SMFIR_ACCEPT || \
4241 	    m->mf_state == SMFS_DONE || \
4242 	    m->mf_state == SMFS_ERROR) \
4243 	{ \
4244 		if (m->mf_state != SMFS_ERROR) \
4245 			m->mf_state = SMFS_DONE; \
4246 		continue;	/* to next filter */ \
4247 	} \
4248 	if (*state != SMFIR_CONTINUE) \
4249 	{ \
4250 		m->mf_state = SMFS_DONE; \
4251 		goto finishup; \
4252 	}
4253 
4254 char *
4255 milter_data(e, state)
4256 	ENVELOPE *e;
4257 	char *state;
4258 {
4259 	bool replbody = false;		/* milter_replbody() called? */
4260 	bool replfailed = false;	/* milter_replbody() failed? */
4261 	bool rewind = false;		/* rewind data file? */
4262 	bool dfopen = false;		/* data file open for writing? */
4263 	bool newfilter;			/* reset on each new filter */
4264 	char rcmd;
4265 	int i;
4266 	int save_errno;
4267 	char *response = NULL;
4268 	time_t eomsent;
4269 	ssize_t rlen;
4270 
4271 	if (tTd(64, 10))
4272 		sm_dprintf("milter_data\n");
4273 
4274 	*state = SMFIR_CONTINUE;
4275 
4276 	/*
4277 	**  XXX: Should actually send body chunks to each filter
4278 	**  a chunk at a time instead of sending the whole body to
4279 	**  each filter in turn.  However, only if the filters don't
4280 	**  change the body.
4281 	*/
4282 
4283 	for (i = 0; InputFilters[i] != NULL; i++)
4284 	{
4285 		struct milter *m = InputFilters[i];
4286 
4287 		if (*state != SMFIR_CONTINUE &&
4288 		    *state != SMFIR_ACCEPT)
4289 		{
4290 			/*
4291 			**  A previous filter has dealt with the message,
4292 			**  safe to stop processing the filters.
4293 			*/
4294 
4295 			break;
4296 		}
4297 
4298 		/* Now reset state for later evaluation */
4299 		*state = SMFIR_CONTINUE;
4300 		newfilter = true;
4301 
4302 		/* previous problem? */
4303 		if (m->mf_state == SMFS_ERROR)
4304 		{
4305 			MILTER_CHECK_ERROR(false, continue);
4306 			break;
4307 		}
4308 
4309 		/* sanity checks */
4310 		if (m->mf_sock < 0 ||
4311 		    (m->mf_state != SMFS_OPEN && m->mf_state != SMFS_INMSG))
4312 			continue;
4313 
4314 		m->mf_state = SMFS_INMSG;
4315 
4316 		/* check if filter wants the headers */
4317 		if (!bitset(SMFIP_NOHDRS, m->mf_pflags))
4318 		{
4319 			response = milter_headers(m, e, state);
4320 			MILTER_CHECK_RESULTS();
4321 		}
4322 
4323 		/* check if filter wants EOH */
4324 		if (!bitset(SMFIP_NOEOH, m->mf_pflags))
4325 		{
4326 			if (tTd(64, 10))
4327 				sm_dprintf("milter_data: eoh\n");
4328 
4329 			if (MilterEOHMacros[0] != NULL)
4330 			{
4331 				milter_send_macros(m, MilterEOHMacros,
4332 					   SMFIC_EOH, e);
4333 				MILTER_CHECK_RESULTS();
4334 			}
4335 
4336 			/* send it over */
4337 			response = milter_send_command(m, SMFIC_EOH, NULL, 0,
4338 						       e, state, "eoh");
4339 			MILTER_CHECK_RESULTS();
4340 		}
4341 
4342 		/* check if filter wants the body */
4343 		if (!bitset(SMFIP_NOBODY, m->mf_pflags) &&
4344 		    e->e_dfp != NULL)
4345 		{
4346 			rewind = true;
4347 			response = milter_body(m, e, state);
4348 			MILTER_CHECK_RESULTS();
4349 		}
4350 
4351 		if (MilterEOMMacros[0] != NULL)
4352 		{
4353 			milter_send_macros(m, MilterEOMMacros,
4354 					   SMFIC_BODYEOB, e);
4355 			MILTER_CHECK_RESULTS();
4356 		}
4357 
4358 		/* send the final body chunk */
4359 		(void) milter_write(m, SMFIC_BODYEOB, NULL, 0,
4360 				    m->mf_timeout[SMFTO_WRITE], e, "eom");
4361 
4362 		/* Get time EOM sent for timeout */
4363 		eomsent = curtime();
4364 
4365 		/* deal with the possibility of multiple responses */
4366 		while (*state == SMFIR_CONTINUE)
4367 		{
4368 			/* Check total timeout from EOM to final ACK/NAK */
4369 			if (m->mf_timeout[SMFTO_EOM] > 0 &&
4370 			    curtime() - eomsent >= m->mf_timeout[SMFTO_EOM])
4371 			{
4372 				if (tTd(64, 5))
4373 					sm_dprintf("milter_data(%s): EOM ACK/NAK timeout\n",
4374 						m->mf_name);
4375 				if (MilterLogLevel > 0)
4376 					sm_syslog(LOG_ERR, e->e_id,
4377 						  "milter_data(%s): EOM ACK/NAK timeout",
4378 						  m->mf_name);
4379 				milter_error(m, e);
4380 				MILTER_CHECK_ERROR(false, break);
4381 				break;
4382 			}
4383 
4384 			response = milter_read(m, &rcmd, &rlen,
4385 					       m->mf_timeout[SMFTO_READ], e,
4386 						"body");
4387 			if (m->mf_state == SMFS_ERROR)
4388 				break;
4389 
4390 			if (tTd(64, 10))
4391 				sm_dprintf("milter_data(%s): state %c\n",
4392 					   m->mf_name, (char) rcmd);
4393 
4394 			switch (rcmd)
4395 			{
4396 			  case SMFIR_REPLYCODE:
4397 				MILTER_CHECK_REPLYCODE("554 5.7.1 Command rejected");
4398 				if (MilterLogLevel > 12)
4399 					sm_syslog(LOG_INFO, e->e_id, "milter=%s, reject=%s",
4400 						  m->mf_name, response);
4401 				*state = rcmd;
4402 				m->mf_state = SMFS_DONE;
4403 				break;
4404 
4405 			  case SMFIR_REJECT: /* log msg at end of function */
4406 				if (MilterLogLevel > 12)
4407 					sm_syslog(LOG_INFO, e->e_id, "milter=%s, reject",
4408 						  m->mf_name);
4409 				*state = rcmd;
4410 				m->mf_state = SMFS_DONE;
4411 				break;
4412 
4413 			  case SMFIR_DISCARD:
4414 				if (MilterLogLevel > 12)
4415 					sm_syslog(LOG_INFO, e->e_id, "milter=%s, discard",
4416 						  m->mf_name);
4417 				*state = rcmd;
4418 				m->mf_state = SMFS_DONE;
4419 				break;
4420 
4421 			  case SMFIR_TEMPFAIL:
4422 				if (MilterLogLevel > 12)
4423 					sm_syslog(LOG_INFO, e->e_id, "milter=%s, tempfail",
4424 						  m->mf_name);
4425 				*state = rcmd;
4426 				m->mf_state = SMFS_DONE;
4427 				break;
4428 
4429 			  case SMFIR_CONTINUE:
4430 			  case SMFIR_ACCEPT:
4431 				/* this filter is done with message */
4432 				if (replfailed)
4433 					*state = SMFIR_TEMPFAIL;
4434 				else
4435 					*state = SMFIR_ACCEPT;
4436 				m->mf_state = SMFS_DONE;
4437 				break;
4438 
4439 			  case SMFIR_PROGRESS:
4440 				break;
4441 
4442 			  case SMFIR_QUARANTINE:
4443 				if (!bitset(SMFIF_QUARANTINE, m->mf_fflags))
4444 				{
4445 					if (MilterLogLevel > 9)
4446 						sm_syslog(LOG_WARNING, e->e_id,
4447 							  "milter_data(%s): lied about quarantining, honoring request anyway",
4448 							  m->mf_name);
4449 				}
4450 				if (response == NULL)
4451 					response = newstr("");
4452 				if (MilterLogLevel > 3)
4453 					sm_syslog(LOG_INFO, e->e_id,
4454 						  "milter=%s, quarantine=%s",
4455 						  m->mf_name, response);
4456 				e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool,
4457 								 response);
4458 				macdefine(&e->e_macro, A_PERM,
4459 					  macid("{quarantine}"), e->e_quarmsg);
4460 				break;
4461 
4462 			  case SMFIR_ADDHEADER:
4463 				if (!bitset(SMFIF_ADDHDRS, m->mf_fflags))
4464 				{
4465 					if (MilterLogLevel > 9)
4466 						sm_syslog(LOG_WARNING, e->e_id,
4467 							  "milter_data(%s): lied about adding headers, honoring request anyway",
4468 							  m->mf_name);
4469 				}
4470 				milter_addheader(m, response, rlen, e);
4471 				break;
4472 
4473 			  case SMFIR_INSHEADER:
4474 				if (!bitset(SMFIF_ADDHDRS, m->mf_fflags))
4475 				{
4476 					if (MilterLogLevel > 9)
4477 						sm_syslog(LOG_WARNING, e->e_id,
4478 							  "milter_data(%s): lied about adding headers, honoring request anyway",
4479 							  m->mf_name);
4480 				}
4481 				milter_insheader(m, response, rlen, e);
4482 				break;
4483 
4484 			  case SMFIR_CHGHEADER:
4485 				if (!bitset(SMFIF_CHGHDRS, m->mf_fflags))
4486 				{
4487 					if (MilterLogLevel > 9)
4488 						sm_syslog(LOG_WARNING, e->e_id,
4489 							  "milter_data(%s): lied about changing headers, honoring request anyway",
4490 							  m->mf_name);
4491 				}
4492 				milter_changeheader(m, response, rlen, e);
4493 				break;
4494 
4495 			  case SMFIR_CHGFROM:
4496 				if (!bitset(SMFIF_CHGFROM, m->mf_fflags))
4497 				{
4498 					if (MilterLogLevel > 9)
4499 						sm_syslog(LOG_WARNING, e->e_id,
4500 							  "milter_data(%s) lied about changing sender, honoring request anyway",
4501 							  m->mf_name);
4502 				}
4503 				milter_chgfrom(response, rlen, e);
4504 				break;
4505 
4506 			  case SMFIR_ADDRCPT:
4507 				if (!bitset(SMFIF_ADDRCPT, m->mf_fflags))
4508 				{
4509 					if (MilterLogLevel > 9)
4510 						sm_syslog(LOG_WARNING, e->e_id,
4511 							  "milter_data(%s) lied about adding recipients, honoring request anyway",
4512 							  m->mf_name);
4513 				}
4514 				milter_addrcpt(response, rlen, e);
4515 				break;
4516 
4517 			  case SMFIR_ADDRCPT_PAR:
4518 				if (!bitset(SMFIF_ADDRCPT_PAR, m->mf_fflags))
4519 				{
4520 					if (MilterLogLevel > 9)
4521 						sm_syslog(LOG_WARNING, e->e_id,
4522 							  "milter_data(%s) lied about adding recipients with parameters, honoring request anyway",
4523 							  m->mf_name);
4524 				}
4525 				milter_addrcpt_par(response, rlen, e);
4526 				break;
4527 
4528 			  case SMFIR_DELRCPT:
4529 				if (!bitset(SMFIF_DELRCPT, m->mf_fflags))
4530 				{
4531 					if (MilterLogLevel > 9)
4532 						sm_syslog(LOG_WARNING, e->e_id,
4533 							  "milter_data(%s): lied about removing recipients, honoring request anyway",
4534 							  m->mf_name);
4535 				}
4536 				milter_delrcpt(response, rlen, e);
4537 				break;
4538 
4539 			  case SMFIR_REPLBODY:
4540 				if (!bitset(SMFIF_MODBODY, m->mf_fflags))
4541 				{
4542 					if (MilterLogLevel > 0)
4543 						sm_syslog(LOG_ERR, e->e_id,
4544 							  "milter_data(%s): lied about replacing body, rejecting request and tempfailing message",
4545 							  m->mf_name);
4546 					replfailed = true;
4547 					break;
4548 				}
4549 
4550 				/* already failed in attempt */
4551 				if (replfailed)
4552 					break;
4553 
4554 				if (!dfopen)
4555 				{
4556 					if (milter_reopen_df(e) < 0)
4557 					{
4558 						replfailed = true;
4559 						break;
4560 					}
4561 					dfopen = true;
4562 					rewind = true;
4563 				}
4564 
4565 				if (milter_replbody(response, rlen,
4566 						    newfilter, e) < 0)
4567 					replfailed = true;
4568 				newfilter = false;
4569 				replbody = true;
4570 				break;
4571 
4572 			  default:
4573 				/* Invalid response to command */
4574 				if (MilterLogLevel > 0)
4575 					sm_syslog(LOG_ERR, e->e_id,
4576 						  "milter_data(%s): returned bogus response %c",
4577 						  m->mf_name, rcmd);
4578 				milter_error(m, e);
4579 				break;
4580 			}
4581 			if (rcmd != SMFIR_REPLYCODE && response != NULL)
4582 			{
4583 				sm_free(response); /* XXX */
4584 				response = NULL;
4585 			}
4586 
4587 			if (m->mf_state == SMFS_ERROR)
4588 				break;
4589 		}
4590 
4591 		if (replbody && !replfailed)
4592 		{
4593 			/* flush possible buffered character */
4594 			milter_replbody(NULL, 0, !replbody, e);
4595 			replbody = false;
4596 		}
4597 
4598 		if (m->mf_state == SMFS_ERROR)
4599 		{
4600 			MILTER_CHECK_ERROR(false, continue);
4601 			goto finishup;
4602 		}
4603 	}
4604 
4605 finishup:
4606 	/* leave things in the expected state if we touched it */
4607 	if (replfailed)
4608 	{
4609 		if (*state == SMFIR_CONTINUE ||
4610 		    *state == SMFIR_ACCEPT)
4611 		{
4612 			*state = SMFIR_TEMPFAIL;
4613 			SM_FREE_CLR(response);
4614 		}
4615 
4616 		if (dfopen)
4617 		{
4618 			(void) sm_io_close(e->e_dfp, SM_TIME_DEFAULT);
4619 			e->e_dfp = NULL;
4620 			e->e_flags &= ~EF_HAS_DF;
4621 			dfopen = false;
4622 		}
4623 		rewind = false;
4624 	}
4625 
4626 	if ((dfopen && milter_reset_df(e) < 0) ||
4627 	    (rewind && bfrewind(e->e_dfp) < 0))
4628 	{
4629 		save_errno = errno;
4630 		ExitStat = EX_IOERR;
4631 
4632 		/*
4633 		**  If filter told us to keep message but we had
4634 		**  an error, we can't really keep it, tempfail it.
4635 		*/
4636 
4637 		if (*state == SMFIR_CONTINUE ||
4638 		    *state == SMFIR_ACCEPT)
4639 		{
4640 			*state = SMFIR_TEMPFAIL;
4641 			SM_FREE_CLR(response);
4642 		}
4643 
4644 		errno = save_errno;
4645 		syserr("milter_data: %s/%cf%s: read error",
4646 		       qid_printqueue(e->e_qgrp, e->e_qdir),
4647 		       DATAFL_LETTER, e->e_id);
4648 	}
4649 
4650 	MILTER_CHECK_DONE_MSG();
4651 	if (MilterLogLevel > 10 && *state == SMFIR_REJECT)
4652 		sm_syslog(LOG_INFO, e->e_id, "Milter: reject, data");
4653 	return response;
4654 }
4655 
4656 /*
4657 **  MILTER_UNKNOWN -- send any unrecognized or unimplemented command
4658 **			string to milter filters
4659 **
4660 **	Parameters:
4661 **		smtpcmd -- the string itself.
4662 **		e -- current envelope.
4663 **		state -- return state from response.
4664 **
4665 **
4666 **	Returns:
4667 **		response string (may be NULL)
4668 */
4669 
4670 char *
4671 milter_unknown(smtpcmd, e, state)
4672 	char *smtpcmd;
4673 	ENVELOPE *e;
4674 	char *state;
4675 {
4676 	if (tTd(64, 10))
4677 		sm_dprintf("milter_unknown(%s)\n", smtpcmd);
4678 
4679 	return milter_command(SMFIC_UNKNOWN, smtpcmd, strlen(smtpcmd) + 1,
4680 				NULL, e, state, "unknown", false);
4681 }
4682 
4683 /*
4684 **  MILTER_QUIT -- informs the filter(s) we are done and closes connection(s)
4685 **
4686 **	Parameters:
4687 **		e -- current envelope.
4688 **
4689 **	Returns:
4690 **		none
4691 */
4692 
4693 void
4694 milter_quit(e)
4695 	ENVELOPE *e;
4696 {
4697 	int i;
4698 
4699 	if (tTd(64, 10))
4700 		sm_dprintf("milter_quit(%s)\n", e->e_id);
4701 
4702 	for (i = 0; InputFilters[i] != NULL; i++)
4703 		milter_quit_filter(InputFilters[i], e);
4704 }
4705 
4706 /*
4707 **  MILTER_ABORT -- informs the filter(s) that we are aborting current message
4708 **
4709 **	Parameters:
4710 **		e -- current envelope.
4711 **
4712 **	Returns:
4713 **		none
4714 */
4715 
4716 void
4717 milter_abort(e)
4718 	ENVELOPE *e;
4719 {
4720 	int i;
4721 
4722 	if (tTd(64, 10))
4723 		sm_dprintf("milter_abort\n");
4724 
4725 	for (i = 0; InputFilters[i] != NULL; i++)
4726 	{
4727 		struct milter *m = InputFilters[i];
4728 
4729 		/* sanity checks */
4730 		if (m->mf_sock < 0 || m->mf_state != SMFS_INMSG)
4731 			continue;
4732 
4733 		milter_abort_filter(m, e);
4734 	}
4735 }
4736 #endif /* MILTER */
4737