1 /******************************************************************************
2 
3 
4 Copyright 1993, 1998  The Open Group
5 
6 Permission to use, copy, modify, distribute, and sell this software and its
7 documentation for any purpose is hereby granted without fee, provided that
8 the above copyright notice appear in all copies and that both that
9 copyright notice and this permission notice appear in supporting
10 documentation.
11 
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
14 
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 
22 Except as contained in this notice, the name of The Open Group shall not be
23 used in advertising or otherwise to promote the sale, use or other dealings
24 in this Software without prior written authorization from The Open Group.
25 
26 Author: 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 
38 Status
IceListenForConnections(int * countRet,IceListenObj ** listenObjsRet,int errorLength,char * errorStringRet)39 IceListenForConnections (
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 
172 int
IceGetListenConnectionNumber(IceListenObj listenObj)173 IceGetListenConnectionNumber (
174 	IceListenObj listenObj
175 )
176 {
177     return (_IceTransGetConnectionNumber (listenObj->trans_conn));
178 }
179 
180 
181 
182 char *
IceGetListenConnectionString(IceListenObj listenObj)183 IceGetListenConnectionString (
184 	IceListenObj listenObj
185 )
186 {
187     return strdup(listenObj->network_id);
188 }
189 
190 
191 
192 char *
IceComposeNetworkIdList(int count,IceListenObj * listenObjs)193 IceComposeNetworkIdList (
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 
249 void
IceFreeListenObjs(int count,IceListenObj * listenObjs)250 IceFreeListenObjs (
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 
275 void
IceSetHostBasedAuthProc(IceListenObj listenObj,IceHostBasedAuthProc hostBasedAuthProc)276 IceSetHostBasedAuthProc (
277 	IceListenObj		listenObj,
278 	IceHostBasedAuthProc	hostBasedAuthProc
279 )
280 {
281     listenObj->host_based_auth_proc = hostBasedAuthProc;
282 }
283