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