1 /* $NetBSD: mail_connect.c,v 1.1.1.1 2009/06/23 10:08:46 tron 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 /* 28 /* mail_connect_wait() is like mail_connect(), but keeps trying until 29 /* the connection succeeds. However, mail_connect_wait() terminates 30 /* with a fatal error when the service is down. This is to ensure that 31 /* processes terminate when the mail system shuts down. 32 /* 33 /* Arguments: 34 /* .IP class 35 /* Name of a class of local transport channel endpoints, 36 /* either \fIpublic\fR (accessible by any local user) or 37 /* \fIprivate\fR (administrative access only). 38 /* .IP service 39 /* The name of a local transport endpoint within the named class. 40 /* .IP block_mode 41 /* NON_BLOCKING for a non-blocking connection, or BLOCKING. 42 /* SEE ALSO 43 /* timed_ipc(3), enforce IPC timeouts. 44 /* LICENSE 45 /* .ad 46 /* .fi 47 /* The Secure Mailer license must be distributed with this software. 48 /* AUTHOR(S) 49 /* Wietse Venema 50 /* IBM T.J. Watson Research 51 /* P.O. Box 704 52 /* Yorktown Heights, NY 10598, USA 53 /*--*/ 54 55 /* System library. */ 56 57 #include <sys_defs.h> 58 #include <fcntl.h> 59 #include <unistd.h> 60 #include <stdlib.h> 61 #include <stdarg.h> 62 #include <errno.h> 63 64 /* Utility library. */ 65 66 #include <msg.h> 67 #include <vstream.h> 68 #include <connect.h> 69 #include <mymalloc.h> 70 #include <iostuff.h> 71 #include <stringops.h> 72 73 /* Global library. */ 74 75 #include "timed_ipc.h" 76 #include "mail_proto.h" 77 78 /* mail_connect - connect to mail subsystem */ 79 80 VSTREAM *mail_connect(const char *class, const char *name, int block_mode) 81 { 82 char *path; 83 VSTREAM *stream; 84 int fd; 85 char *sock_name; 86 87 path = mail_pathname(class, name); 88 if ((fd = LOCAL_CONNECT(path, block_mode, 0)) < 0) { 89 if (msg_verbose) 90 msg_info("connect to subsystem %s: %m", path); 91 stream = 0; 92 } else { 93 if (msg_verbose) 94 msg_info("connect to subsystem %s", path); 95 stream = vstream_fdopen(fd, O_RDWR); 96 timed_ipc_setup(stream); 97 sock_name = concatenate(path, " socket", (char *) 0); 98 vstream_control(stream, 99 VSTREAM_CTL_PATH, sock_name, 100 VSTREAM_CTL_END); 101 myfree(sock_name); 102 } 103 myfree(path); 104 return (stream); 105 } 106 107 /* mail_connect_wait - connect to mail service until it succeeds */ 108 109 VSTREAM *mail_connect_wait(const char *class, const char *name) 110 { 111 VSTREAM *stream; 112 int count = 0; 113 114 /* 115 * XXX Solaris workaround for ECONNREFUSED on a busy socket. 116 */ 117 while ((stream = mail_connect(class, name, BLOCKING)) == 0) { 118 if (count++ >= 10) { 119 msg_fatal("connect #%d to subsystem %s/%s: %m", 120 count, class, name); 121 } else { 122 msg_warn("connect #%d to subsystem %s/%s: %m", 123 count, class, name); 124 } 125 sleep(10); /* XXX make configurable */ 126 } 127 return (stream); 128 } 129