1/*++
2/* NAME
3/*	stream_connect 3
4/* SUMMARY
5/*	connect to stream listener
6/* SYNOPSIS
7/*	#include <connect.h>
8/*
9/*	int	stream_connect(path, block_mode, timeout)
10/*	const char *path;
11/*	int	block_mode;
12/*	int	timeout;
13/* DESCRIPTION
14/*	stream_connect() connects to a stream listener for the specified
15/*	pathname, and returns the resulting file descriptor.
16/*
17/*	Arguments:
18/* .IP path
19/*	Null-terminated string with listener endpoint name.
20/* .IP block_mode
21/*	Either NON_BLOCKING for a non-blocking stream, or BLOCKING for
22/*	blocking mode. However, a stream connection succeeds or fails
23/*	immediately.
24/* .IP timeout
25/*	This argument is ignored; it is present for compatibility with
26/*	other interfaces. Stream connections succeed or fail immediately.
27/* DIAGNOSTICS
28/*	The result is -1 in case the connection could not be made.
29/*	Fatal errors: other system call failures.
30/* LICENSE
31/* .ad
32/* .fi
33/*	The Secure Mailer license must be distributed with this software.
34/* AUTHOR(S)
35/*	Wietse Venema
36/*	IBM T.J. Watson Research
37/*	P.O. Box 704
38/*	Yorktown Heights, NY 10598, USA
39/*--*/
40
41/* System library. */
42
43#include <sys_defs.h>
44
45#ifdef STREAM_CONNECTIONS
46
47#include <sys/stat.h>
48#include <unistd.h>
49#include <fcntl.h>
50#include <errno.h>
51#include <stropts.h>
52
53#endif
54
55/* Utility library. */
56
57#include <msg.h>
58#include <connect.h>
59
60/* stream_connect - connect to stream listener */
61
62int     stream_connect(const char *path, int block_mode, int unused_timeout)
63{
64#ifdef STREAM_CONNECTIONS
65    const char *myname = "stream_connect";
66    int     pair[2];
67    int     fifo;
68
69    /*
70     * The requested file system object must exist, otherwise we can't reach
71     * the server.
72     */
73    if ((fifo = open(path, O_WRONLY | O_NONBLOCK, 0)) < 0)
74	return (-1);
75
76    /*
77     * This is for {unix,inet}_connect() compatibility.
78     */
79    if (block_mode == BLOCKING)
80	non_blocking(fifo, BLOCKING);
81
82    /*
83     * Create a pipe, and send one pipe end to the server.
84     */
85    if (pipe(pair) < 0)
86	msg_fatal("%s: pipe: %m", myname);
87    if (ioctl(fifo, I_SENDFD, pair[1]) < 0)
88	msg_fatal("%s: send file descriptor: %m", myname);
89    close(pair[1]);
90
91    /*
92     * This is for {unix,inet}_connect() compatibility.
93     */
94    if (block_mode == NON_BLOCKING)
95	non_blocking(pair[0], NON_BLOCKING);
96
97    /*
98     * Cleanup.
99     */
100    close(fifo);
101
102    /*
103     * Keep the other end of the pipe.
104     */
105    return (pair[0]);
106#else
107    msg_fatal("stream connections are not implemented");
108#endif
109}
110