1/*++ 2/* NAME 3/* mail_connect 3 4/* SUMMARY 5/* intra-mail system connection management 6/* SYNOPSIS 7/* #include <mail_proto.h> 8/* 9/* VSTREAM *mail_connect(class, name, block_mode) 10/* const char *class; 11/* const char *name; 12/* int block_mode; 13/* 14/* VSTREAM *mail_connect_wait(class, name) 15/* const char *class; 16/* const char *name; 17/* DESCRIPTION 18/* This module does low-level connection management for intra-mail 19/* communication. All reads and writes are subject to a time limit 20/* (controlled by the global variable \fIvar_ipc_timeout\fR). This 21/* protects against deadlock conditions that should never happen. 22/* 23/* mail_connect() attempts to connect to the UNIX-domain socket of 24/* the named subsystem. The result is a null pointer in case of failure. 25/* 26/* mail_connect_wait() is like mail_connect(), but keeps trying until 27/* the connection succeeds. However, mail_connect_wait() terminates 28/* with a fatal error when the service is down. This is to ensure that 29/* processes terminate when the mail system shuts down. 30/* 31/* Arguments: 32/* .IP class 33/* Name of a class of local transport channel endpoints, 34/* either \fIpublic\fR (accessible by any local user) or 35/* \fIprivate\fR (administrative access only). 36/* .IP service 37/* The name of a local transport endpoint within the named class. 38/* .IP block_mode 39/* NON_BLOCKING for a non-blocking connection, or BLOCKING. 40/* SEE ALSO 41/* timed_ipc(3), enforce IPC timeouts. 42/* LICENSE 43/* .ad 44/* .fi 45/* The Secure Mailer license must be distributed with this software. 46/* AUTHOR(S) 47/* Wietse Venema 48/* IBM T.J. Watson Research 49/* P.O. Box 704 50/* Yorktown Heights, NY 10598, USA 51/*--*/ 52 53/* System library. */ 54 55#include <sys_defs.h> 56#include <fcntl.h> 57#include <unistd.h> 58#include <stdlib.h> 59#include <stdarg.h> 60#include <errno.h> 61 62/* Utility library. */ 63 64#include <msg.h> 65#include <vstream.h> 66#include <connect.h> 67#include <mymalloc.h> 68#include <iostuff.h> 69#include <stringops.h> 70 71/* Global library. */ 72 73#include "timed_ipc.h" 74#include "mail_proto.h" 75 76/* mail_connect - connect to mail subsystem */ 77 78VSTREAM *mail_connect(const char *class, const char *name, int block_mode) 79{ 80 char *path; 81 VSTREAM *stream; 82 int fd; 83 char *sock_name; 84 85 path = mail_pathname(class, name); 86 if ((fd = LOCAL_CONNECT(path, block_mode, 0)) < 0) { 87 if (msg_verbose) 88 msg_info("connect to subsystem %s: %m", path); 89 stream = 0; 90 } else { 91 if (msg_verbose) 92 msg_info("connect to subsystem %s", path); 93 stream = vstream_fdopen(fd, O_RDWR); 94 timed_ipc_setup(stream); 95 sock_name = concatenate(path, " socket", (char *) 0); 96 vstream_control(stream, 97 VSTREAM_CTL_PATH, sock_name, 98 VSTREAM_CTL_END); 99 myfree(sock_name); 100 } 101 myfree(path); 102 return (stream); 103} 104 105/* mail_connect_wait - connect to mail service until it succeeds */ 106 107VSTREAM *mail_connect_wait(const char *class, const char *name) 108{ 109 VSTREAM *stream; 110 int count = 0; 111 112 /* 113 * XXX Solaris workaround for ECONNREFUSED on a busy socket. 114 */ 115 while ((stream = mail_connect(class, name, BLOCKING)) == 0) { 116 if (count++ >= 10) { 117 msg_fatal("connect #%d to subsystem %s/%s: %m", 118 count, class, name); 119 } else { 120 msg_warn("connect #%d to subsystem %s/%s: %m", 121 count, class, name); 122 } 123 sleep(10); /* XXX make configurable */ 124 } 125 return (stream); 126} 127