1/* $NetBSD$ */ 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 56int 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 80int 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