1/*++ 2/* NAME 3/* unix_listen 3 4/* SUMMARY 5/* start UNIX-domain listener 6/* SYNOPSIS 7/* #include <listen.h> 8/* 9/* int unix_listen(addr, backlog, block_mode) 10/* const char *addr; 11/* int backlog; 12/* int block_mode; 13/* 14/* int unix_accept(fd) 15/* int fd; 16/* DESCRIPTION 17/* The \fBunix_listen\fR() routine starts a listener in the UNIX domain 18/* on the specified address, with the specified backlog, and returns 19/* the resulting file descriptor. 20/* 21/* unix_accept() accepts a connection and sanitizes error results. 22/* 23/* Arguments: 24/* .IP addr 25/* Null-terminated string with connection destination. 26/* .IP backlog 27/* This argument is passed on to the \fIlisten(2)\fR routine. 28/* .IP block_mode 29/* Either NON_BLOCKING for a non-blocking socket, or BLOCKING for 30/* blocking mode. 31/* .IP fd 32/* File descriptor returned by unix_listen(). 33/* DIAGNOSTICS 34/* Fatal errors: unix_listen() aborts upon any system call failure. 35/* unix_accept() leaves all error handling up to the caller. 36/* LICENSE 37/* .ad 38/* .fi 39/* The Secure Mailer license must be distributed with this software. 40/* AUTHOR(S) 41/* Wietse Venema 42/* IBM T.J. Watson Research 43/* P.O. Box 704 44/* Yorktown Heights, NY 10598, USA 45/*--*/ 46 47/* System interfaces. */ 48 49#include <sys_defs.h> 50#include <sys/socket.h> 51#include <sys/un.h> 52#include <string.h> 53#include <unistd.h> 54#include <sys/stat.h> 55#include <errno.h> 56 57/* Utility library. */ 58 59#include "msg.h" 60#include "iostuff.h" 61#include "listen.h" 62#include "sane_accept.h" 63 64/* unix_listen - create UNIX-domain listener */ 65 66int unix_listen(const char *addr, int backlog, int block_mode) 67{ 68#undef sun 69 struct sockaddr_un sun; 70 int len = strlen(addr); 71 int sock; 72 73 /* 74 * Translate address information to internal form. 75 */ 76 if (len >= (int) sizeof(sun.sun_path)) 77 msg_fatal("unix-domain name too long: %s", addr); 78 memset((char *) &sun, 0, sizeof(sun)); 79 sun.sun_family = AF_UNIX; 80#ifdef HAS_SUN_LEN 81 sun.sun_len = len + 1; 82#endif 83 memcpy(sun.sun_path, addr, len + 1); 84 85 /* 86 * Create a listener socket. Do whatever we can so we don't run into 87 * trouble when this process is restarted after crash. 88 */ 89 if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) 90 msg_fatal("socket: %m"); 91 if (unlink(addr) < 0 && errno != ENOENT) 92 msg_fatal("remove %s: %m", addr); 93 if (bind(sock, (struct sockaddr *) & sun, sizeof(sun)) < 0) 94 msg_fatal("bind: %s: %m", addr); 95#ifdef FCHMOD_UNIX_SOCKETS 96 if (fchmod(sock, 0666) < 0) 97 msg_fatal("fchmod socket %s: %m", addr); 98#else 99 if (chmod(addr, 0666) < 0) 100 msg_fatal("chmod socket %s: %m", addr); 101#endif 102 non_blocking(sock, block_mode); 103 if (listen(sock, backlog) < 0) 104 msg_fatal("listen: %m"); 105 return (sock); 106} 107 108/* unix_accept - accept connection */ 109 110int unix_accept(int fd) 111{ 112 return (sane_accept(fd, (struct sockaddr *) 0, (SOCKADDR_SIZE *) 0)); 113} 114