1/*++ 2/* NAME 3/* unix_connect 3 4/* SUMMARY 5/* connect to UNIX-domain listener 6/* SYNOPSIS 7/* #include <connect.h> 8/* 9/* int unix_connect(addr, block_mode, timeout) 10/* const char *addr; 11/* int block_mode; 12/* int timeout; 13/* DESCRIPTION 14/* unix_connect() connects to a listener in the UNIX domain at the 15/* specified address, and returns the resulting file descriptor. 16/* 17/* Arguments: 18/* .IP addr 19/* Null-terminated string with connection destination. 20/* .IP block_mode 21/* Either NON_BLOCKING for a non-blocking socket, or BLOCKING for 22/* blocking mode. 23/* .IP timeout 24/* Bounds the number of seconds that the operation may take. Specify 25/* a value <= 0 to disable the time limit. 26/* DIAGNOSTICS 27/* The result is -1 in case the connection could not be made. 28/* Fatal errors: other system call failures. 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 interfaces. */ 41 42#include <sys_defs.h> 43#include <sys/socket.h> 44#include <sys/un.h> 45#include <string.h> 46#include <unistd.h> 47#include <errno.h> 48 49/* Utility library. */ 50 51#include "msg.h" 52#include "iostuff.h" 53#include "sane_connect.h" 54#include "connect.h" 55#include "timed_connect.h" 56 57/* unix_connect - connect to UNIX-domain listener */ 58 59int unix_connect(const char *addr, int block_mode, int timeout) 60{ 61#undef sun 62 struct sockaddr_un sun; 63 int len = strlen(addr); 64 int sock; 65 66 /* 67 * Translate address information to internal form. 68 */ 69 if (len >= (int) sizeof(sun.sun_path)) 70 msg_fatal("unix-domain name too long: %s", addr); 71 memset((char *) &sun, 0, sizeof(sun)); 72 sun.sun_family = AF_UNIX; 73#ifdef HAS_SUN_LEN 74 sun.sun_len = len + 1; 75#endif 76 memcpy(sun.sun_path, addr, len + 1); 77 78 /* 79 * Create a client socket. 80 */ 81 if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) 82 return (-1); 83 84 /* 85 * Timed connect. 86 */ 87 if (timeout > 0) { 88 non_blocking(sock, NON_BLOCKING); 89 if (timed_connect(sock, (struct sockaddr *) & sun, sizeof(sun), timeout) < 0) { 90 close(sock); 91 return (-1); 92 } 93 if (block_mode != NON_BLOCKING) 94 non_blocking(sock, block_mode); 95 return (sock); 96 } 97 98 /* 99 * Maybe block until connected. 100 */ 101 else { 102 non_blocking(sock, block_mode); 103 if (sane_connect(sock, (struct sockaddr *) & sun, sizeof(sun)) < 0 104 && errno != EINPROGRESS) { 105 close(sock); 106 return (-1); 107 } 108 return (sock); 109 } 110} 111