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