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