1 /* $XConsortium: Xtransutil.c /main/32 1996/12/04 10:22:57 lehors $ */
2 /* $XFree86: xc/lib/xtrans/Xtransutil.c,v 3.9 1996/12/23 06:04:18 dawes Exp $ */
3 /*
4 
5 Copyright (c) 1993, 1994  X Consortium
6 
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
14 
15 The above copyright notice and this permission notice shall be included
16 in all copies or substantial portions of the Software.
17 
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 OTHER DEALINGS IN THE SOFTWARE.
25 
26 Except as contained in this notice, the name of the X Consortium shall
27 not be used in advertising or otherwise to promote the sale, use or
28 other dealings in this Software without prior written authorization
29 from the X Consortium.
30 
31 */
32 
33 /* Copyright (c) 1993, 1994 NCR Corporation - Dayton, Ohio, USA
34  *
35  * All Rights Reserved
36  *
37  * Permission to use, copy, modify, and distribute this software and its
38  * documentation for any purpose and without fee is hereby granted, provided
39  * that the above copyright notice appear in all copies and that both that
40  * copyright notice and this permission notice appear in supporting
41  * documentation, and that the name NCR not be used in advertising
42  * or publicity pertaining to distribution of the software without specific,
43  * written prior permission.  NCR makes no representations about the
44  * suitability of this software for any purpose.  It is provided "as is"
45  * without express or implied warranty.
46  *
47  * NCRS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
48  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
49  * NO EVENT SHALL NCR BE LIABLE FOR ANY SPECIAL, INDIRECT OR
50  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
51  * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
52  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
53  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
54  */
55 
56 /*
57  * These are some utility functions created for convenience or to provide
58  * an interface that is similar to an existing interface. These are built
59  * only using the Transport Independant API, and have no knowledge of
60  * the internal implementation.
61  */
62 
63 #ifdef XTHREADS
64 #include <X11/Xthreads.h>
65 #endif
66 
67 #ifdef X11_t
68 
69 /*
70  * These values come from X.h and Xauth.h, and MUST match them. Some
71  * of these values are also defined by the ChangeHost protocol message.
72  */
73 
74 #define FamilyInternet		0
75 #define FamilyDECnet		1
76 #define FamilyChaos		2
77 #define FamilyAmoeba		33
78 #define FamilyLocalHost		252
79 #define FamilyKrb5Principal	253
80 #define FamilyNetname		254
81 #define FamilyLocal		256
82 #define FamilyWild		65535
83 
84 /*
85  * TRANS(ConvertAddress) converts a sockaddr based address to an
86  * X authorization based address. Some of this is defined as part of
87  * the ChangeHost protocol. The rest is just doen in a consistent manner.
88  */
89 
90 int
91 TRANS(ConvertAddress)(familyp,addrlenp,addrp)
92 int	*familyp;
93 int	*addrlenp;
94 Xtransaddr	**addrp;
95 {
96 
97     PRMSG(2,"ConvertAddress(%d,%d,%x)\n",*familyp,*addrlenp,*addrp);
98 
99     switch( *familyp )
100     {
101 #if defined(TCPCONN) || defined(STREAMSCONN) || defined(MNX_TCPCONN)
102     case AF_INET:
103     {
104 	/*
105 	 * Check for the BSD hack localhost address 127.0.0.1.
106 	 * In this case, we are really FamilyLocal.
107 	 */
108 
109 	struct sockaddr_in saddr;
110 #ifdef CRAY
111 #ifdef OLDTCP
112 	int len = sizeof(saddr.sin_addr);
113 #else
114 	int len = SIZEOF_in_addr;
115 #endif /* OLDTCP */
116 	char *cp = (char *) &saddr.sin_addr;
117 #else /* else not CRAY */
118 	int len = sizeof(saddr.sin_addr.s_addr);
119 	char *cp = (char *) &saddr.sin_addr.s_addr;
120 #endif /* CRAY */
121 
122 	memcpy (&saddr, *addrp, sizeof (struct sockaddr_in));
123 
124 	if ((len == 4) && (cp[0] == 127) && (cp[1] == 0) &&
125 	    (cp[2] == 0) && (cp[3] == 1))
126 	{
127 	    *familyp=FamilyLocal;
128 	}
129 	else
130 	{
131 	    *familyp=FamilyInternet;
132 	    *addrlenp=len;
133 	    memcpy(*addrp,&saddr.sin_addr,len);
134 	}
135 	break;
136     }
137 #endif /* defined(TCPCONN) || defined(STREAMSCONN) || MNX_TCPCONN */
138 
139 #if defined(DNETCONN)
140     case AF_DECnet:
141     {
142 	struct sockaddr_dn saddr;
143 
144 	memcpy (&saddr, *addrp, sizeof (struct sockaddr_dn));
145 
146 	*familyp=FamilyDECnet;
147 	*addrlenp=sizeof(struct dn_naddr);
148 	memcpy(*addrp,&saddr.sdn_add,*addrlenp);
149 
150 	break;
151     }
152 #endif /* defined(DNETCONN) */
153 
154 #if defined(UNIXCONN) || defined(LOCALCONN) || defined(OS2PIPECONN)
155     case AF_UNIX:
156     {
157 	*familyp=FamilyLocal;
158 	break;
159     }
160 #endif /* defined(UNIXCONN) || defined(LOCALCONN) || defined(OS2PIPECONN)*/
161 
162 #if defined(AMRPCCONN)
163     case AF_AMOEBA:
164     {
165 	*familyp=FamilyAmoeba;
166 	break;
167     }
168 #endif
169 #if defined(AMTCPCONN) && !(defined(TCPCONN) || defined(STREAMSCONN))
170     case AF_INET:
171     {
172 	*familyp=FamilyInternet;
173 	break;
174     }
175 #endif
176 
177     default:
178 	PRMSG(1,"ConvertAddress: Unknown family type %d\n",
179 	      *familyp, 0,0 );
180 	return -1;
181     }
182 
183 
184     if (*familyp == FamilyLocal)
185     {
186 	/*
187 	 * In the case of a local connection, we need to get the
188 	 * host name for authentication.
189 	 */
190 
191 	char hostnamebuf[256];
192 	int len = TRANS(GetHostname) (hostnamebuf, sizeof hostnamebuf);
193 
194 	if (len > 0) {
195 	    if (*addrp && *addrlenp < (len + 1))
196 	    {
197 		xfree ((char *) *addrp);
198 		*addrp = NULL;
199 	    }
200 	    if (!*addrp)
201 		*addrp = (Xtransaddr *) xalloc (len + 1);
202 	    if (*addrp) {
203 		strcpy ((char *) *addrp, hostnamebuf);
204 		*addrlenp = len;
205 	    } else {
206 		*addrlenp = 0;
207 	    }
208 	}
209 	else
210 	{
211 	    if (*addrp)
212 		xfree ((char *) *addrp);
213 	    *addrp = NULL;
214 	    *addrlenp = 0;
215 	}
216     }
217 
218     return 0;
219 }
220 
221 #endif /* X11_t */
222 
223 #ifdef ICE_t
224 
225 #include <signal.h>
226 
227 char *
228 TRANS(GetMyNetworkId) (ciptr)
229 
230 XtransConnInfo  ciptr;
231 
232 {
233     int		family = ciptr->family;
234     int		addrlen = ciptr->addrlen;
235     char 	*addr = ciptr->addr;
236     char	hostnamebuf[256];
237     char 	*networkId = NULL;
238     char	*transName = ciptr->transptr->TransName;
239 
240     if (gethostname (hostnamebuf, sizeof (hostnamebuf)) < 0)
241     {
242 	return (NULL);
243     }
244 
245     switch (family)
246     {
247 #if defined(UNIXCONN) || defined(STREAMSCONN) || defined(LOCALCONN) || defined(OS2PIPECONN)
248     case AF_UNIX:
249     {
250 	struct sockaddr_un *saddr = (struct sockaddr_un *) addr;
251 	networkId = (char *) xalloc (3 + strlen (transName) +
252 	    strlen (hostnamebuf) + strlen (saddr->sun_path));
253 	sprintf (networkId, "%s/%s:%s", transName,
254 	    hostnamebuf, saddr->sun_path);
255 	break;
256     }
257 #endif /* defined(UNIXCONN) || defined(STREAMSCONN) || defined(LOCALCONN) || defined(OS2PIPECONN)
258 */
259 
260 #if defined(TCPCONN) || defined(STREAMSCONN) || defined(MNX_TCPCONN)
261     case AF_INET:
262     {
263 	struct sockaddr_in *saddr = (struct sockaddr_in *) addr;
264 	char portnumbuf[10];
265 
266 	sprintf (portnumbuf, "%d", ntohs (saddr->sin_port));
267 	networkId = (char *) xalloc (3 + strlen (transName) +
268 	    strlen (hostnamebuf) + strlen (portnumbuf));
269 	sprintf (networkId, "%s/%s:%s", transName, hostnamebuf, portnumbuf);
270 	break;
271     }
272 #endif /* defined(TCPCONN) || defined(STREAMSCONN) || MNX_TCPCONN */
273 
274 #if defined(DNETCONN)
275     case AF_DECnet:
276     {
277 	struct sockaddr_dn *saddr = (struct sockaddr_dn *) addr;
278 
279 	networkId = (char *) xalloc (
280 	    13 + strlen (hostnamebuf) + saddr->sdn_objnamel);
281 	sprintf (networkId, "dnet/%s::%s",
282 	    hostnamebuf, saddr->sdn_objname);
283 	break;
284     }
285 #endif /* defined(DNETCONN) */
286 
287     default:
288 	break;
289     }
290 
291     return (networkId);
292 }
293 
294 #include <setjmp.h>
295 static jmp_buf env;
296 
297 #ifdef SIGALRM
298 static int nameserver_timedout = 0;
299 
300 static
301 #ifdef SIGNALRETURNSINT
302 int
303 #else
304 void
305 #endif
nameserver_lost(sig)306 nameserver_lost(sig)
307 {
308   nameserver_timedout = 1;
309   longjmp (env, -1);
310   /* NOTREACHED */
311 #ifdef SIGNALRETURNSINT
312   return -1;				/* for picky compilers */
313 #endif
314 }
315 #endif /* SIGALARM */
316 
317 
318 char *
319 TRANS(GetPeerNetworkId) (ciptr)
320 
321 XtransConnInfo  ciptr;
322 
323 {
324     int		family = ciptr->family;
325     int		peer_addrlen = ciptr->peeraddrlen;
326     char	*peer_addr = ciptr->peeraddr;
327     char	*hostname;
328     char	*networkId = NULL;
329     char	addrbuf[256];
330     char	*addr = NULL;
331 
332     switch (family)
333     {
334     case AF_UNSPEC:
335 #if defined(UNIXCONN) || defined(STREAMSCONN) || defined(LOCALCONN) || defined(OS2PIPECONN)
336     case AF_UNIX:
337     {
338 	if (gethostname (addrbuf, sizeof (addrbuf)) == 0)
339 	    addr = addrbuf;
340 	break;
341     }
342 #endif /* defined(UNIXCONN) || defined(STREAMSCONN) || defined(LOCALCONN) || defined(OS2PIPECONN)
343 */
344 
345 #if defined(TCPCONN) || defined(STREAMSCONN) || defined(MNX_TCPCONN)
346     case AF_INET:
347     {
348 	struct sockaddr_in *saddr = (struct sockaddr_in *) peer_addr;
349 	_Xgethostbynameparams hparams;
350 	struct hostent * hostp;
351 
352 #ifndef WIN32
353  	char *inet_ntoa();
354 #endif
355 
356 #ifdef SIGALRM
357 	/*
358 	 * gethostbyaddr can take a LONG time if the host does not exist.
359 	 * Assume that if it does not respond in NAMESERVER_TIMEOUT seconds
360 	 * that something is wrong and do not make the user wait.
361 	 * gethostbyaddr will continue after a signal, so we have to
362 	 * jump out of it.
363 	 */
364 
365 	nameserver_timedout = 0;
366 	signal (SIGALRM, nameserver_lost);
367 	alarm (4);
368 	if (setjmp(env) == 0) {
369 #endif
370 	    hostp = _XGethostbyaddr ((char *) &saddr->sin_addr,
371 		sizeof (saddr->sin_addr), AF_INET, hparams);
372 #ifdef SIGALRM
373 	}
374 	alarm (0);
375 #endif
376 	if (hostp != NULL)
377 	  addr = hostp->h_name;
378 	else
379 	  addr = inet_ntoa (saddr->sin_addr);
380 	break;
381     }
382 
383 #endif /* defined(TCPCONN) || defined(STREAMSCONN) || MNX_TCPCONN */
384 
385 #if defined(DNETCONN)
386     case AF_DECnet:
387     {
388 	struct sockaddr_dn *saddr = (struct sockaddr_dn *) peer_addr;
389 	struct nodeent *np;
390 
391 	if (np = getnodebyaddr(saddr->sdn_add.a_addr,
392 	    saddr->sdn_add.a_len, AF_DECnet)) {
393 	    sprintf(addrbuf, "%s:", np->n_name);
394 	} else {
395 	    sprintf(addrbuf, "%s:", dnet_htoa(&saddr->sdn_add));
396 	}
397 	addr = addrbuf;
398 	break;
399     }
400 #endif /* defined(DNETCONN) */
401 
402 #if defined(AMRPCCONN)
403     case AF_AMOEBA:
404     {
405 	addr = "Amoeba"; /* not really used */
406 	break;
407     }
408 #endif
409 #if defined(AMTCPCONN) && !(defined(TCPCONN) || defined(STREAMSCONN))
410     case AF_INET:
411     {
412 	if (gethostname (addrbuf, sizeof (addrbuf)) == 0) {
413 	    addr = addrbuf;
414 	} else {
415 	    addr = "";
416 	}
417 	break;
418     }
419 #endif
420 
421     default:
422 	return (NULL);
423     }
424 
425 
426     hostname = (char *) xalloc (
427 	strlen (ciptr->transptr->TransName) + strlen (addr) + 2);
428     strcpy (hostname, ciptr->transptr->TransName);
429     strcat (hostname, "/");
430     if (addr)
431 	strcat (hostname, addr);
432 
433     return (hostname);
434 }
435 
436 #endif /* ICE_t */
437 
438 
439 #if defined(WIN32) && (defined(TCPCONN) || defined(DNETCONN))
440 int
TRANS(WSAStartup)441 TRANS(WSAStartup) ()
442 {
443     static WSADATA wsadata;
444 
445     PRMSG (2,"WSAStartup()\n", 0, 0, 0);
446 
447     if (!wsadata.wVersion && WSAStartup(MAKEWORD(1,1), &wsadata))
448         return 1;
449     return 0;
450 }
451 #endif
452 
453 
454 static int
is_numeric(str)455 is_numeric (str)
456 
457 char *str;
458 
459 {
460     int i;
461 
462     for (i = 0; i < (int) strlen (str); i++)
463 	if (!isdigit (str[i]))
464 	    return (0);
465 
466     return (1);
467 }
468