Description: systemd-like socket activation support for libmilter Author: Mikhail Gusarov {unix|local}:/path/to/file -- A named pipe.
  • inet:port@{hostname|ip-address} -- An IPV4 socket.
  • inet6:port@{hostname|ip-address} -- An IPV6 socket. +
  • fd:number -- Pre-opened file descriptor. diff --git a/libmilter/listener.c b/libmilter/listener.c index 48c552f..2249a1f 100644 --- a/libmilter/listener.c +++ b/libmilter/listener.c @@ -197,6 +197,11 @@ mi_milteropen(conn, backlog, rmsocket, name) L_socksize = sizeof addr.sin6; } #endif /* NETINET6 */ + else if (strcasecmp(p, "fd") == 0) + { + addr.sa.sa_family = AF_UNSPEC; + L_socksize = sizeof (_SOCK_ADDR); + } else { smi_log(SMI_LOG_ERR, "%s: unknown socket type %s", @@ -443,7 +448,21 @@ mi_milteropen(conn, backlog, rmsocket, name) } #endif /* NETINET || NETINET6 */ - sock = socket(addr.sa.sa_family, SOCK_STREAM, 0); + if (addr.sa.sa_family == AF_UNSPEC) + { + char *end; + sock = strtol(colon, &end, 10); + if (*end != '\0' || sock < 0) + { + smi_log(SMI_LOG_ERR, "%s: expected positive integer as fd, got %s", name, colon); + return INVALID_SOCKET; + } + } + else + { + sock = socket(addr.sa.sa_family, SOCK_STREAM, 0); + } + if (!ValidSocket(sock)) { smi_log(SMI_LOG_ERR, @@ -466,6 +485,7 @@ mi_milteropen(conn, backlog, rmsocket, name) #if NETUNIX addr.sa.sa_family != AF_UNIX && #endif /* NETUNIX */ + addr.sa.sa_family != AF_UNSPEC && setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *) &sockopt, sizeof(sockopt)) == -1) { @@ -511,7 +531,8 @@ mi_milteropen(conn, backlog, rmsocket, name) } #endif /* NETUNIX */ - if (bind(sock, &addr.sa, L_socksize) < 0) + if (addr.sa.sa_family != AF_UNSPEC && + bind(sock, &addr.sa, L_socksize) < 0) { smi_log(SMI_LOG_ERR, "%s: Unable to bind to port %s: %s", @@ -817,7 +838,7 @@ mi_listener(conn, dbg, smfi, timeout, backlog) # ifdef BSD4_4_SOCKADDR cliaddr.sa.sa_len == 0 || # endif /* BSD4_4_SOCKADDR */ - cliaddr.sa.sa_family != L_family)) + (L_family != AF_UNSPEC && cliaddr.sa.sa_family != L_family))) { (void) closesocket(connfd); connfd = INVALID_SOCKET;