xref: /netbsd-src/external/ibm-public/postfix/dist/src/util/pass_accept.c (revision e6ca80d43962864f49719de05ed892793630d07f)
1*e6ca80d4Stron /*	$NetBSD: pass_accept.c,v 1.1.1.1 2013/09/25 19:06:37 tron Exp $	*/
2*e6ca80d4Stron 
3*e6ca80d4Stron /*++
4*e6ca80d4Stron /* NAME
5*e6ca80d4Stron /*	pass_accept 3
6*e6ca80d4Stron /* SUMMARY
7*e6ca80d4Stron /*	start UNIX-domain file descriptor listener
8*e6ca80d4Stron /* SYNOPSIS
9*e6ca80d4Stron /*	#include <listen.h>
10*e6ca80d4Stron /*
11*e6ca80d4Stron /*	int	pass_accept(listen_fd)
12*e6ca80d4Stron /*	int	listen_fd;
13*e6ca80d4Stron /*
14*e6ca80d4Stron /*	int	pass_accept_attr(listen_fd, attr)
15*e6ca80d4Stron /*	int	listen_fd;
16*e6ca80d4Stron /*	HTABLE	**attr;
17*e6ca80d4Stron /* DESCRIPTION
18*e6ca80d4Stron /*	This module implements a listener that receives one attribute list
19*e6ca80d4Stron /*	and file descriptor over each a local connection that is made to it.
20*e6ca80d4Stron /*
21*e6ca80d4Stron /*	Arguments:
22*e6ca80d4Stron /* .IP attr
23*e6ca80d4Stron /*	Pointer to attribute list pointer.  In case of error, or
24*e6ca80d4Stron /*	no attributes, the attribute list pointer is set to null.
25*e6ca80d4Stron /* .IP listen_fd
26*e6ca80d4Stron /*	File descriptor returned by LOCAL_LISTEN().
27*e6ca80d4Stron /* DIAGNOSTICS
28*e6ca80d4Stron /*	Warnings: I/O errors, timeout.
29*e6ca80d4Stron /* LICENSE
30*e6ca80d4Stron /* .ad
31*e6ca80d4Stron /* .fi
32*e6ca80d4Stron /*	The Secure Mailer license must be distributed with this software.
33*e6ca80d4Stron /* AUTHOR(S)
34*e6ca80d4Stron /*	Wietse Venema
35*e6ca80d4Stron /*	IBM T.J. Watson Research
36*e6ca80d4Stron /*	P.O. Box 704
37*e6ca80d4Stron /*	Yorktown Heights, NY 10598, USA
38*e6ca80d4Stron /*--*/
39*e6ca80d4Stron 
40*e6ca80d4Stron /* System library. */
41*e6ca80d4Stron 
42*e6ca80d4Stron #include <sys_defs.h>
43*e6ca80d4Stron #include <errno.h>
44*e6ca80d4Stron #include <unistd.h>
45*e6ca80d4Stron 
46*e6ca80d4Stron /* Utility library. */
47*e6ca80d4Stron 
48*e6ca80d4Stron #include <msg.h>
49*e6ca80d4Stron #include <listen.h>
50*e6ca80d4Stron #include <attr.h>
51*e6ca80d4Stron 
52*e6ca80d4Stron #define PASS_ACCEPT_TMOUT	100
53*e6ca80d4Stron 
54*e6ca80d4Stron /* pass_accept - accept descriptor */
55*e6ca80d4Stron 
pass_accept(int listen_fd)56*e6ca80d4Stron int     pass_accept(int listen_fd)
57*e6ca80d4Stron {
58*e6ca80d4Stron     const char *myname = "pass_accept";
59*e6ca80d4Stron     int     accept_fd;
60*e6ca80d4Stron     int     recv_fd = -1;
61*e6ca80d4Stron 
62*e6ca80d4Stron     accept_fd = LOCAL_ACCEPT(listen_fd);
63*e6ca80d4Stron     if (accept_fd < 0) {
64*e6ca80d4Stron 	if (errno != EAGAIN)
65*e6ca80d4Stron 	    msg_warn("%s: cannot accept connection: %m", myname);
66*e6ca80d4Stron 	return (-1);
67*e6ca80d4Stron     } else {
68*e6ca80d4Stron 	if (read_wait(accept_fd, PASS_ACCEPT_TMOUT) < 0)
69*e6ca80d4Stron 	    msg_warn("%s: timeout receiving file descriptor: %m", myname);
70*e6ca80d4Stron 	else if ((recv_fd = LOCAL_RECV_FD(accept_fd)) < 0)
71*e6ca80d4Stron 	    msg_warn("%s: cannot receive file descriptor: %m", myname);
72*e6ca80d4Stron 	if (close(accept_fd) < 0)
73*e6ca80d4Stron 	    msg_warn("%s: close: %m", myname);
74*e6ca80d4Stron 	return (recv_fd);
75*e6ca80d4Stron     }
76*e6ca80d4Stron }
77*e6ca80d4Stron 
78*e6ca80d4Stron /* pass_accept_attr - accept descriptor and attribute list */
79*e6ca80d4Stron 
pass_accept_attr(int listen_fd,HTABLE ** attr)80*e6ca80d4Stron int     pass_accept_attr(int listen_fd, HTABLE **attr)
81*e6ca80d4Stron {
82*e6ca80d4Stron     const char *myname = "pass_accept_attr";
83*e6ca80d4Stron     int     accept_fd;
84*e6ca80d4Stron     int     recv_fd = -1;
85*e6ca80d4Stron 
86*e6ca80d4Stron     *attr = 0;
87*e6ca80d4Stron     accept_fd = LOCAL_ACCEPT(listen_fd);
88*e6ca80d4Stron     if (accept_fd < 0) {
89*e6ca80d4Stron 	if (errno != EAGAIN)
90*e6ca80d4Stron 	    msg_warn("%s: cannot accept connection: %m", myname);
91*e6ca80d4Stron 	return (-1);
92*e6ca80d4Stron     } else {
93*e6ca80d4Stron 	if (read_wait(accept_fd, PASS_ACCEPT_TMOUT) < 0)
94*e6ca80d4Stron 	    msg_warn("%s: timeout receiving file descriptor: %m", myname);
95*e6ca80d4Stron 	else if ((recv_fd = LOCAL_RECV_FD(accept_fd)) < 0)
96*e6ca80d4Stron 	    msg_warn("%s: cannot receive file descriptor: %m", myname);
97*e6ca80d4Stron 	else if (read_wait(accept_fd, PASS_ACCEPT_TMOUT) < 0
98*e6ca80d4Stron 	     || recv_pass_attr(accept_fd, attr, PASS_ACCEPT_TMOUT, 0) < 0) {
99*e6ca80d4Stron 	    msg_warn("%s: cannot receive connection attributes: %m", myname);
100*e6ca80d4Stron 	    if (close(recv_fd) < 0)
101*e6ca80d4Stron 		msg_warn("%s: close: %m", myname);
102*e6ca80d4Stron 	    recv_fd = -1;
103*e6ca80d4Stron 	}
104*e6ca80d4Stron 	if (close(accept_fd) < 0)
105*e6ca80d4Stron 	    msg_warn("%s: close: %m", myname);
106*e6ca80d4Stron 	return (recv_fd);
107*e6ca80d4Stron     }
108*e6ca80d4Stron }
109