1/*++
2/* NAME
3/*	unix_pass_listen 3
4/* SUMMARY
5/*	start UNIX-domain file descriptor listener
6/* SYNOPSIS
7/*	#include <listen.h>
8/*
9/*	int	unix_pass_listen(path, backlog, block_mode)
10/*	const char *path;
11/*	int	backlog;
12/*	int	block_mode;
13/*
14/*	int	unix_pass_accept(fd)
15/*	int	fd;
16/* DESCRIPTION
17/*	This module implements a listener that receives one file descriptor
18/*	across each UNIX-domain connection that is made to it.
19/*
20/*	unix_pass_listen() creates a listener endpoint with the specified
21/*	permissions, and returns a file descriptor to be used for accepting
22/*	descriptors.
23/*
24/*	unix_pass_accept() accepts a descriptor.
25/*
26/*	Arguments:
27/* .IP path
28/*	Null-terminated string with connection destination.
29/* .IP backlog
30/*	This argument exists for compatibility and is ignored.
31/* .IP block_mode
32/*	Either NON_BLOCKING or BLOCKING. This does not affect the
33/*	mode of accepted connections.
34/* .IP fd
35/*	File descriptor returned by unix_pass_listen().
36/* DIAGNOSTICS
37/*	Fatal errors: unix_pass_listen() aborts upon any system call failure.
38/*	unix_pass_accept() leaves all error handling up to the caller.
39/* LICENSE
40/* .ad
41/* .fi
42/*	The Secure Mailer license must be distributed with this software.
43/* AUTHOR(S)
44/*	Wietse Venema
45/*	IBM T.J. Watson Research
46/*	P.O. Box 704
47/*	Yorktown Heights, NY 10598, USA
48/*--*/
49
50/* System library. */
51
52#include <sys_defs.h>
53#include <sys/socket.h>
54#include <errno.h>
55#include <unistd.h>
56
57/* Utility library. */
58
59#include <msg.h>
60#include <sane_accept.h>
61#include <listen.h>
62
63/* unix_pass_accept - accept descriptor */
64
65int     unix_pass_accept(int listen_fd)
66{
67    const char *myname = "unix_pass_accept";
68    int     accept_fd;
69    int     recv_fd = -1;
70
71    accept_fd = sane_accept(listen_fd, (struct sockaddr *) 0, (SOCKADDR_SIZE *) 0);
72    if (accept_fd < 0) {
73	if (errno != EAGAIN)
74	    msg_warn("%s: accept connection: %m", myname);
75	return (-1);
76    } else {
77	if (read_wait(accept_fd, 100) < 0)
78	    msg_warn("%s: timeout receiving file descriptor: %m", myname);
79	else if ((recv_fd = unix_recv_fd(accept_fd)) < 0)
80	    msg_warn("%s: cannot receive file descriptor: %m", myname);
81	if (close(accept_fd) < 0)
82	    msg_warn("%s: close: %m", myname);
83	return (recv_fd);
84    }
85}
86