1/******************************************************************************
2
3
4Copyright 1993, 1998  The Open Group
5
6Permission to use, copy, modify, distribute, and sell this software and its
7documentation for any purpose is hereby granted without fee, provided that
8the above copyright notice appear in all copies and that both that
9copyright notice and this permission notice appear in supporting
10documentation.
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall not be
23used in advertising or otherwise to promote the sale, use or other dealings
24in this Software without prior written authorization from The Open Group.
25
26Author: Ralph Mor,  X Consortium
27******************************************************************************/
28
29#ifdef HAVE_CONFIG_H
30#include <config.h>
31#endif
32#include <X11/ICE/ICElib.h>
33#include "ICElibint.h"
34#include <X11/Xtrans/Xtrans.h>
35#include <stdio.h>
36
37
38Status
39IceListenForConnections (
40	int		*countRet,
41	IceListenObj	**listenObjsRet,
42	int		errorLength,
43	char		*errorStringRet
44)
45{
46    struct _IceListenObj	*listenObjs;
47    char			*networkId;
48    int				transCount, partial, i, j;
49    Status			status = 1;
50    XtransConnInfo		*transConns = NULL;
51
52
53    if ((_IceTransMakeAllCOTSServerListeners (NULL, &partial,
54	&transCount, &transConns) < 0) || (transCount < 1))
55    {
56	*listenObjsRet = NULL;
57	*countRet = 0;
58
59	if (errorStringRet && errorLength > 0) {
60	    strncpy (errorStringRet,
61		"Cannot establish any listening sockets", errorLength);
62	    errorStringRet[errorLength - 1] = '\0';
63	}
64
65	return (0);
66    }
67
68    if ((listenObjs = malloc (transCount * sizeof (struct _IceListenObj))) == NULL)
69    {
70	for (i = 0; i < transCount; i++)
71	    _IceTransClose (transConns[i]);
72	free (transConns);
73	return (0);
74    }
75
76    *countRet = 0;
77
78    for (i = 0; i < transCount; i++)
79    {
80	_IceTransSetOption(transConns[i], TRANS_CLOSEONEXEC, 1);
81
82	networkId = _IceTransGetMyNetworkId (transConns[i]);
83
84	if (networkId)
85	{
86	    listenObjs[*countRet].trans_conn = transConns[i];
87	    listenObjs[*countRet].network_id = networkId;
88
89	    (*countRet)++;
90	}
91    }
92
93    if (*countRet == 0)
94    {
95	*listenObjsRet = NULL;
96
97	if (errorStringRet && errorLength > 0) {
98	    strncpy (errorStringRet,
99		"Cannot establish any listening sockets", errorLength);
100	    errorStringRet[errorLength - 1] = '\0';
101	}
102
103	status = 0;
104    }
105    else
106    {
107	*listenObjsRet = malloc (*countRet * sizeof (IceListenObj));
108
109	if (*listenObjsRet == NULL)
110	{
111	    if (errorStringRet && errorLength > 0) {
112		strncpy (errorStringRet, "Malloc failed", errorLength);
113		errorStringRet[errorLength - 1] = '\0';
114	    }
115
116	    status = 0;
117	}
118	else
119	{
120	    for (i = 0; i < *countRet; i++)
121	    {
122		(*listenObjsRet)[i] = malloc (sizeof (struct _IceListenObj));
123
124		if ((*listenObjsRet)[i] == NULL)
125		{
126		    if (errorStringRet && errorLength > 0) {
127			strncpy (errorStringRet, "Malloc failed", errorLength);
128			errorStringRet[errorLength - 1] = '\0';
129		    }
130
131		    for (j = 0; j < i; j++)
132			free ((*listenObjsRet)[j]);
133
134		    free (*listenObjsRet);
135		    *listenObjsRet = NULL;
136
137		    status = 0;
138		    break;
139		}
140		else
141		{
142		    *((*listenObjsRet)[i]) = listenObjs[i];
143		}
144	    }
145	}
146    }
147
148    if (status == 1)
149    {
150	if (errorStringRet && errorLength > 0)
151	    *errorStringRet = '\0';
152
153	for (i = 0; i < *countRet; i++)
154	{
155	    (*listenObjsRet)[i]->host_based_auth_proc = NULL;
156	}
157    }
158    else
159    {
160	for (i = 0; i < transCount; i++)
161	    _IceTransClose (transConns[i]);
162    }
163
164    free (listenObjs);
165    free (transConns);
166
167    return (status);
168}
169
170
171
172int
173IceGetListenConnectionNumber (
174	IceListenObj listenObj
175)
176{
177    return (_IceTransGetConnectionNumber (listenObj->trans_conn));
178}
179
180
181
182char *
183IceGetListenConnectionString (
184	IceListenObj listenObj
185)
186{
187    return strdup(listenObj->network_id);
188}
189
190
191
192char *
193IceComposeNetworkIdList (
194	int		count,
195	IceListenObj	*listenObjs
196)
197{
198    char *list;
199    int len = 0;
200    int i;
201
202    if (count < 1 || listenObjs == NULL)
203	return (NULL);
204
205    for (i = 0; i < count; i++)
206	len += (strlen (listenObjs[i]->network_id) + 1);
207
208    list = malloc (len);
209
210    if (list == NULL)
211	return (NULL);
212    else
213    {
214	int doneCount = 0;
215
216	list[0] = '\0';
217
218	for (i = 0; i < count; i++)
219	{
220	    if (_IceTransIsLocal (listenObjs[i]->trans_conn))
221	    {
222		strcat (list, listenObjs[i]->network_id);
223		doneCount++;
224		if (doneCount < count)
225		    strcat (list, ",");
226	    }
227	}
228
229	if (doneCount < count)
230	{
231	    for (i = 0; i < count; i++)
232	    {
233		if (!_IceTransIsLocal (listenObjs[i]->trans_conn))
234		{
235		    strcat (list, listenObjs[i]->network_id);
236		    doneCount++;
237		    if (doneCount < count)
238			strcat (list, ",");
239		}
240	    }
241	}
242
243	return (list);
244    }
245}
246
247
248
249void
250IceFreeListenObjs (
251	int	     count,
252	IceListenObj *listenObjs
253)
254{
255    int i;
256
257    for (i = 0; i < count; i++)
258    {
259	free (listenObjs[i]->network_id);
260	_IceTransClose (listenObjs[i]->trans_conn);
261	free (listenObjs[i]);
262    }
263
264    free (listenObjs);
265}
266
267
268
269/*
270 * Allow host based authentication for the ICE Connection Setup.
271 * Do not confuse with the host based authentication callbacks that
272 * can be set up in IceRegisterForProtocolReply.
273 */
274
275void
276IceSetHostBasedAuthProc (
277	IceListenObj		listenObj,
278	IceHostBasedAuthProc	hostBasedAuthProc
279)
280{
281    listenObj->host_based_auth_proc = hostBasedAuthProc;
282}
283