summaryrefslogtreecommitdiffstats
path: root/contrib/sendmail/libmilter/listener.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/sendmail/libmilter/listener.c')
-rw-r--r--contrib/sendmail/libmilter/listener.c68
1 files changed, 57 insertions, 11 deletions
diff --git a/contrib/sendmail/libmilter/listener.c b/contrib/sendmail/libmilter/listener.c
index 5eb5f32..bb7a297 100644
--- a/contrib/sendmail/libmilter/listener.c
+++ b/contrib/sendmail/libmilter/listener.c
@@ -9,7 +9,7 @@
*/
#include <sm/gen.h>
-SM_RCSID("@(#)$Id: listener.c,v 8.85.2.12 2003/08/04 18:47:29 ca Exp $")
+SM_RCSID("@(#)$Id: listener.c,v 8.85.2.17 2003/10/21 17:22:57 ca Exp $")
/*
** listener.c -- threaded network listener
@@ -18,6 +18,9 @@ SM_RCSID("@(#)$Id: listener.c,v 8.85.2.12 2003/08/04 18:47:29 ca Exp $")
#include "libmilter.h"
#include <sm/errstring.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
# if NETINET || NETINET6
# include <arpa/inet.h>
@@ -28,26 +31,29 @@ static int L_family;
static SOCKADDR_LEN_T L_socksize;
static socket_t listenfd = INVALID_SOCKET;
-static socket_t mi_milteropen __P((char *, int, char *));
+static socket_t mi_milteropen __P((char *, int, bool, char *));
/*
** MI_OPENSOCKET -- create the socket where this filter and the MTA will meet
**
-** Parameters:
+** Parameters:
** conn -- connection description
** backlog -- listen backlog
-** dbg -- debug level
+** dbg -- debug level
+** rmsocket -- if true, try to unlink() the socket first
+** (UNIX domain sockets only)
** smfi -- filter structure to use
**
-** Return value:
-** MI_SUCCESS/MI_FAILURE
+** Return value:
+** MI_SUCCESS/MI_FAILURE
*/
int
-mi_opensocket(conn, backlog, dbg, smfi)
+mi_opensocket(conn, backlog, dbg, rmsocket, smfi)
char *conn;
int backlog;
int dbg;
+ bool rmsocket;
smfiDesc_ptr smfi;
{
if (smfi == NULL || conn == NULL)
@@ -64,7 +70,7 @@ mi_opensocket(conn, backlog, dbg, smfi)
}
(void) smutex_init(&L_Mutex);
(void) smutex_lock(&L_Mutex);
- listenfd = mi_milteropen(conn, backlog, smfi->xxfi_name);
+ listenfd = mi_milteropen(conn, backlog, rmsocket, smfi->xxfi_name);
if (!ValidSocket(listenfd))
{
smi_log(SMI_LOG_FATAL,
@@ -91,6 +97,8 @@ mi_opensocket(conn, backlog, dbg, smfi)
** Parameters:
** conn -- connection description
** backlog -- listen backlog
+** rmsocket -- if true, try to unlink() the socket first
+** (UNIX domain sockets only)
** name -- name for logging
**
** Returns:
@@ -105,9 +113,10 @@ static char *sockpath = NULL;
#endif /* NETUNIX */
static socket_t
-mi_milteropen(conn, backlog, name)
+mi_milteropen(conn, backlog, rmsocket, name)
char *conn;
int backlog;
+ bool rmsocket;
char *name;
{
socket_t sock;
@@ -457,6 +466,41 @@ mi_milteropen(conn, backlog, name)
return INVALID_SOCKET;
}
+#if NETUNIX
+ if (addr.sa.sa_family == AF_UNIX && rmsocket)
+ {
+ struct stat s;
+
+ if (stat(colon, &s) != 0)
+ {
+ if (errno != ENOENT)
+ {
+ smi_log(SMI_LOG_ERR,
+ "%s: Unable to stat() %s: %s",
+ name, colon, sm_errstring(errno));
+ (void) closesocket(sock);
+ return INVALID_SOCKET;
+ }
+ }
+ else if (!S_ISSOCK(s.st_mode))
+ {
+ smi_log(SMI_LOG_ERR,
+ "%s: %s is not a UNIX domain socket",
+ name, colon);
+ (void) closesocket(sock);
+ return INVALID_SOCKET;
+ }
+ else if (unlink(colon) != 0)
+ {
+ smi_log(SMI_LOG_ERR,
+ "%s: Unable to remove %s: %s",
+ name, colon, sm_errstring(errno));
+ (void) closesocket(sock);
+ return INVALID_SOCKET;
+ }
+ }
+#endif /* NETUNIX */
+
if (bind(sock, &addr.sa, L_socksize) < 0)
{
smi_log(SMI_LOG_ERR,
@@ -591,9 +635,11 @@ mi_closener()
** Parameters:
** conn -- connection description
** dbg -- debug level
+** rmsocket -- if true, try to unlink() the socket first
+** (UNIX domain sockets only)
** smfi -- filter structure to use
** timeout -- timeout for reads/writes
-** backlog -- listen queue backlog size
+** backlog -- listen queue backlog size
**
** Returns:
** MI_SUCCESS -- Exited normally
@@ -673,7 +719,7 @@ mi_listener(conn, dbg, smfi, timeout, backlog)
FD_RD_VAR(rds, excs);
struct timeval chktime;
- if (mi_opensocket(conn, backlog, dbg, smfi) == MI_FAILURE)
+ if (mi_opensocket(conn, backlog, dbg, false, smfi) == MI_FAILURE)
return MI_FAILURE;
clilen = L_socksize;
OpenPOWER on IntegriCloud