diff --git a/contrib/blacklist/bin/conf.c b/contrib/blacklist/bin/conf.c
index 94baa75c09b0..f872b3de787a 100644
--- a/contrib/blacklist/bin/conf.c
+++ b/contrib/blacklist/bin/conf.c
@@ -1,1143 +1,1143 @@
 /*	$NetBSD: conf.c,v 1.24 2016/04/04 15:52:56 christos Exp $	*/
 
 /*-
  * Copyright (c) 2015 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
  * by Christos Zoulas.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
 #include <sys/cdefs.h>
 __RCSID("$NetBSD: conf.c,v 1.24 2016/04/04 15:52:56 christos Exp $");
 
 #include <stdio.h>
 #ifdef HAVE_LIBUTIL_H
 #include <libutil.h>
 #endif
 #ifdef HAVE_UTIL_H
 #include <util.h>
 #endif
 #include <string.h>
 #include <ctype.h>
 #include <inttypes.h>
 #include <netdb.h>
 #include <pwd.h>
 #include <syslog.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <limits.h>
 #include <ifaddrs.h>
 #include <arpa/inet.h>
 #include <netinet/in.h>
 #include <net/if.h>
 #include <sys/socket.h>
 
 #include "bl.h"
 #include "internal.h"
 #include "support.h"
 #include "conf.h"
 
 
 struct sockaddr_if {
 	uint8_t		sif_len;
 	sa_family_t	sif_family;
 	in_port_t	sif_port;
 	char		sif_name[16];
 };
 
 #define SIF_NAME(a) \
     ((const struct sockaddr_if *)(const void *)(a))->sif_name
 
 static int conf_is_interface(const char *);
 
 #define FSTAR	-1
 #define FEQUAL	-2
 
 static void
 advance(char **p)
 {
 	char *ep = *p;
 	while (*ep && !isspace((unsigned char)*ep))
 		ep++;
 	while (*ep && isspace((unsigned char)*ep))
 		*ep++ = '\0';
 	*p = ep;
 }
 
 static int
 getnum(const char *f, size_t l, bool local, void *rp, const char *name,
     const char *p)
 {
 	int e;
 	intmax_t im;
 	int *r = rp;
 
 	if (strcmp(p, "*") == 0) {
 		*r = FSTAR;
 		return 0;
 	}
 	if (strcmp(p, "=") == 0) {
 		if (local)
 			goto out;
 		*r = FEQUAL;
 		return 0;
 	}
 
 	im = strtoi(p, NULL, 0, 0, INT_MAX, &e);
 	if (e == 0) {
 		*r = (int)im;
 		return 0;
 	}
 
 	if (f == NULL)
 		return -1;
 	(*lfun)(LOG_ERR, "%s: %s, %zu: Bad number for %s [%s]", __func__, f, l,
 	   name,  p);
 	return -1;
 out:
 	(*lfun)(LOG_ERR, "%s: %s, %zu: `=' for %s not allowed in local config",
 	    __func__, f, l, name);
 	return -1;
 
 }
 
 static int
 getnfail(const char *f, size_t l, bool local, struct conf *c, const char *p)
 {
 	return getnum(f, l, local, &c->c_nfail, "nfail", p);
 }
 
 static int
 getsecs(const char *f, size_t l, bool local, struct conf *c, const char *p)
 {
 	int e;
 	char *ep;
 	intmax_t tot, im;
 
 	tot = 0;
 	if (strcmp(p, "*") == 0) {
 		c->c_duration = FSTAR;
 		return 0;
 	}
 	if (strcmp(p, "=") == 0) {
 		if (local)
 			goto out;
 		c->c_duration = FEQUAL;
 		return 0;
 	}
 again:
 	im = strtoi(p, &ep, 0, 0, INT_MAX, &e);
 
 	if (e == ENOTSUP) {
 		switch (*ep) {
 		case 'd':
 			im *= 24;
 			/*FALLTHROUGH*/
 		case 'h':
 			im *= 60;
 			/*FALLTHROUGH*/
 		case 'm':
 			im *= 60;
 			/*FALLTHROUGH*/
 		case 's':
 			e = 0;
 			tot += im;
 			if (ep[1] != '\0') {
 				p = ep + 2;
 				goto again;
 			}
 			break;
 		}
 	} else
 		tot = im;
 
 	if (e == 0) {
 		c->c_duration = (int)tot;
 		return 0;
 	}
 
 	if (f == NULL)
 		return -1;
 	(*lfun)(LOG_ERR, "%s: %s, %zu: Bad number [%s]", __func__, f, l, p);
 	return -1;
 out:
 	(*lfun)(LOG_ERR, "%s: %s, %zu: `=' duration not allowed in local"
 	    " config", __func__, f, l);
 	return -1;
 
 }
 
 static int
 getport(const char *f, size_t l, bool local, void *r, const char *p)
 {
 	struct servent *sv;
 
 	// XXX: Pass in the proto instead
 	if ((sv = getservbyname(p, "tcp")) != NULL) {
 		*(int *)r = ntohs(sv->s_port);
 		return 0;
 	}
 	if ((sv = getservbyname(p, "udp")) != NULL) {
 		*(int *)r = ntohs(sv->s_port);
 		return 0;
 	}
 
 	return getnum(f, l, local, r, "service", p);
 }
 
 static int
 getmask(const char *f, size_t l, bool local, const char **p, int *mask)
 {
 	char *d;
 	const char *s = *p;
 
 	if ((d = strchr(s, ':')) != NULL) {
 		*d++ = '\0';
 		*p = d;
 	}
 	if ((d = strchr(s, '/')) == NULL) {
 		*mask = FSTAR;
 		return 0;
 	}
 
 	*d++ = '\0';
 	return getnum(f, l, local, mask, "mask", d);
 }
 
 static int
 gethostport(const char *f, size_t l, bool local, struct conf *c, const char *p)
 {
 	char *d;	// XXX: Ok to write to string.
 	in_port_t *port = NULL;
 	const char *pstr;
 
 	if (strcmp(p, "*") == 0) {
 		c->c_port = FSTAR;
 		c->c_lmask = FSTAR;
 		return 0;
 	}
 
 	if ((d = strchr(p, ']')) != NULL) {
 		*d++ = '\0';
 		pstr = d;
 		p++;
 	} else
 		pstr = p;
 
 	if (getmask(f, l, local, &pstr, &c->c_lmask) == -1)
 		goto out;
 
 	if (d) {
 		struct sockaddr_in6 *sin6 = (void *)&c->c_ss;
 		if (debug)
 			(*lfun)(LOG_DEBUG, "%s: host6 %s", __func__, p);
 		if (strcmp(p, "*") != 0) {
 			if (inet_pton(AF_INET6, p, &sin6->sin6_addr) == -1)
 				goto out;
 			sin6->sin6_family = AF_INET6;
 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
 			sin6->sin6_len = sizeof(*sin6);
 #endif
 			port = &sin6->sin6_port;
 		}
 	} else if (pstr != p || strchr(p, '.') || conf_is_interface(p)) {
 		if (pstr == p)
 			pstr = "*";
 		struct sockaddr_in *sin = (void *)&c->c_ss;
 		struct sockaddr_if *sif = (void *)&c->c_ss;
 		if (debug)
 			(*lfun)(LOG_DEBUG, "%s: host4 %s", __func__, p);
 		if (strcmp(p, "*") != 0) {
 			if (conf_is_interface(p)) {
 				if (!local)
 					goto out2;
 				if (debug)
 					(*lfun)(LOG_DEBUG, "%s: interface %s",
 					    __func__, p);
 				if (c->c_lmask != FSTAR)
 					goto out1;
 				sif->sif_family = AF_MAX;
 				strlcpy(sif->sif_name, p,
 				    sizeof(sif->sif_name));
 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
 				sif->sif_len = sizeof(*sif);
 #endif
 				port = &sif->sif_port;
 			} else if (inet_pton(AF_INET, p, &sin->sin_addr) != -1)
 			{
 				sin->sin_family = AF_INET;
 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
 				sin->sin_len = sizeof(*sin);
 #endif
 				port = &sin->sin_port;
 			} else
 				goto out;
 		}
 	}
 
 	if (getport(f, l, local, &c->c_port, pstr) == -1)
 		return -1;
 
 	if (port && c->c_port != FSTAR && c->c_port != FEQUAL)
 		*port = htons((in_port_t)c->c_port);
 	return 0;
 out:
 	(*lfun)(LOG_ERR, "%s: %s, %zu: Bad address [%s]", __func__, f, l, pstr);
 	return -1;
 out1:
 	(*lfun)(LOG_ERR, "%s: %s, %zu: Can't specify mask %d with "
 	    "interface [%s]", __func__, f, l, c->c_lmask, p);
 	return -1;
 out2:
 	(*lfun)(LOG_ERR, "%s: %s, %zu: Interface spec does not make sense "
 	    "with remote config [%s]", __func__, f, l, p);
 	return -1;
 }
 
 static int
 getproto(const char *f, size_t l, bool local __unused, struct conf *c,
     const char *p)
 {
 	if (strcmp(p, "stream") == 0) {
 		c->c_proto = IPPROTO_TCP;
 		return 0;
 	}
 	if (strcmp(p, "dgram") == 0) {
 		c->c_proto = IPPROTO_UDP;
 		return 0;
 	}
 	return getnum(f, l, local, &c->c_proto, "protocol", p);
 }
 
 static int
 getfamily(const char *f, size_t l, bool local __unused, struct conf *c,
     const char *p)
 {
 	if (strncmp(p, "tcp", 3) == 0 || strncmp(p, "udp", 3) == 0) {
 		c->c_family = p[3] == '6' ? AF_INET6 : AF_INET;
 		return 0;
 	}
 	return getnum(f, l, local, &c->c_family, "family", p);
 }
 
 static int
 getuid(const char *f, size_t l, bool local __unused, struct conf *c,
     const char *p)
 {
 	struct passwd *pw;
 
 	if ((pw = getpwnam(p)) != NULL) {
 		c->c_uid = (int)pw->pw_uid;
 		return 0;
 	}
 
 	return getnum(f, l, local, &c->c_uid, "user", p);
 }
 
 
 static int
 getname(const char *f, size_t l, bool local, struct conf *c,
     const char *p)
 {
 	if (getmask(f, l, local, &p, &c->c_rmask) == -1)
 		return -1;
 
 	if (strcmp(p, "*") == 0) {
 		strlcpy(c->c_name, rulename, CONFNAMESZ);
 		return 0;
 	}
+
 	if (strcmp(p, "=") == 0) {
 		if (local)
 			goto out;
 		c->c_name[0] = '\0';
 		return 0;
 	}
 
 	snprintf(c->c_name, CONFNAMESZ, "%s%s", *p == '-' ? rulename : "", p);
 	return 0;
 out:
 	(*lfun)(LOG_ERR, "%s: %s, %zu: `=' name not allowed in local"
 	    " config", __func__, f, l);
 	return -1;
 }
 
 static int
 getvalue(const char *f, size_t l, bool local, void *r, char **p,
     int (*fun)(const char *, size_t, bool, struct conf *, const char *))
 {
 	char *ep = *p;
 
 	advance(p);
 	return (*fun)(f, l, local, r, ep);
 }
 
 
 static int
 conf_parseline(const char *f, size_t l, char *p, struct conf *c, bool local)
 {
 	int e;
 
 	while (*p && isspace((unsigned char)*p))
 		p++;
 
 	memset(c, 0, sizeof(*c));
 	e = getvalue(f, l, local, c, &p, gethostport);
 	if (e) return -1;
 	e = getvalue(f, l, local, c, &p, getproto);
 	if (e) return -1;
 	e = getvalue(f, l, local, c, &p, getfamily);
 	if (e) return -1;
 	e = getvalue(f, l, local, c, &p, getuid);
 	if (e) return -1;
 	e = getvalue(f, l, local, c, &p, getname);
 	if (e) return -1;
 	e = getvalue(f, l, local, c, &p, getnfail);
 	if (e) return -1;
 	e = getvalue(f, l, local, c, &p, getsecs);
 	if (e) return -1;
 
 	return 0;
 }
 
 static int
 conf_sort(const void *v1, const void *v2)
 {
 	const struct conf *c1 = v1;
 	const struct conf *c2 = v2;
 
 #define CMP(a, b, f) \
 	if ((a)->f > (b)->f) return -1; \
 	else if ((a)->f < (b)->f) return 1
 
 	CMP(c1, c2, c_ss.ss_family);
 	CMP(c1, c2, c_lmask);
 	CMP(c1, c2, c_port);
 	CMP(c1, c2, c_proto);
 	CMP(c1, c2, c_family);
 	CMP(c1, c2, c_rmask);
 	CMP(c1, c2, c_uid);
 #undef CMP
 	return 0;
 }
 
 static int
 conf_is_interface(const char *name)
 {
 	const struct ifaddrs *ifa;
 
 	for (ifa = ifas; ifa; ifa = ifa->ifa_next)
 		if (strcmp(ifa->ifa_name, name) == 0)
 			return 1;
 	return 0;
 }
 
 #define MASK(m)  ((uint32_t)~((1 << (32 - (m))) - 1))
 
 static int
 conf_amask_eq(const void *v1, const void *v2, size_t len, int mask)
 {
 	const uint32_t *a1 = v1;
 	const uint32_t *a2 = v2;
 	uint32_t m;
 	int omask = mask;
 
 	len >>= 2;
 	switch (mask) {
 	case FSTAR:
 		if (memcmp(v1, v2, len) == 0)
 			return 1;
 		goto out;
 	case FEQUAL:
-
 		(*lfun)(LOG_CRIT, "%s: Internal error: bad mask %d", __func__,
 		    mask);
 		abort();
 	default:
 		break;
 	}
 
 	for (size_t i = 0; i < len; i++) {
 		if (mask > 32) {
 			m = htonl((uint32_t)~0);
 			mask -= 32;
 		} else if (mask) {
 			m = htonl(MASK(mask));
 			mask = 0;
 		} else
 			return 1;
 		if ((a1[i] & m) != (a2[i] & m))
 			goto out;
 	}
 	return 1;
 out:
 	if (debug > 1) {
 		char b1[256], b2[256];
 		len <<= 2;
 		blhexdump(b1, sizeof(b1), "a1", v1, len);
 		blhexdump(b2, sizeof(b2), "a2", v2, len);
 		(*lfun)(LOG_DEBUG, "%s: %s != %s [0x%x]", __func__,
 		    b1, b2, omask);
 	}
 	return 0;
 }
 
 /*
  * Apply the mask to the given address
  */
 static void
 conf_apply_mask(void *v, size_t len, int mask)
 {
 	uint32_t *a = v;
 	uint32_t m;
 
 	switch (mask) {
 	case FSTAR:
 		return;
 	case FEQUAL:
 		(*lfun)(LOG_CRIT, "%s: Internal error: bad mask %d", __func__,
 		    mask);
 		abort();
 	default:
 		break;
 	}
 	len >>= 2;
 
 	for (size_t i = 0; i < len; i++) {
 		if (mask > 32) {
 			m = htonl((uint32_t)~0);
 			mask -= 32;
 		} else if (mask) {
 			m = htonl(MASK(mask));
 			mask = 0;
 		} else
 			m = 0;
 		a[i] &= m;
 	}
 }
 
 /*
  * apply the mask and the port to the address given
  */
 static void
 conf_addr_set(struct conf *c, const struct sockaddr_storage *ss)
 {
 	struct sockaddr_in *sin;
 	struct sockaddr_in6 *sin6;
 	in_port_t *port;
 	void *addr;
 	size_t alen;
 
 	c->c_lmask = c->c_rmask;
 	c->c_ss = *ss;
 
 	if (c->c_ss.ss_family != c->c_family) {
 		(*lfun)(LOG_CRIT, "%s: Internal error: mismatched family "
 		    "%u != %u", __func__, c->c_ss.ss_family, c->c_family);
 		abort();
 	}
 
 	switch (c->c_ss.ss_family) {
 	case AF_INET:
 		sin = (void *)&c->c_ss;
 		port = &sin->sin_port;
 		addr = &sin->sin_addr;
 		alen = sizeof(sin->sin_addr);
 		break;
 	case AF_INET6:
 		sin6 = (void *)&c->c_ss;
 		port = &sin6->sin6_port;
 		addr = &sin6->sin6_addr;
 		alen = sizeof(sin6->sin6_addr);
 		break;
 	default:
 		(*lfun)(LOG_CRIT, "%s: Internal error: bad family %u",
 		    __func__, c->c_ss.ss_family);
 		abort();
 	}
 
 	*port = htons((in_port_t)c->c_port);
 	conf_apply_mask(addr, alen, c->c_lmask);
 	if (c->c_lmask == FSTAR)
 		c->c_lmask = (int)(alen * 8);
 	if (debug) {
 		char buf[128];
 		sockaddr_snprintf(buf, sizeof(buf), "%a:%p", (void *)&c->c_ss);
 		(*lfun)(LOG_DEBUG, "Applied address %s", buf);
 	}
 }
 
 /*
  * Compared two addresses for equality applying the mask
  */
 static int
 conf_inet_eq(const void *v1, const void *v2, int mask)
 {
 	const struct sockaddr *sa1 = v1;
 	const struct sockaddr *sa2 = v2;
 	size_t size;
 
 	if (sa1->sa_family != sa2->sa_family)
 		return 0;
 
 	switch (sa1->sa_family) {
 	case AF_INET: {
 		const struct sockaddr_in *s1 = v1;
 		const struct sockaddr_in *s2 = v2;
 		size = sizeof(s1->sin_addr);
 		v1 = &s1->sin_addr;
 		v2 = &s2->sin_addr;
 		break;
 	}
 
 	case AF_INET6: {
 		const struct sockaddr_in6 *s1 = v1;
 		const struct sockaddr_in6 *s2 = v2;
 		size = sizeof(s1->sin6_addr);
 		v1 = &s1->sin6_addr;
 		v2 = &s2->sin6_addr;
 		break;
 	}
 
 	default:
 		(*lfun)(LOG_CRIT, "%s: Internal error: bad family %u",
 		    __func__, sa1->sa_family);
 		abort();
 	}
 
 	return conf_amask_eq(v1, v2, size, mask);
 }
 
 static int
 conf_addr_in_interface(const struct sockaddr_storage *s1,
     const struct sockaddr_storage *s2, int mask)
 {
 	const char *name = SIF_NAME(s2);
 	const struct ifaddrs *ifa;
 
 	for (ifa = ifas; ifa; ifa = ifa->ifa_next) {
 		if ((ifa->ifa_flags & IFF_UP) == 0)
 			continue;
 
 		if (strcmp(ifa->ifa_name, name) != 0)
 			continue;
 
 		if (s1->ss_family != ifa->ifa_addr->sa_family)
 			continue;
 
 		bool eq;
 		switch (s1->ss_family) {
 		case AF_INET:
 		case AF_INET6:
 			eq = conf_inet_eq(ifa->ifa_addr, s1, mask);
 			break;
 		default:
 			(*lfun)(LOG_ERR, "Bad family %u", s1->ss_family);
 			continue;
 		}
 		if (eq)
 			return 1;
 	}
 	return 0;
 }
 
 static int
 conf_addr_eq(const struct sockaddr_storage *s1,
     const struct sockaddr_storage *s2, int mask)
 {
 	switch (s2->ss_family) {
 	case 0:
 		return 1;
 	case AF_MAX:
 		return conf_addr_in_interface(s1, s2, mask);
 	case AF_INET:
 	case AF_INET6:
 		return conf_inet_eq(s1, s2, mask);
 	default:
 		(*lfun)(LOG_CRIT, "%s: Internal error: bad family %u",
 		    __func__, s1->ss_family);
 		abort();
 	}
 }
 
 static int
 conf_eq(const struct conf *c1, const struct conf *c2)
 {
 
 	if (!conf_addr_eq(&c1->c_ss, &c2->c_ss, c2->c_lmask))
 		return 0;
 
 #define CMP(a, b, f) \
 	if ((a)->f != (b)->f && (b)->f != FSTAR && (b)->f != FEQUAL) { \
 		if (debug > 1) \
 			(*lfun)(LOG_DEBUG, "%s: %s fail %d != %d", __func__, \
 			    __STRING(f), (a)->f, (b)->f); \
 		return 0; \
 	}
 	CMP(c1, c2, c_port);
 	CMP(c1, c2, c_proto);
 	CMP(c1, c2, c_family);
 	CMP(c1, c2, c_uid);
 #undef CMP
 	return 1;
 }
 
 static const char *
 conf_num(char *b, size_t l, int n)
 {
 	switch (n) {
 	case FSTAR:
 		return "*";
 	case FEQUAL:
 		return "=";
 	default:
 		snprintf(b, l, "%d", n);
 		return b;
 	}
 }
 
 static const char *
 fmtname(const char *n) {
 	size_t l = strlen(rulename);
 	if (l == 0)
 		return "*";
 	if (strncmp(n, rulename, l) == 0) {
 		if (n[l] != '\0')
 			return n + l;
 		else
 			return "*";
 	} else if (!*n)
 		return "=";
 	else
 		return n;
 }
 
 static void
 fmtport(char *b, size_t l, int port)
 {
 	char buf[128];
 
 	if (port == FSTAR)
 		return;
 
 	if (b[0] == '\0' || strcmp(b, "*") == 0)
 		snprintf(b, l, "%d", port);
 	else {
 		snprintf(buf, sizeof(buf), ":%d", port);
 		strlcat(b, buf, l);
 	}
 }
 
 static const char *
 fmtmask(char *b, size_t l, int fam, int mask)
 {
 	char buf[128];
 
 	switch (mask) {
 	case FSTAR:
 		return "";
 	case FEQUAL:
 		if (strcmp(b, "=") == 0)
 			return "";
 		else {
 			strlcat(b, "/=", l);
 			return b;
 		}
 	default:
 		break;
 	}
 
 	switch (fam) {
 	case AF_INET:
 		if (mask == 32)
 			return "";
 		break;
 	case AF_INET6:
 		if (mask == 128)
 			return "";
 		break;
 	default:
 		break;
 	}
 
 	snprintf(buf, sizeof(buf), "/%d", mask);
 	strlcat(b, buf, l);
 	return b;
 }
 
 static const char *
 conf_namemask(char *b, size_t l, const struct conf *c)
 {
 	strlcpy(b, fmtname(c->c_name), l);
 	fmtmask(b, l, c->c_family, c->c_rmask);
 	return b;
 }
 
 const char *
 conf_print(char *buf, size_t len, const char *pref, const char *delim,
     const struct conf *c)
 {
 	char ha[128], hb[32], b[5][64];
 	int sp;
 
 #define N(n, v) conf_num(b[n], sizeof(b[n]), (v))
 
 	switch (c->c_ss.ss_family) {
 	case 0:
 		snprintf(ha, sizeof(ha), "*");
 		break;
 	case AF_MAX:
 		snprintf(ha, sizeof(ha), "%s", SIF_NAME(&c->c_ss));
 		break;
 	default:
 		sockaddr_snprintf(ha, sizeof(ha), "%a", (const void *)&c->c_ss);
 		break;
 	}
 
 	fmtmask(ha, sizeof(ha), c->c_family, c->c_lmask);
 	fmtport(ha, sizeof(ha), c->c_port);
 
 	sp = *delim == '\t' ? 20 : -1;
 	hb[0] = '\0';
 	if (*delim)
 		snprintf(buf, len, "%s%*.*s%s%s%s" "%s%s%s%s"
 		    "%s%s" "%s%s%s",
 		    pref, sp, sp, ha, delim, N(0, c->c_proto), delim,
 		    N(1, c->c_family), delim, N(2, c->c_uid), delim,
 		    conf_namemask(hb, sizeof(hb), c), delim,
 		    N(3, c->c_nfail), delim, N(4, c->c_duration));
 	else
 		snprintf(buf, len, "%starget:%s, proto:%s, family:%s, "
 		    "uid:%s, name:%s, nfail:%s, duration:%s", pref,
 		    ha, N(0, c->c_proto), N(1, c->c_family), N(2, c->c_uid),
 		    conf_namemask(hb, sizeof(hb), c),
 		    N(3, c->c_nfail), N(4, c->c_duration));
 	return buf;
 }
 
 /*
  * Apply the local config match to the result
  */
 static void
 conf_apply(struct conf *c, const struct conf *sc)
 {
 	char buf[BUFSIZ];
 
 	if (debug) {
 		(*lfun)(LOG_DEBUG, "%s: %s", __func__,
 		    conf_print(buf, sizeof(buf), "merge:\t", "", sc));
 		(*lfun)(LOG_DEBUG, "%s: %s", __func__,
 		    conf_print(buf, sizeof(buf), "to:\t", "", c));
 	}
 	memcpy(c->c_name, sc->c_name, CONFNAMESZ);
 	c->c_uid = sc->c_uid;
 	c->c_rmask = sc->c_rmask;
 	c->c_nfail = sc->c_nfail;
 	c->c_duration = sc->c_duration;
 
 	if (debug)
 		(*lfun)(LOG_DEBUG, "%s: %s", __func__,
 		    conf_print(buf, sizeof(buf), "result:\t", "", c));
 }
 
 /*
  * Merge a remote configuration to the result
  */
 static void
 conf_merge(struct conf *c, const struct conf *sc)
 {
 	char buf[BUFSIZ];
 
 	if (debug) {
 		(*lfun)(LOG_DEBUG, "%s: %s", __func__,
 		    conf_print(buf, sizeof(buf), "merge:\t", "", sc));
 		(*lfun)(LOG_DEBUG, "%s: %s", __func__,
 		    conf_print(buf, sizeof(buf), "to:\t", "", c));
 	}
 
 	if (sc->c_name[0])
 		memcpy(c->c_name, sc->c_name, CONFNAMESZ);
 	if (sc->c_uid != FEQUAL)
 		c->c_uid = sc->c_uid;
 	if (sc->c_rmask != FEQUAL)
 		c->c_lmask = c->c_rmask = sc->c_rmask;
 	if (sc->c_nfail != FEQUAL)
 		c->c_nfail = sc->c_nfail;
 	if (sc->c_duration != FEQUAL)
 		c->c_duration = sc->c_duration;
 	if (debug)
 		(*lfun)(LOG_DEBUG, "%s: %s", __func__,
 		    conf_print(buf, sizeof(buf), "result:\t", "", c));
 }
 
 static void
 confset_init(struct confset *cs)
 {
 	cs->cs_c = NULL;
 	cs->cs_n = 0;
 	cs->cs_m = 0;
 }
 
 static int
 confset_grow(struct confset *cs)
 {
 	void *tc;
 
 	cs->cs_m += 10;
 	tc = realloc(cs->cs_c, cs->cs_m * sizeof(*cs->cs_c));
 	if (tc == NULL) {
 		(*lfun)(LOG_ERR, "%s: Can't grow confset (%m)", __func__);
 		return -1;
 	}
 	cs->cs_c = tc;
 	return 0;
 }
 
 static struct conf *
 confset_get(struct confset *cs)
 {
 	return &cs->cs_c[cs->cs_n];
 }
 
 static bool
 confset_full(const struct confset *cs)
 {
 	return cs->cs_n == cs->cs_m;
 }
 
 static void
 confset_sort(struct confset *cs)
 {
 	qsort(cs->cs_c, cs->cs_n, sizeof(*cs->cs_c), conf_sort);
 }
 
 static void
 confset_add(struct confset *cs)
 {
 	cs->cs_n++;
 }
 
 static void
 confset_free(struct confset *cs)
 {
 	free(cs->cs_c);
 	confset_init(cs);
 }
 
 static void
 confset_replace(struct confset *dc, struct confset *sc)
 {
 	struct confset tc;
 	tc = *dc;
 	*dc = *sc;
 	confset_init(sc);
 	confset_free(&tc);
 }
 
 static void
 confset_list(const struct confset *cs, const char *msg, const char *where)
 {
 	char buf[BUFSIZ];
 
 	(*lfun)(LOG_DEBUG, "[%s]", msg);
 	(*lfun)(LOG_DEBUG, "%20.20s\ttype\tproto\towner\tname\tnfail\tduration",
 	    where);
 	for (size_t i = 0; i < cs->cs_n; i++)
 		(*lfun)(LOG_DEBUG, "%s", conf_print(buf, sizeof(buf), "", "\t",
 		    &cs->cs_c[i]));
 }
 
 /*
  * Match a configuration against the given list and apply the function
  * to it, returning the matched entry number.
  */
 static size_t
 confset_match(const struct confset *cs, struct conf *c,
     void (*fun)(struct conf *, const struct conf *))
 {
 	char buf[BUFSIZ];
 	size_t i;
 
 	for (i = 0; i < cs->cs_n; i++) {
 		if (debug)
 			(*lfun)(LOG_DEBUG, "%s", conf_print(buf, sizeof(buf),
 			    "check:\t", "", &cs->cs_c[i]));
 		if (conf_eq(c, &cs->cs_c[i])) {
 			if (debug)
 				(*lfun)(LOG_DEBUG, "%s",
 				    conf_print(buf, sizeof(buf),
 				    "found:\t", "", &cs->cs_c[i]));
 			(*fun)(c, &cs->cs_c[i]);
 			break;
 		}
 	}
 	return i;
 }
 
 const struct conf *
 conf_find(int fd, uid_t uid, const struct sockaddr_storage *rss,
     struct conf *cr)
 {
 	int proto;
 	socklen_t slen;
 	struct sockaddr_storage lss;
 	size_t i;
 	char buf[BUFSIZ];
 
 	memset(cr, 0, sizeof(*cr));
 	slen = sizeof(lss);
 	memset(&lss, 0, slen);
 	if (getsockname(fd, (void *)&lss, &slen) == -1) {
 		(*lfun)(LOG_ERR, "getsockname failed (%m)");
 		return NULL;
 	}
 
 	slen = sizeof(proto);
 	if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &proto, &slen) == -1) {
 		(*lfun)(LOG_ERR, "getsockopt failed (%m)");
 		return NULL;
 	}
 
 	if (debug) {
 		sockaddr_snprintf(buf, sizeof(buf), "%a:%p", (void *)&lss);
 		(*lfun)(LOG_DEBUG, "listening socket: %s", buf);
 	}
 
 	switch (proto) {
 	case SOCK_STREAM:
 		cr->c_proto = IPPROTO_TCP;
 		break;
 	case SOCK_DGRAM:
 		cr->c_proto = IPPROTO_UDP;
 		break;
 	default:
 		(*lfun)(LOG_ERR, "unsupported protocol %d", proto);
 		return NULL;
 	}
 
 	switch (lss.ss_family) {
 	case AF_INET:
 		cr->c_port = ntohs(((struct sockaddr_in *)&lss)->sin_port);
 		break;
 	case AF_INET6:
 		cr->c_port = ntohs(((struct sockaddr_in6 *)&lss)->sin6_port);
 		break;
 	default:
 		(*lfun)(LOG_ERR, "unsupported family %d", lss.ss_family);
 		return NULL;
 	}
 
 	cr->c_ss = lss;
 	cr->c_lmask = FSTAR;
 	cr->c_uid = (int)uid;
 	cr->c_family = lss.ss_family;
 	cr->c_name[0] = '\0';
 	cr->c_rmask = FSTAR;
 	cr->c_nfail = FSTAR;
 	cr->c_duration = FSTAR;
 
 	if (debug)
 		(*lfun)(LOG_DEBUG, "%s", conf_print(buf, sizeof(buf),
 		    "look:\t", "", cr));
 
 	/* match the local config */
 	i = confset_match(&lconf, cr, conf_apply);
 	if (i == lconf.cs_n) {
 		if (debug)
 			(*lfun)(LOG_DEBUG, "not found");
 		return NULL;
 	}
 
 	conf_addr_set(cr, rss);
 	/* match the remote config */
 	confset_match(&rconf, cr, conf_merge);
 	/* to apply the mask */
 	conf_addr_set(cr, &cr->c_ss);
 
 	return cr;
 }
 
 
 void
 conf_parse(const char *f)
 {
 	FILE *fp;
 	char *line;
 	size_t lineno, len;
 	struct confset lc, rc, *cs;
 
 	if ((fp = fopen(f, "r")) == NULL) {
 		(*lfun)(LOG_ERR, "%s: Cannot open `%s' (%m)", __func__, f);
 		return;
 	}
 
 	lineno = 1;
 
 	confset_init(&rc);
 	confset_init(&lc);
 	cs = &lc;
 	for (; (line = fparseln(fp, &len, &lineno, NULL, 0)) != NULL;
 	    free(line))
 	{
 		if (!*line)
 			continue;
 		if (strcmp(line, "[local]") == 0) {
 			cs = &lc;
 			continue;
 		}
 		if (strcmp(line, "[remote]") == 0) {
 			cs = &rc;
 			continue;
 		}
 
 		if (confset_full(cs)) {
 			if (confset_grow(cs) == -1) {
 				confset_free(&lc);
 				confset_free(&rc);
 				fclose(fp);
 				free(line);
 				return;
 			}
 		}
 		if (conf_parseline(f, lineno, line, confset_get(cs),
 		    cs == &lc) == -1)
 			continue;
 		confset_add(cs);
 	}
 
 	fclose(fp);
 	confset_sort(&lc);
 	confset_sort(&rc);
 
 	confset_replace(&rconf, &rc);
 	confset_replace(&lconf, &lc);
 
 	if (debug) {
 		confset_list(&lconf, "local", "target");
 		confset_list(&rconf, "remote", "source");
 	}
 }
diff --git a/contrib/blacklist/lib/bl.c b/contrib/blacklist/lib/bl.c
index a3aa4ef1f9f6..409317bc3fc0 100644
--- a/contrib/blacklist/lib/bl.c
+++ b/contrib/blacklist/lib/bl.c
@@ -1,533 +1,532 @@
 /*	$NetBSD: bl.c,v 1.28 2016/07/29 17:13:09 christos Exp $	*/
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
  * by Christos Zoulas.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
 #include <sys/cdefs.h>
 __RCSID("$NetBSD: bl.c,v 1.28 2016/07/29 17:13:09 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/un.h>
 
 #include <stdio.h>
 #include <string.h>
 #include <syslog.h>
 #include <signal.h>
 #include <fcntl.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <stdint.h>
 #include <stdbool.h>
 #include <errno.h>
 #include <stdarg.h>
 #include <netinet/in.h>
 #ifdef _REENTRANT
 #include <pthread.h>
 #endif
 
 #include "bl.h"
 
 typedef struct {
 	uint32_t bl_len;
 	uint32_t bl_version;
 	uint32_t bl_type;
 	uint32_t bl_salen;
 	struct sockaddr_storage bl_ss;
 	char bl_data[];
 } bl_message_t;
 
 struct blacklist {
 #ifdef _REENTRANT
 	pthread_mutex_t b_mutex;
 # define BL_INIT(b)	pthread_mutex_init(&b->b_mutex, NULL)
 # define BL_LOCK(b)	pthread_mutex_lock(&b->b_mutex)
 # define BL_UNLOCK(b)	pthread_mutex_unlock(&b->b_mutex)
 #else
 # define BL_INIT(b)	do {} while(/*CONSTCOND*/0)
 # define BL_LOCK(b)	BL_INIT(b)
 # define BL_UNLOCK(b)	BL_INIT(b)
 #endif
 	int b_fd;
 	int b_connected;
 	struct sockaddr_un b_sun;
 	void (*b_fun)(int, const char *, va_list);
 	bl_info_t b_info;
 };
 
 #define BL_VERSION	1
 
 bool
 bl_isconnected(bl_t b)
 {
 	return b->b_connected == 0;
 }
 
 int
 bl_getfd(bl_t b)
 {
 	return b->b_fd;
 }
 
 static void
 bl_reset(bl_t b, bool locked)
 {
 	int serrno = errno;
 	if (!locked)
 		BL_LOCK(b);
 	close(b->b_fd);
 	errno = serrno;
 	b->b_fd = -1;
 	b->b_connected = -1;
 	if (!locked)
 		BL_UNLOCK(b);
 }
 
 static void
 bl_log(void (*fun)(int, const char *, va_list), int level,
     const char *fmt, ...)
 {
 	va_list ap;
 	int serrno = errno;
 
 	va_start(ap, fmt);
 	(*fun)(level, fmt, ap);
 	va_end(ap);
 	errno = serrno;
 }
 
 static int
 bl_init(bl_t b, bool srv)
 {
 	static int one = 1;
 	/* AF_UNIX address of local logger */
 	mode_t om;
 	int rv, serrno;
 	struct sockaddr_un *sun = &b->b_sun;
 
 #ifndef SOCK_NONBLOCK
 #define SOCK_NONBLOCK 0
 #endif
 #ifndef SOCK_CLOEXEC
 #define SOCK_CLOEXEC 0
 #endif
 #ifndef SOCK_NOSIGPIPE
 #define SOCK_NOSIGPIPE 0
 #endif
 
 	BL_LOCK(b);
 
 	if (b->b_fd == -1) {
 		b->b_fd = socket(PF_LOCAL,
 		    SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK|SOCK_NOSIGPIPE, 0);
 		if (b->b_fd == -1) {
 			bl_log(b->b_fun, LOG_ERR, "%s: socket failed (%s)",
 			    __func__, strerror(errno));
 			BL_UNLOCK(b);
 			return -1;
 		}
 #if SOCK_CLOEXEC == 0
 		fcntl(b->b_fd, F_SETFD, FD_CLOEXEC);
 #endif
 #if SOCK_NONBLOCK == 0
 		fcntl(b->b_fd, F_SETFL, fcntl(b->b_fd, F_GETFL) | O_NONBLOCK);
 #endif
 #if SOCK_NOSIGPIPE == 0
 #ifdef SO_NOSIGPIPE
 		int o = 1;
 		setsockopt(b->b_fd, SOL_SOCKET, SO_NOSIGPIPE, &o, sizeof(o));
 #else
 		signal(SIGPIPE, SIG_IGN);
 #endif
 #endif
 	}
 
 	if (bl_isconnected(b)) {
 		BL_UNLOCK(b);
 		return 0;
 	}
 
 	/*
 	 * We try to connect anyway even when we are a server to verify
 	 * that no other server is listening to the socket. If we succeed
 	 * to connect and we are a server, someone else owns it.
 	 */
 	rv = connect(b->b_fd, (const void *)sun, (socklen_t)sizeof(*sun));
 	if (rv == 0) {
 		if (srv) {
 			bl_log(b->b_fun, LOG_ERR,
 			    "%s: another daemon is handling `%s'",
 			    __func__, sun->sun_path);
 			goto out;
 		}
 	} else {
 		if (!srv) {
 			/*
 			 * If the daemon is not running, we just try a
 			 * connect, so leave the socket alone until it does
 			 * and only log once.
 			 */
 			if (b->b_connected != 1) {
 				bl_log(b->b_fun, LOG_DEBUG,
 				    "%s: connect failed for `%s' (%s)",
 				    __func__, sun->sun_path, strerror(errno));
 				b->b_connected = 1;
 			}
 			BL_UNLOCK(b);
 			return -1;
 		}
 		bl_log(b->b_fun, LOG_DEBUG, "Connected to blacklist server",
 		    __func__);
 	}
 
 	if (srv) {
 		(void)unlink(sun->sun_path);
 		om = umask(0);
 		rv = bind(b->b_fd, (const void *)sun, (socklen_t)sizeof(*sun));
 		serrno = errno;
 		(void)umask(om);
 		errno = serrno;
 		if (rv == -1) {
 			bl_log(b->b_fun, LOG_ERR,
 			    "%s: bind failed for `%s' (%s)",
 			    __func__, sun->sun_path, strerror(errno));
 			goto out;
 		}
 	}
 
 	b->b_connected = 0;
 #define GOT_FD		1
 #if defined(LOCAL_CREDS)
 #define CRED_LEVEL	0
 #define	CRED_NAME	LOCAL_CREDS
 #define CRED_SC_UID	sc_euid
 #define CRED_SC_GID	sc_egid
 #define CRED_MESSAGE	SCM_CREDS
 #define CRED_SIZE	SOCKCREDSIZE(NGROUPS_MAX)
 #define CRED_TYPE	struct sockcred
 #define GOT_CRED	2
 #elif defined(SO_PASSCRED)
 #define CRED_LEVEL	SOL_SOCKET
 #define	CRED_NAME	SO_PASSCRED
 #define CRED_SC_UID	uid
 #define CRED_SC_GID	gid
 #define CRED_MESSAGE	SCM_CREDENTIALS
 #define CRED_SIZE	sizeof(struct ucred)
 #define CRED_TYPE	struct ucred
 #define GOT_CRED	2
 #else
 #define GOT_CRED	0
 /*
  * getpeereid() and LOCAL_PEERCRED don't help here
  * because we are not a stream socket!
  */
 #define	CRED_SIZE	0
 #define CRED_TYPE	void * __unused
 #endif
 
 #ifdef CRED_LEVEL
 	if (setsockopt(b->b_fd, CRED_LEVEL, CRED_NAME,
 	    &one, (socklen_t)sizeof(one)) == -1) {
 		bl_log(b->b_fun, LOG_ERR, "%s: setsockopt %s "
 		    "failed (%s)", __func__, __STRING(CRED_NAME),
 		    strerror(errno));
 		goto out;
 	}
 #endif
 
 	BL_UNLOCK(b);
 	return 0;
 out:
 	bl_reset(b, true);
 	BL_UNLOCK(b);
 	return -1;
 }
 
 bl_t
 bl_create(bool srv, const char *path, void (*fun)(int, const char *, va_list))
 {
 	bl_t b = calloc(1, sizeof(*b));
 	if (b == NULL)
 		goto out;
 	b->b_fun = fun == NULL ? vsyslog : fun;
 	b->b_fd = -1;
 	b->b_connected = -1;
 	BL_INIT(b);
 
 	memset(&b->b_sun, 0, sizeof(b->b_sun));
 	b->b_sun.sun_family = AF_LOCAL;
 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
 	b->b_sun.sun_len = sizeof(b->b_sun);
 #endif
 	strlcpy(b->b_sun.sun_path,
 	    path ? path : _PATH_BLSOCK, sizeof(b->b_sun.sun_path));
 
 	bl_init(b, srv);
 	return b;
 out:
 	free(b);
 	bl_log(fun, LOG_ERR, "%s: malloc failed (%s)", __func__,
 	    strerror(errno));
 	return NULL;
 }
 
 void
 bl_destroy(bl_t b)
 {
 	bl_reset(b, false);
 	free(b);
 }
 
 static int
 bl_getsock(bl_t b, struct sockaddr_storage *ss, const struct sockaddr *sa,
     socklen_t slen, const char *ctx)
 {
 	uint8_t family;
 
 	memset(ss, 0, sizeof(*ss));
 
 	switch (slen) {
 	case 0:
 		return 0;
 	case sizeof(struct sockaddr_in):
 		family = AF_INET;
 		break;
 	case sizeof(struct sockaddr_in6):
 		family = AF_INET6;
 		break;
 	default:
 		bl_log(b->b_fun, LOG_ERR, "%s: invalid socket len %u (%s)",
 		    __func__, (unsigned)slen, ctx);
 		errno = EINVAL;
 		return -1;
 	}
 
 	memcpy(ss, sa, slen);
 
 	if (ss->ss_family != family) {
 		bl_log(b->b_fun, LOG_INFO,
 		    "%s: correcting socket family %d to %d (%s)",
 		    __func__, ss->ss_family, family, ctx);
 		ss->ss_family = family;
 	}
 
 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
 	if (ss->ss_len != slen) {
 		bl_log(b->b_fun, LOG_INFO,
 		    "%s: correcting socket len %u to %u (%s)",
 		    __func__, ss->ss_len, (unsigned)slen, ctx);
 		ss->ss_len = (uint8_t)slen;
 	}
 #endif
 	return 0;
 }
 
 int
 bl_send(bl_t b, bl_type_t e, int pfd, const struct sockaddr *sa,
     socklen_t slen, const char *ctx)
 {
 	struct msghdr   msg;
 	struct iovec    iov;
 	union {
 		char ctrl[CMSG_SPACE(sizeof(int))];
 		uint32_t fd;
 	} ua;
 	struct cmsghdr *cmsg;
 	union {
 		bl_message_t bl;
 		char buf[512];
 	} ub;
 	size_t ctxlen, tried;
 #define NTRIES	5
 
 	ctxlen = strlen(ctx);
 	if (ctxlen > 128)
 		ctxlen = 128;
 
 	iov.iov_base = ub.buf;
 	iov.iov_len = sizeof(bl_message_t) + ctxlen;
 	ub.bl.bl_len = (uint32_t)iov.iov_len;
 	ub.bl.bl_version = BL_VERSION;
 	ub.bl.bl_type = (uint32_t)e;
 
 	if (bl_getsock(b, &ub.bl.bl_ss, sa, slen, ctx) == -1)
 		return -1;
 
 
 	ub.bl.bl_salen = slen;
 	memcpy(ub.bl.bl_data, ctx, ctxlen);
 
 	msg.msg_name = NULL;
 	msg.msg_namelen = 0;
 	msg.msg_iov = &iov;
 	msg.msg_iovlen = 1;
 	msg.msg_flags = 0;
 
 	msg.msg_control = ua.ctrl;
 	msg.msg_controllen = sizeof(ua.ctrl);
 
 	cmsg = CMSG_FIRSTHDR(&msg);
 	cmsg->cmsg_len = CMSG_LEN(sizeof(int));
 	cmsg->cmsg_level = SOL_SOCKET;
 	cmsg->cmsg_type = SCM_RIGHTS;
 
 	memcpy(CMSG_DATA(cmsg), &pfd, sizeof(pfd));
 
 	tried = 0;
 again:
 	if (bl_init(b, false) == -1)
 		return -1;
 
 	if ((sendmsg(b->b_fd, &msg, 0) == -1) && tried++ < NTRIES) {
 		bl_reset(b, false);
 		goto again;
 	}
 	return tried >= NTRIES ? -1 : 0;
 }
 
 bl_info_t *
 bl_recv(bl_t b)
 {
         struct msghdr   msg;
         struct iovec    iov;
 	union {
 		char ctrl[CMSG_SPACE(sizeof(int)) + CMSG_SPACE(CRED_SIZE)];
 		uint32_t fd;
 		CRED_TYPE sc;
 	} ua;
 	struct cmsghdr *cmsg;
 	CRED_TYPE *sc;
 	union {
 		bl_message_t bl;
 		char buf[512];
 	} ub;
 	int got;
 	ssize_t rlen;
 	size_t rem;
 	bl_info_t *bi = &b->b_info;
 
 	got = 0;
 	memset(bi, 0, sizeof(*bi));
 
 	iov.iov_base = ub.buf;
 	iov.iov_len = sizeof(ub);
 
 	msg.msg_name = NULL;
 	msg.msg_namelen = 0;
 	msg.msg_iov = &iov;
 	msg.msg_iovlen = 1;
 	msg.msg_flags = 0;
 
 	msg.msg_control = ua.ctrl;
 	msg.msg_controllen = sizeof(ua.ctrl) + 100;
 
         rlen = recvmsg(b->b_fd, &msg, 0);
         if (rlen == -1) {
 		bl_log(b->b_fun, LOG_ERR, "%s: recvmsg failed (%s)", __func__,
 		    strerror(errno));
 		return NULL;
         }
 
 	for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
 		if (cmsg->cmsg_level != SOL_SOCKET) {
 			bl_log(b->b_fun, LOG_ERR,
 			    "%s: unexpected cmsg_level %d",
 			    __func__, cmsg->cmsg_level);
 			continue;
 		}
 		switch (cmsg->cmsg_type) {
 		case SCM_RIGHTS:
 			if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) {
 				bl_log(b->b_fun, LOG_ERR,
 				    "%s: unexpected cmsg_len %d != %zu",
 				    __func__, cmsg->cmsg_len,
 				    CMSG_LEN(2 * sizeof(int)));
 				continue;
 			}
 			memcpy(&bi->bi_fd, CMSG_DATA(cmsg), sizeof(bi->bi_fd));
 			got |= GOT_FD;
 			break;
 #ifdef CRED_MESSAGE
 		case CRED_MESSAGE:
 			sc = (void *)CMSG_DATA(cmsg);
 			bi->bi_uid = sc->CRED_SC_UID;
 			bi->bi_gid = sc->CRED_SC_GID;
 			got |= GOT_CRED;
 			break;
 #endif
 		default:
 			bl_log(b->b_fun, LOG_ERR,
 			    "%s: unexpected cmsg_type %d",
 			    __func__, cmsg->cmsg_type);
 			continue;
 		}
 
 	}
 
 	if (got != (GOT_CRED|GOT_FD)) {
 		bl_log(b->b_fun, LOG_ERR, "message missing %s %s",
 #if GOT_CRED != 0
 		    (got & GOT_CRED) == 0 ? "cred" :
 #endif
 		    "", (got & GOT_FD) == 0 ? "fd" : "");
-
 		return NULL;
 	}
 
 	rem = (size_t)rlen;
 	if (rem < sizeof(ub.bl)) {
 		bl_log(b->b_fun, LOG_ERR, "message too short %zd", rlen);
 		return NULL;
 	}
 	rem -= sizeof(ub.bl);
 
 	if (ub.bl.bl_version != BL_VERSION) {
 		bl_log(b->b_fun, LOG_ERR, "bad version %d", ub.bl.bl_version);
 		return NULL;
 	}
 
 	bi->bi_type = ub.bl.bl_type;
 	bi->bi_slen = ub.bl.bl_salen;
 	bi->bi_ss = ub.bl.bl_ss;
 #ifndef CRED_MESSAGE
 	bi->bi_uid = -1;
 	bi->bi_gid = -1;
 #endif
 	rem = MIN(sizeof(bi->bi_msg), rem);
 	if (rem == 0)
 		bi->bi_msg[0] = '\0';
 	else
 		strlcpy(bi->bi_msg, ub.bl.bl_data, rem);
 	return bi;
 }