22602d4832cc0ed1d8315532b04a4f1b188bff6f
[framework/uifw/xorg/lib/libice.git] / src / listen.c
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 \f
38 Status
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         strncpy (errorStringRet,
60             "Cannot establish any listening sockets", errorLength);
61
62         return (0);
63     }
64
65     if ((listenObjs = (struct _IceListenObj *) malloc (
66         transCount * sizeof (struct _IceListenObj))) == NULL)
67     {
68         for (i = 0; i < transCount; i++)
69             _IceTransClose (transConns[i]);
70         free ((char *) transConns);
71         return (0);
72     }
73
74     *countRet = 0;
75
76     for (i = 0; i < transCount; i++)
77     {
78         _IceTransSetOption(transConns[i], TRANS_CLOSEONEXEC, 1);
79
80         networkId = _IceTransGetMyNetworkId (transConns[i]);
81
82         if (networkId)
83         {
84             listenObjs[*countRet].trans_conn = transConns[i];
85             listenObjs[*countRet].network_id = networkId;
86                 
87             (*countRet)++;
88         }
89     }
90
91     if (*countRet == 0)
92     {
93         *listenObjsRet = NULL;
94
95         strncpy (errorStringRet,
96             "Cannot establish any listening sockets", errorLength);
97
98         status = 0;
99     }
100     else
101     {
102         *listenObjsRet = (IceListenObj *) malloc (
103             *countRet * sizeof (IceListenObj));
104
105         if (*listenObjsRet == NULL)
106         {
107             strncpy (errorStringRet, "Malloc failed", errorLength);
108
109             status = 0;
110         }
111         else
112         {
113             for (i = 0; i < *countRet; i++)
114             {
115                 (*listenObjsRet)[i] = (IceListenObj) malloc (
116                     sizeof (struct _IceListenObj));
117
118                 if ((*listenObjsRet)[i] == NULL)
119                 {
120                     strncpy (errorStringRet, "Malloc failed", errorLength);
121
122                     for (j = 0; j < i; j++)
123                         free ((char *) (*listenObjsRet)[j]);
124
125                     free ((char *) *listenObjsRet);
126                     *listenObjsRet = NULL;
127
128                     status = 0;
129                     break;
130                 }
131                 else
132                 {
133                     *((*listenObjsRet)[i]) = listenObjs[i];
134                 }
135             }
136         }
137     }
138
139     if (status == 1)
140     {
141         if (errorStringRet && errorLength > 0)
142             *errorStringRet = '\0';
143         
144         for (i = 0; i < *countRet; i++)
145         {
146             (*listenObjsRet)[i]->host_based_auth_proc = NULL;
147         }
148     }
149     else
150     {
151         for (i = 0; i < transCount; i++)
152             _IceTransClose (transConns[i]);
153     }
154
155     free ((char *) listenObjs);
156     free ((char *) transConns);
157
158     return (status);
159 }
160
161
162 \f
163 int
164 IceGetListenConnectionNumber (
165         IceListenObj listenObj
166 )
167 {
168     return (_IceTransGetConnectionNumber (listenObj->trans_conn));
169 }
170
171
172 \f
173 char *
174 IceGetListenConnectionString (
175         IceListenObj listenObj
176 )
177 {
178     return strdup(listenObj->network_id);
179 }
180
181
182 \f
183 char *
184 IceComposeNetworkIdList (
185         int             count,
186         IceListenObj    *listenObjs
187 )
188 {
189     char *list;
190     int len = 0;
191     int i;
192
193     if (count < 1 || listenObjs == NULL)
194         return (NULL);
195
196     for (i = 0; i < count; i++)
197         len += (strlen (listenObjs[i]->network_id) + 1);
198
199     list = (char *) malloc (len);
200
201     if (list == NULL)
202         return (NULL);
203     else
204     {
205         int doneCount = 0;
206
207         list[0] = '\0';
208
209         for (i = 0; i < count; i++)
210         {
211             if (_IceTransIsLocal (listenObjs[i]->trans_conn))
212             {
213                 strcat (list, listenObjs[i]->network_id);
214                 doneCount++;
215                 if (doneCount < count)
216                     strcat (list, ",");
217             }
218         }
219
220         if (doneCount < count)
221         {
222             for (i = 0; i < count; i++)
223             {
224                 if (!_IceTransIsLocal (listenObjs[i]->trans_conn))
225                 {
226                     strcat (list, listenObjs[i]->network_id);
227                     doneCount++;
228                     if (doneCount < count)
229                         strcat (list, ",");
230                 }
231             }
232         }
233
234         return (list);
235     }
236 }
237
238
239 \f
240 void
241 IceFreeListenObjs (
242         int          count,
243         IceListenObj *listenObjs
244 )
245 {
246     int i;
247
248     for (i = 0; i < count; i++)
249     {
250         free (listenObjs[i]->network_id);
251         _IceTransClose (listenObjs[i]->trans_conn);
252         free ((char *) listenObjs[i]);
253     }
254
255     free ((char *) listenObjs);
256 }
257
258
259 \f
260 /*
261  * Allow host based authentication for the ICE Connection Setup.
262  * Do not confuse with the host based authentication callbacks that
263  * can be set up in IceRegisterForProtocolReply.
264  */
265
266 void
267 IceSetHostBasedAuthProc (
268         IceListenObj            listenObj,
269         IceHostBasedAuthProc    hostBasedAuthProc
270 )
271 {
272     listenObj->host_based_auth_proc = hostBasedAuthProc;
273 }