xref: /netbsd-src/external/ibm-public/postfix/dist/src/global/mail_connect.c (revision e89934bbf778a6d6d6894877c4da59d0c7835b0f)
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 
mail_connect(const char * class,const char * name,int block_mode)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 
mail_connect_wait(const char * class,const char * name)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