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