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