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 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 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