xhost.c revision 169a0819
1169a0819Smrg/*
2169a0819Smrg * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
3169a0819Smrg *
4169a0819Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5169a0819Smrg * copy of this software and associated documentation files (the "Software"),
6169a0819Smrg * to deal in the Software without restriction, including without limitation
7169a0819Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8169a0819Smrg * and/or sell copies of the Software, and to permit persons to whom the
9169a0819Smrg * Software is furnished to do so, subject to the following conditions:
10169a0819Smrg *
11169a0819Smrg * The above copyright notice and this permission notice (including the next
12169a0819Smrg * paragraph) shall be included in all copies or substantial portions of the
13169a0819Smrg * Software.
14169a0819Smrg *
15169a0819Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16169a0819Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17169a0819Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18169a0819Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19169a0819Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20169a0819Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21169a0819Smrg * DEALINGS IN THE SOFTWARE.
22169a0819Smrg */
2364ce7165Smrg/*
2464ce7165Smrg
2564ce7165SmrgCopyright 1985, 1986, 1987, 1998  The Open Group
2664ce7165Smrg
2764ce7165SmrgAll rights reserved.
2864ce7165Smrg
2964ce7165SmrgPermission is hereby granted, free of charge, to any person obtaining a
3064ce7165Smrgcopy of this software and associated documentation files (the
3164ce7165Smrg"Software"), to deal in the Software without restriction, including
3264ce7165Smrgwithout limitation the rights to use, copy, modify, merge, publish,
3364ce7165Smrgdistribute, and/or sell copies of the Software, and to permit persons
3464ce7165Smrgto whom the Software is furnished to do so, provided that the above
3564ce7165Smrgcopyright notice(s) and this permission notice appear in all copies of
3664ce7165Smrgthe Software and that both the above copyright notice(s) and this
3764ce7165Smrgpermission notice appear in supporting documentation.
3864ce7165Smrg
3964ce7165SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
4064ce7165SmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
4164ce7165SmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
4264ce7165SmrgOF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
4364ce7165SmrgHOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
4464ce7165SmrgINDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
4564ce7165SmrgFROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
4664ce7165SmrgNEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
4764ce7165SmrgWITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
4864ce7165Smrg
4964ce7165SmrgExcept as contained in this notice, the name of a copyright holder
5064ce7165Smrgshall not be used in advertising or otherwise to promote the sale, use
5164ce7165Smrgor other dealings in this Software without prior written authorization
5264ce7165Smrgof the copyright holder.
5364ce7165Smrg
5464ce7165SmrgX Window System is a trademark of The Open Group.
5564ce7165Smrg
5664ce7165Smrg*/
5764ce7165Smrg
5864ce7165Smrg#ifdef HAVE_CONFIG_H
5964ce7165Smrg#include "config.h"
6064ce7165Smrg#endif
6164ce7165Smrg
6264ce7165Smrg#if defined(TCPCONN) || defined(STREAMSCONN)
6364ce7165Smrg#define NEEDSOCKETS
6464ce7165Smrg#endif
6564ce7165Smrg#ifdef UNIXCONN
6664ce7165Smrg#define NEEDSOCKETS
6764ce7165Smrg#endif
6864ce7165Smrg#ifdef DNETCONN
6964ce7165Smrg#define NEEDSOCKETS
7064ce7165Smrg#endif
7164ce7165Smrg
7264ce7165Smrg#include <X11/Xlib.h>
7364ce7165Smrg#include <X11/Xos.h>
7464ce7165Smrg#include <X11/Xproto.h>
7564ce7165Smrg#include <X11/Xfuncs.h>
7664ce7165Smrg#include <stdio.h>
7764ce7165Smrg#include <stdlib.h>
7864ce7165Smrg#include <signal.h>
7964ce7165Smrg#ifdef X_NOT_POSIX
8064ce7165Smrg#include <setjmp.h>
8164ce7165Smrg#endif
8264ce7165Smrg#include <ctype.h>
8364ce7165Smrg#include <X11/Xauth.h>
8464ce7165Smrg#include <X11/Xmu/Error.h>
8564ce7165Smrg#include <stdlib.h>
8664ce7165Smrg
8764ce7165Smrg#ifdef NEEDSOCKETS
8864ce7165Smrg#ifdef att
8964ce7165Smrgtypedef unsigned short unsign16;
9064ce7165Smrgtypedef unsigned long unsign32;
9164ce7165Smrgtypedef short sign16;
9264ce7165Smrgtypedef long sign32;
9364ce7165Smrg#include <interlan/socket.h>
9464ce7165Smrg#include <interlan/netdb.h>
9564ce7165Smrg#include <interlan/in.h>
9664ce7165Smrg#else
9764ce7165Smrg#ifndef Lynx
9864ce7165Smrg#include <sys/socket.h>
9964ce7165Smrg#else
10064ce7165Smrg#include <socket.h>
10164ce7165Smrg#endif
10264ce7165Smrg#include <netdb.h>
10364ce7165Smrg#include <netinet/in.h>
10464ce7165Smrg#endif
10564ce7165Smrg#endif /* NEEDSOCKETS */
10664ce7165Smrg
10764ce7165Smrg#ifndef BAD_ARPAINET
10864ce7165Smrg#include <arpa/inet.h>
10964ce7165Smrg#else
11064ce7165Smrg/* bogus definition of inet_makeaddr() in BSD 4.2 and Ultrix */
11164ce7165Smrgextern unsigned long inet_makeaddr();
11264ce7165Smrg#endif
11364ce7165Smrg
11464ce7165Smrg#ifdef DNETCONN
11564ce7165Smrg#include <netdnet/dn.h>
11664ce7165Smrg#include <netdnet/dnetdb.h>
11764ce7165Smrg#endif
11864ce7165Smrg
11964ce7165Smrg#ifdef SECURE_RPC
12064ce7165Smrg#include <pwd.h>
12164ce7165Smrg#include <rpc/rpc.h>
12264ce7165Smrg#ifdef X_POSIX_C_SOURCE
12364ce7165Smrg#define _POSIX_C_SOURCE X_POSIX_C_SOURCE
12464ce7165Smrg#include <limits.h>
12564ce7165Smrg#undef _POSIX_C_SOURCE
12664ce7165Smrg#else
12764ce7165Smrg#if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE)
12864ce7165Smrg#include <limits.h>
12964ce7165Smrg#else
13064ce7165Smrg#define _POSIX_SOURCE
13164ce7165Smrg#include <limits.h>
13264ce7165Smrg#undef _POSIX_SOURCE
13364ce7165Smrg#endif
13464ce7165Smrg#endif
13564ce7165Smrg#ifndef NGROUPS_MAX
13664ce7165Smrg#include <sys/param.h>
13764ce7165Smrg#define NGROUPS_MAX NGROUPS
13864ce7165Smrg#endif
13964ce7165Smrg#ifdef sun
14064ce7165Smrg/* Go figure, there's no getdomainname() prototype available */
14164ce7165Smrgextern int getdomainname(char *name, size_t len);
14264ce7165Smrg#endif
14364ce7165Smrg#endif
14464ce7165Smrg
14564ce7165Smrgstatic int change_host(Display *dpy, char *name, Bool add);
14664ce7165Smrgstatic char *get_hostname(XHostAddress *ha);
14764ce7165Smrgstatic int local_xerror(Display *dpy, XErrorEvent *rep);
14864ce7165Smrg
14964ce7165Smrg#ifdef RETSIGTYPE /* autoconf AC_TYPE_SIGNAL */
15064ce7165Smrg# define signal_t RETSIGTYPE
15164ce7165Smrg#else /* Imake */
15264ce7165Smrg#ifdef SIGNALRETURNSINT
15364ce7165Smrg#define signal_t int
15464ce7165Smrg#else
15564ce7165Smrg#define signal_t void
15664ce7165Smrg#endif
15764ce7165Smrg#endif /* RETSIGTYPE */
15864ce7165Smrgstatic signal_t nameserver_lost(int sig);
15964ce7165Smrg
16064ce7165Smrg#define NAMESERVER_TIMEOUT 5	/* time to wait for nameserver */
16164ce7165Smrg
162fb23d3a8Smrgstatic volatile int nameserver_timedout;
163fb23d3a8Smrg
164fb23d3a8Smrgstatic char *ProgramName;
16564ce7165Smrg
16664ce7165Smrg#ifdef NEEDSOCKETS
16764ce7165Smrgstatic int
16864ce7165SmrgXFamily(int af)
16964ce7165Smrg{
17064ce7165Smrg    int i;
17164ce7165Smrg    static struct _familyMap {
17264ce7165Smrg	int af, xf;
17364ce7165Smrg    } familyMap[] = {
17464ce7165Smrg#ifdef	AF_DECnet
17564ce7165Smrg        { AF_DECnet, FamilyDECnet },
17664ce7165Smrg#endif
17764ce7165Smrg#ifdef	AF_CHAOS
17864ce7165Smrg        { AF_CHAOS, FamilyChaos },
17964ce7165Smrg#endif
18064ce7165Smrg#ifdef	AF_INET
18164ce7165Smrg        { AF_INET, FamilyInternet },
18264ce7165Smrg#if defined(IPv6) && defined(AF_INET6)
18364ce7165Smrg        { AF_INET6, FamilyInternet6 },
18464ce7165Smrg#endif
18564ce7165Smrg#endif
18664ce7165Smrg};
18764ce7165Smrg
18864ce7165Smrg#define FAMILIES ((sizeof familyMap)/(sizeof familyMap[0]))
18964ce7165Smrg
19064ce7165Smrg    for (i = 0; i < FAMILIES; i++)
19164ce7165Smrg	if (familyMap[i].af == af) return familyMap[i].xf;
19264ce7165Smrg    return -1;
19364ce7165Smrg}
19464ce7165Smrg#endif /* NEEDSOCKETS */
19564ce7165Smrg
196fb23d3a8Smrgstatic Display *dpy;
19764ce7165Smrg
19864ce7165Smrgint
19964ce7165Smrgmain(int argc, char *argv[])
20064ce7165Smrg{
20164ce7165Smrg    register char *arg;
20264ce7165Smrg    int i, nhosts = 0;
20364ce7165Smrg    char *hostname;
20464ce7165Smrg    int nfailed = 0;
20564ce7165Smrg    XHostAddress *list;
20664ce7165Smrg    Bool enabled = False;
20764ce7165Smrg#ifdef DNETCONN
20864ce7165Smrg    char *dnet_htoa();
20964ce7165Smrg    struct nodeent *np;
21064ce7165Smrg    struct dn_naddr *nlist, dnaddr, *dnaddrp, *dnet_addr();
21164ce7165Smrg    char *cp;
21264ce7165Smrg#endif
21364ce7165Smrg
21464ce7165Smrg    ProgramName = argv[0];
21564ce7165Smrg
21664ce7165Smrg    if ((dpy = XOpenDisplay(NULL)) == NULL) {
21764ce7165Smrg	fprintf(stderr, "%s:  unable to open display \"%s\"\n",
21864ce7165Smrg		ProgramName, XDisplayName (NULL));
21964ce7165Smrg	exit(1);
22064ce7165Smrg    }
22164ce7165Smrg
22264ce7165Smrg    XSetErrorHandler(local_xerror);
22364ce7165Smrg
22464ce7165Smrg
22564ce7165Smrg    if (argc == 1) {
22664ce7165Smrg#ifdef DNETCONN
22764ce7165Smrg	setnodeent(1);		/* keep the database accessed */
22864ce7165Smrg#endif
22964ce7165Smrg	sethostent(1);		/* don't close the data base each time */
23064ce7165Smrg	list = XListHosts(dpy, &nhosts, &enabled);
23164ce7165Smrg	if (enabled)
23264ce7165Smrg	    printf ("access control enabled, only authorized clients can connect\n");
23364ce7165Smrg	else
23464ce7165Smrg	    printf ("access control disabled, clients can connect from any host\n");
23564ce7165Smrg
23664ce7165Smrg	if (nhosts != 0) {
23764ce7165Smrg	    for (i = 0; i < nhosts; i++ )  {
23864ce7165Smrg		hostname = get_hostname(&list[i]);
23964ce7165Smrg		if (hostname) {
24064ce7165Smrg		    switch (list[i].family) {
24164ce7165Smrg		    case FamilyInternet:
24264ce7165Smrg			printf("INET:");
24364ce7165Smrg			break;
24464ce7165Smrg		    case FamilyInternet6:
24564ce7165Smrg			printf("INET6:");
24664ce7165Smrg			break;
24764ce7165Smrg		    case FamilyDECnet:
24864ce7165Smrg			printf("DNET:");
24964ce7165Smrg			break;
25064ce7165Smrg		    case FamilyNetname:
25164ce7165Smrg			printf("NIS:");
25264ce7165Smrg			break;
25364ce7165Smrg		    case FamilyKrb5Principal:
25464ce7165Smrg			printf("KRB:");
25564ce7165Smrg			break;
25664ce7165Smrg		    case FamilyLocalHost:
25764ce7165Smrg			printf("LOCAL:");
25864ce7165Smrg			break;
25964ce7165Smrg		    case FamilyServerInterpreted:
26064ce7165Smrg			printf("SI:");
26164ce7165Smrg			break;
26264ce7165Smrg		    default:
26364ce7165Smrg			printf("<unknown family type %d>:", list[i].family);
26464ce7165Smrg			break;
26564ce7165Smrg		    }
26664ce7165Smrg		    printf ("%s", hostname);
26764ce7165Smrg		} else {
26864ce7165Smrg		    printf ("<unknown address in family %d>",
26964ce7165Smrg			    list[i].family);
27064ce7165Smrg		}
27164ce7165Smrg		if (nameserver_timedout) {
27264ce7165Smrg		    printf("\t(no nameserver response within %d seconds)\n",
27364ce7165Smrg			   NAMESERVER_TIMEOUT);
27464ce7165Smrg		    nameserver_timedout = 0;
27564ce7165Smrg		} else
27664ce7165Smrg		    printf("\n");
27764ce7165Smrg	    }
27864ce7165Smrg	    free(list);
27964ce7165Smrg	    endhostent();
28064ce7165Smrg	}
28164ce7165Smrg	exit(0);
28264ce7165Smrg    }
28364ce7165Smrg
28464ce7165Smrg    if (argc == 2 && !strcmp(argv[1], "-help")) {
28564ce7165Smrg	fprintf(stderr, "usage: %s [[+-]hostname ...]\n", argv[0]);
28664ce7165Smrg	exit(1);
28764ce7165Smrg    }
28864ce7165Smrg
28964ce7165Smrg    for (i = 1; i < argc; i++) {
29064ce7165Smrg	arg = argv[i];
29164ce7165Smrg	if (*arg == '-') {
29264ce7165Smrg
29364ce7165Smrg	    if (!argv[i][1] && ((i+1) == argc)) {
29464ce7165Smrg		printf ("access control enabled, only authorized clients can connect\n");
29564ce7165Smrg		XEnableAccessControl(dpy);
29664ce7165Smrg	    } else {
29764ce7165Smrg		arg = argv[i][1]? &argv[i][1] : argv[++i];
29864ce7165Smrg		if (!change_host (dpy, arg, False)) {
29964ce7165Smrg		    fprintf (stderr, "%s:  bad hostname \"%s\"\n",
30064ce7165Smrg			     ProgramName, arg);
30164ce7165Smrg		    nfailed++;
30264ce7165Smrg		}
30364ce7165Smrg	    }
30464ce7165Smrg	} else {
30564ce7165Smrg	    if (*arg == '+' && !argv[i][1] && ((i+1) == argc)) {
30664ce7165Smrg		printf ("access control disabled, clients can connect from any host\n");
30764ce7165Smrg		XDisableAccessControl(dpy);
30864ce7165Smrg	    } else {
30964ce7165Smrg		if (*arg == '+') {
31064ce7165Smrg		    arg = argv[i][1]? &argv[i][1] : argv[++i];
31164ce7165Smrg		}
31264ce7165Smrg		if (!change_host (dpy, arg, True)) {
31364ce7165Smrg		    fprintf (stderr, "%s:  bad hostname \"%s\"\n",
31464ce7165Smrg			     ProgramName, arg);
31564ce7165Smrg		    nfailed++;
31664ce7165Smrg		}
31764ce7165Smrg	    }
31864ce7165Smrg	}
31964ce7165Smrg    }
32064ce7165Smrg    XCloseDisplay (dpy);	/* does an XSync first */
32164ce7165Smrg    exit(nfailed);
32264ce7165Smrg}
32364ce7165Smrg
32464ce7165Smrg
32564ce7165Smrg
32664ce7165Smrg/*
32764ce7165Smrg * change_host - edit the list of hosts that may connect to the server;
32864ce7165Smrg * it parses DECnet names (expo::), Internet addresses (18.30.0.212), or
32964ce7165Smrg * Internet names (expo.lcs.mit.edu); if 4.3bsd macro h_addr is defined
33064ce7165Smrg * (from <netdb.h>), it will add or remove all addresses with the given
33164ce7165Smrg * address.
33264ce7165Smrg */
33364ce7165Smrg
33464ce7165Smrgstatic int
33564ce7165Smrgchange_host(Display *dpy, char *name, Bool add)
33664ce7165Smrg{
33764ce7165Smrg    XHostAddress ha;
33864ce7165Smrg    char *lname;
33964ce7165Smrg    int namelen, i, family = FamilyWild;
34064ce7165Smrg#ifdef K5AUTH
34164ce7165Smrg    krb5_principal princ;
34264ce7165Smrg    krb5_data kbuf;
34364ce7165Smrg#endif
34464ce7165Smrg#ifdef NEEDSOCKETS
34564ce7165Smrg    static struct in_addr addr;	/* so we can point at it */
34664ce7165Smrg#if defined(IPv6) && defined(AF_INET6)
34764ce7165Smrg    static struct in6_addr addr6; /* so we can point at it */
34864ce7165Smrg#else
34964ce7165Smrg    struct hostent *hp;
35064ce7165Smrg#endif
35164ce7165Smrg#endif
35264ce7165Smrg    char *cp;
35364ce7165Smrg#ifdef DNETCONN
35464ce7165Smrg    struct dn_naddr *dnaddrp;
35564ce7165Smrg    struct nodeent *np;
35664ce7165Smrg    static struct dn_naddr dnaddr;
35764ce7165Smrg#endif				/* DNETCONN */
35864ce7165Smrg    static char *add_msg = "being added to access control list";
35964ce7165Smrg    static char *remove_msg = "being removed from access control list";
36064ce7165Smrg
36164ce7165Smrg    namelen = strlen(name);
36264ce7165Smrg    if ((lname = (char *)malloc(namelen+1)) == NULL) {
36364ce7165Smrg	fprintf (stderr, "%s: malloc bombed in change_host\n", ProgramName);
36464ce7165Smrg	exit (1);
36564ce7165Smrg    }
36664ce7165Smrg    for (i = 0; i < namelen; i++) {
36764ce7165Smrg	lname[i] = tolower(name[i]);
36864ce7165Smrg    }
36964ce7165Smrg    lname[namelen] = '\0';
37064ce7165Smrg    if (!strncmp("inet:", lname, 5)) {
37164ce7165Smrg#if defined(TCPCONN) || defined(STREAMSCONN)
37264ce7165Smrg	family = FamilyInternet;
37364ce7165Smrg	name += 5;
37464ce7165Smrg#else
37564ce7165Smrg	fprintf (stderr, "%s: not compiled for TCP/IP\n", ProgramName);
37664ce7165Smrg	free(lname);
37764ce7165Smrg	return 0;
37864ce7165Smrg#endif
37964ce7165Smrg    }
38064ce7165Smrg    else if (!strncmp("inet6:", lname, 6)) {
38164ce7165Smrg#if (defined(TCPCONN) || defined(STREAMSCONN)) && \
38264ce7165Smrg    defined(IPv6) && defined(AF_INET6)
38364ce7165Smrg	family = FamilyInternet6;
38464ce7165Smrg	name += 6;
38564ce7165Smrg#else
38664ce7165Smrg	fprintf (stderr, "%s: not compiled for IPv6\n", ProgramName);
38764ce7165Smrg	free(lname);
38864ce7165Smrg	return 0;
38964ce7165Smrg#endif
39064ce7165Smrg    }
39164ce7165Smrg#ifdef ACCEPT_INETV6 /* Allow inetv6 as an alias for inet6 for compatibility
39264ce7165Smrg			with original X11 over IPv6 draft. */
39364ce7165Smrg    else if (!strncmp("inetv6:", lname, 7)) {
39464ce7165Smrg#if (defined(TCPCONN) || defined(STREAMSCONN)) && \
39564ce7165Smrg    defined(IPv6) && defined(AF_INET6)
39664ce7165Smrg	family = FamilyInternet6;
39764ce7165Smrg	name += 7;
39864ce7165Smrg#else
39964ce7165Smrg	fprintf (stderr, "%s: not compiled for IPv6\n", ProgramName);
40064ce7165Smrg	free(lname);
40164ce7165Smrg	return 0;
40264ce7165Smrg#endif
40364ce7165Smrg    }
40464ce7165Smrg#endif /* ACCEPT_INETV6 */
40564ce7165Smrg    else if (!strncmp("dnet:", lname, 5)) {
40664ce7165Smrg#ifdef DNETCONN
40764ce7165Smrg	family = FamilyDECnet;
40864ce7165Smrg	name += 5;
40964ce7165Smrg#else
41064ce7165Smrg	fprintf (stderr, "%s: not compiled for DECnet\n", ProgramName);
41164ce7165Smrg	free(lname);
41264ce7165Smrg	return 0;
41364ce7165Smrg#endif
41464ce7165Smrg    }
41564ce7165Smrg    else if (!strncmp("nis:", lname, 4)) {
41664ce7165Smrg#ifdef SECURE_RPC
41764ce7165Smrg	family = FamilyNetname;
41864ce7165Smrg	name += 4;
41964ce7165Smrg#else
42064ce7165Smrg	fprintf (stderr, "%s: not compiled for Secure RPC\n", ProgramName);
42164ce7165Smrg	free(lname);
42264ce7165Smrg	return 0;
42364ce7165Smrg#endif
42464ce7165Smrg    }
42564ce7165Smrg    else if (!strncmp("krb:", lname, 4)) {
42664ce7165Smrg#ifdef K5AUTH
42764ce7165Smrg	family = FamilyKrb5Principal;
42864ce7165Smrg	name +=4;
42964ce7165Smrg#else
43064ce7165Smrg	fprintf (stderr, "%s: not compiled for Kerberos 5\n", ProgramName);
43164ce7165Smrg	free(lname);
43264ce7165Smrg	return 0;
43364ce7165Smrg#endif
43464ce7165Smrg    }
43564ce7165Smrg    else if (!strncmp("local:", lname, 6)) {
43664ce7165Smrg	family = FamilyLocalHost;
43764ce7165Smrg    }
43864ce7165Smrg    else if (!strncmp("si:", lname, 3)) {
43964ce7165Smrg	family = FamilyServerInterpreted;
44064ce7165Smrg	name += 3;
44164ce7165Smrg    }
44264ce7165Smrg    if (family == FamilyWild && (cp = strchr(lname, ':'))) {
44364ce7165Smrg	*cp = '\0';
44464ce7165Smrg	fprintf (stderr, "%s: unknown address family \"%s\"\n",
44564ce7165Smrg		 ProgramName, lname);
44664ce7165Smrg	free(lname);
44764ce7165Smrg	return 0;
44864ce7165Smrg    }
44964ce7165Smrg    free(lname);
45064ce7165Smrg
45164ce7165Smrg    if (family == FamilyServerInterpreted) {
45264ce7165Smrg	XServerInterpretedAddress siaddr;
45364ce7165Smrg	int namelen;
45464ce7165Smrg
45564ce7165Smrg	cp = strchr(name, ':');
45664ce7165Smrg	if (cp == NULL || cp == name) {
45764ce7165Smrg	    fprintf(stderr,
45864ce7165Smrg	   "%s: type must be specified for server interpreted family \"%s\"\n",
45964ce7165Smrg	      ProgramName, name);
46064ce7165Smrg	    return 0;
46164ce7165Smrg	}
46264ce7165Smrg	ha.family = FamilyServerInterpreted;
46364ce7165Smrg	ha.address = (char *) &siaddr;
46464ce7165Smrg	namelen = strlen(name);
46564ce7165Smrg	siaddr.type = malloc(namelen);
46664ce7165Smrg	if (siaddr.type == NULL) {
46764ce7165Smrg	    return 0;
46864ce7165Smrg	}
46964ce7165Smrg	memcpy(siaddr.type, name, namelen);
47064ce7165Smrg	siaddr.typelength = cp - name;
47164ce7165Smrg	siaddr.type[siaddr.typelength] = '\0';
47264ce7165Smrg	siaddr.value = siaddr.type + siaddr.typelength + 1;
47364ce7165Smrg	siaddr.valuelength = namelen - (siaddr.typelength + 1);
47464ce7165Smrg	if (add)
47564ce7165Smrg	    XAddHost(dpy, &ha);
47664ce7165Smrg	else
47764ce7165Smrg	    XRemoveHost(dpy, &ha);
47864ce7165Smrg	free(siaddr.type);
47964ce7165Smrg	printf( "%s %s\n", name, add ? add_msg : remove_msg);
48064ce7165Smrg	return 1;
48164ce7165Smrg    }
48264ce7165Smrg
48364ce7165Smrg#ifdef DNETCONN
48464ce7165Smrg    if (family == FamilyDECnet || ((family == FamilyWild) &&
48564ce7165Smrg	(cp = strchr(name, ':')) && (*(cp + 1) == ':') &&
48664ce7165Smrg	!(*cp = '\0'))) {
48764ce7165Smrg	ha.family = FamilyDECnet;
48864ce7165Smrg	if (dnaddrp = dnet_addr(name)) {
48964ce7165Smrg	    dnaddr = *dnaddrp;
49064ce7165Smrg	} else {
49164ce7165Smrg	    if ((np = getnodebyname (name)) == NULL) {
49264ce7165Smrg		fprintf (stderr, "%s:  unable to get node name for \"%s::\"\n",
49364ce7165Smrg			 ProgramName, name);
49464ce7165Smrg		return 0;
49564ce7165Smrg	    }
49664ce7165Smrg	    dnaddr.a_len = np->n_length;
49764ce7165Smrg	    memmove( dnaddr.a_addr, np->n_addr, np->n_length);
49864ce7165Smrg	}
49964ce7165Smrg	ha.length = sizeof(struct dn_naddr);
50064ce7165Smrg	ha.address = (char *)&dnaddr;
50164ce7165Smrg	if (add) {
50264ce7165Smrg	    XAddHost (dpy, &ha);
50364ce7165Smrg	    printf ("%s:: %s\n", name, add_msg);
50464ce7165Smrg	} else {
50564ce7165Smrg	    XRemoveHost (dpy, &ha);
50664ce7165Smrg	    printf ("%s:: %s\n", name, remove_msg);
50764ce7165Smrg	}
50864ce7165Smrg	return 1;
50964ce7165Smrg    }
51064ce7165Smrg#endif				/* DNETCONN */
51164ce7165Smrg#ifdef K5AUTH
51264ce7165Smrg    if (family == FamilyKrb5Principal) {
51364ce7165Smrg	krb5_error_code retval;
51464ce7165Smrg
51564ce7165Smrg	retval = krb5_parse_name(name, &princ);
51664ce7165Smrg	if (retval) {
51764ce7165Smrg	    krb5_init_ets();	/* init krb errs for error_message() */
51864ce7165Smrg	    fprintf(stderr, "%s: cannot parse Kerberos name: %s\n",
51964ce7165Smrg		    ProgramName, error_message(retval));
52064ce7165Smrg	    return 0;
52164ce7165Smrg	}
52264ce7165Smrg	XauKrb5Encode(princ, &kbuf);
52364ce7165Smrg	ha.length = kbuf.length;
52464ce7165Smrg	ha.address = kbuf.data;
52564ce7165Smrg	ha.family = family;
52664ce7165Smrg	if (add)
52764ce7165Smrg	    XAddHost(dpy, &ha);
52864ce7165Smrg	else
52964ce7165Smrg	    XRemoveHost(dpy, &ha);
53064ce7165Smrg	krb5_free_principal(princ);
53164ce7165Smrg	free(kbuf.data);
53264ce7165Smrg	printf( "%s %s\n", name, add ? add_msg : remove_msg);
53364ce7165Smrg	return 1;
53464ce7165Smrg    }
53564ce7165Smrg#endif
53664ce7165Smrg    if (family == FamilyLocalHost) {
53764ce7165Smrg	ha.length = 0;
53864ce7165Smrg	ha.address = "";
53964ce7165Smrg	ha.family = family;
54064ce7165Smrg	if (add)
54164ce7165Smrg	    XAddHost(dpy, &ha);
54264ce7165Smrg	else
54364ce7165Smrg	    XRemoveHost(dpy, &ha);
54464ce7165Smrg	printf( "non-network local connections %s\n", add ? add_msg : remove_msg);
54564ce7165Smrg	return 1;
54664ce7165Smrg    }
54764ce7165Smrg    /*
54864ce7165Smrg     * If it has an '@', it's a netname
54964ce7165Smrg     */
55064ce7165Smrg    if ((family == FamilyNetname && (cp = strchr(name, '@'))) ||
55164ce7165Smrg	(cp = strchr(name, '@'))) {
55264ce7165Smrg        char *netname = name;
55364ce7165Smrg#ifdef SECURE_RPC
55464ce7165Smrg	static char username[MAXNETNAMELEN];
55564ce7165Smrg
55664ce7165Smrg	if (!cp[1]) {
55764ce7165Smrg	    struct passwd *pwd;
55864ce7165Smrg	    static char domainname[128];
55964ce7165Smrg
56064ce7165Smrg	    *cp = '\0';
56164ce7165Smrg	    pwd = getpwnam(name);
56264ce7165Smrg	    if (!pwd) {
56364ce7165Smrg		fprintf(stderr, "no such user \"%s\"\n", name);
56464ce7165Smrg		return 0;
56564ce7165Smrg	    }
56664ce7165Smrg	    getdomainname(domainname, sizeof(domainname));
56764ce7165Smrg	    if (!user2netname(username, pwd->pw_uid, domainname)) {
56864ce7165Smrg		fprintf(stderr, "failed to get netname for \"%s\"\n", name);
56964ce7165Smrg		return 0;
57064ce7165Smrg	    }
57164ce7165Smrg	    netname = username;
57264ce7165Smrg	}
57364ce7165Smrg#endif
57464ce7165Smrg	ha.family = FamilyNetname;
57564ce7165Smrg	ha.length = strlen(netname);
57664ce7165Smrg	ha.address = netname;
57764ce7165Smrg	if (add)
57864ce7165Smrg	    XAddHost (dpy, &ha);
57964ce7165Smrg	else
58064ce7165Smrg	    XRemoveHost (dpy, &ha);
58164ce7165Smrg	if (netname != name)
58264ce7165Smrg	    printf ("%s@ (%s) %s\n", name, netname, add ? add_msg : remove_msg);
58364ce7165Smrg	else
58464ce7165Smrg	    printf ("%s %s\n", netname, add ? add_msg : remove_msg);
58564ce7165Smrg        return 1;
58664ce7165Smrg    }
58764ce7165Smrg#ifdef NEEDSOCKETS
58864ce7165Smrg    /*
58964ce7165Smrg     * First see if inet_addr() can grok the name; if so, then use it.
59064ce7165Smrg     */
59164ce7165Smrg    if (((family == FamilyWild) || (family == FamilyInternet)) &&
59264ce7165Smrg	((addr.s_addr = inet_addr(name)) != -1)) {
59364ce7165Smrg	ha.family = FamilyInternet;
59464ce7165Smrg	ha.length = 4;		/* but for Cray would be sizeof(addr.s_addr) */
59564ce7165Smrg	ha.address = (char *)&addr; /* but for Cray would be &addr.s_addr */
59664ce7165Smrg	if (add) {
59764ce7165Smrg	    XAddHost (dpy, &ha);
59864ce7165Smrg	    printf ("%s %s\n", name, add_msg);
59964ce7165Smrg	} else {
60064ce7165Smrg	    XRemoveHost (dpy, &ha);
60164ce7165Smrg	    printf ("%s %s\n", name, remove_msg);
60264ce7165Smrg	}
60364ce7165Smrg	return 1;
60464ce7165Smrg    }
60564ce7165Smrg#if defined(IPv6) && defined(AF_INET6)
60664ce7165Smrg    /*
60764ce7165Smrg     * Check to see if inet_pton() can grok it as an IPv6 address
60864ce7165Smrg     */
60964ce7165Smrg    else if (((family == FamilyWild) || (family == FamilyInternet6)) &&
61064ce7165Smrg	     (inet_pton(AF_INET6, name, &addr6.s6_addr) == 1)) {
61164ce7165Smrg	ha.family = FamilyInternet6;
61264ce7165Smrg	ha.length = sizeof(addr6.s6_addr);
61364ce7165Smrg	ha.address = (char *) &addr6.s6_addr;
61464ce7165Smrg	if (add) {
61564ce7165Smrg	    XAddHost (dpy, &ha);
61664ce7165Smrg	    printf ("%s %s\n", name, add_msg);
61764ce7165Smrg	} else {
61864ce7165Smrg	    XRemoveHost (dpy, &ha);
61964ce7165Smrg	    printf ("%s %s\n", name, remove_msg);
62064ce7165Smrg	}
62164ce7165Smrg	return 1;
62264ce7165Smrg    } else {
62364ce7165Smrg    /*
62464ce7165Smrg     * Is it in the namespace?
62564ce7165Smrg     *
62664ce7165Smrg     * If no family was specified, use both Internet v4 & v6 addresses.
62764ce7165Smrg     * Otherwise, use only addresses matching specified family.
62864ce7165Smrg     */
62964ce7165Smrg	struct addrinfo *addresses;
63064ce7165Smrg	struct addrinfo *a;
63164ce7165Smrg	Bool didit = False;
63264ce7165Smrg
63364ce7165Smrg	if (getaddrinfo(name, NULL, NULL, &addresses) != 0)
63464ce7165Smrg	    return 0;
63564ce7165Smrg
63664ce7165Smrg	for (a = addresses; a != NULL; a = a->ai_next) {
63764ce7165Smrg	    if ( ((a->ai_family == AF_INET) && (family != FamilyInternet6))
63864ce7165Smrg	      || ((a->ai_family == AF_INET6) && (family != FamilyInternet)) ) {
63964ce7165Smrg		char ad[INET6_ADDRSTRLEN];
64064ce7165Smrg		ha.family = XFamily(a->ai_family);
64164ce7165Smrg		if (a->ai_family == AF_INET6) {
64264ce7165Smrg		    ha.address = (char *)
64364ce7165Smrg		      &((struct sockaddr_in6 *) a->ai_addr)->sin6_addr;
64464ce7165Smrg		    ha.length =
64564ce7165Smrg		      sizeof (((struct sockaddr_in6 *) a->ai_addr)->sin6_addr);
64664ce7165Smrg		} else {
64764ce7165Smrg		    ha.address = (char *)
64864ce7165Smrg		      &((struct sockaddr_in *) a->ai_addr)->sin_addr;
64964ce7165Smrg		    ha.length =
65064ce7165Smrg		      sizeof (((struct sockaddr_in *) a->ai_addr)->sin_addr);
65164ce7165Smrg		}
65264ce7165Smrg		inet_ntop(a->ai_family, ha.address, ad, sizeof(ad));
65364ce7165Smrg	/* printf("Family: %d\nLength: %d\n", a->ai_family, ha.length); */
65464ce7165Smrg		/* printf("Address: %s\n", ad); */
65564ce7165Smrg
65664ce7165Smrg		if (add) {
65764ce7165Smrg		    XAddHost (dpy, &ha);
65864ce7165Smrg		} else {
65964ce7165Smrg		    XRemoveHost (dpy, &ha);
66064ce7165Smrg		}
66164ce7165Smrg		didit = True;
66264ce7165Smrg	    }
66364ce7165Smrg	}
66464ce7165Smrg	if (didit == True) {
66564ce7165Smrg	    printf ("%s %s\n", name, add ? add_msg : remove_msg);
66664ce7165Smrg	} else {
66764ce7165Smrg	    const char *familyMsg = "";
66864ce7165Smrg
66964ce7165Smrg	    if (family == FamilyInternet6) {
67064ce7165Smrg		familyMsg = "inet6 ";
67164ce7165Smrg	    } else if (family == FamilyInternet) {
67264ce7165Smrg		familyMsg = "inet ";
67364ce7165Smrg	    }
67464ce7165Smrg
67564ce7165Smrg	    fprintf(stderr, "%s: unable to get %saddress for \"%s\"\n",
67664ce7165Smrg		ProgramName, familyMsg, name);
67764ce7165Smrg	}
67864ce7165Smrg	freeaddrinfo(addresses);
67964ce7165Smrg	return 1;
68064ce7165Smrg    }
68164ce7165Smrg#else /* !IPv6 */
68264ce7165Smrg    /*
68364ce7165Smrg     * Is it in the namespace?
68464ce7165Smrg     */
68564ce7165Smrg    else if (((hp = gethostbyname(name)) == (struct hostent *)NULL)
68664ce7165Smrg	     || hp->h_addrtype != AF_INET) {
68764ce7165Smrg	return 0;
68864ce7165Smrg    } else {
68964ce7165Smrg	ha.family = XFamily(hp->h_addrtype);
69064ce7165Smrg	ha.length = hp->h_length;
69164ce7165Smrg#ifdef h_addr			/* new 4.3bsd version of gethostent */
69264ce7165Smrg    {
69364ce7165Smrg	char **list;
69464ce7165Smrg
69564ce7165Smrg	/* iterate over the hosts */
69664ce7165Smrg	for (list = hp->h_addr_list; *list; list++) {
69764ce7165Smrg	    ha.address = *list;
69864ce7165Smrg	    if (add) {
69964ce7165Smrg		XAddHost (dpy, &ha);
70064ce7165Smrg	    } else {
70164ce7165Smrg		XRemoveHost (dpy, &ha);
70264ce7165Smrg	    }
70364ce7165Smrg	}
70464ce7165Smrg    }
70564ce7165Smrg#else
70664ce7165Smrg	ha.address = hp->h_addr;
70764ce7165Smrg	if (add) {
70864ce7165Smrg	    XAddHost (dpy, &ha);
70964ce7165Smrg	} else {
71064ce7165Smrg	    XRemoveHost (dpy, &ha);
71164ce7165Smrg	}
71264ce7165Smrg#endif
71364ce7165Smrg	printf ("%s %s\n", name, add ? add_msg : remove_msg);
71464ce7165Smrg	return 1;
71564ce7165Smrg    }
71664ce7165Smrg#endif /* IPv6 */
71764ce7165Smrg#else /* NEEDSOCKETS */
71864ce7165Smrg    return 0;
71964ce7165Smrg#endif /* NEEDSOCKETS */
72064ce7165Smrg}
72164ce7165Smrg
72264ce7165Smrg
72364ce7165Smrg/*
72464ce7165Smrg * get_hostname - Given an internet address, return a name (CHARON.MIT.EDU)
72564ce7165Smrg * or a string representing the address (18.58.0.13) if the name cannot
72664ce7165Smrg * be found.
72764ce7165Smrg */
72864ce7165Smrg
72964ce7165Smrg#ifdef X_NOT_POSIX
73064ce7165Smrgjmp_buf env;
73164ce7165Smrg#endif
73264ce7165Smrg
73364ce7165Smrgstatic char *
73464ce7165Smrgget_hostname(XHostAddress *ha)
73564ce7165Smrg{
73664ce7165Smrg#if (defined(TCPCONN) || defined(STREAMSCONN)) &&	\
73764ce7165Smrg     (!defined(IPv6) || !defined(AF_INET6))
73864ce7165Smrg    static struct hostent *hp = NULL;
73964ce7165Smrg#endif
74064ce7165Smrg#ifdef DNETCONN
74164ce7165Smrg    struct nodeent *np;
74264ce7165Smrg    static char nodeaddr[5 + 2 * DN_MAXADDL];
74364ce7165Smrg#endif				/* DNETCONN */
74464ce7165Smrg#ifdef K5AUTH
74564ce7165Smrg    krb5_principal princ;
74664ce7165Smrg    krb5_data kbuf;
74764ce7165Smrg    char *kname;
74864ce7165Smrg    static char kname_out[255];
74964ce7165Smrg#endif
75064ce7165Smrg#ifndef X_NOT_POSIX
75164ce7165Smrg    struct sigaction sa;
75264ce7165Smrg#endif
75364ce7165Smrg
75464ce7165Smrg#if defined(TCPCONN) || defined(STREAMSCONN)
75564ce7165Smrg#if defined(IPv6) && defined(AF_INET6)
75664ce7165Smrg    if ((ha->family == FamilyInternet) || (ha->family == FamilyInternet6)) {
75764ce7165Smrg	struct sockaddr_storage saddr;
75864ce7165Smrg	static char inetname[NI_MAXHOST];
75964ce7165Smrg	int saddrlen;
76064ce7165Smrg
76164ce7165Smrg	inetname[0] = '\0';
76264ce7165Smrg	memset(&saddr, 0, sizeof saddr);
76364ce7165Smrg	if (ha->family == FamilyInternet) {
76464ce7165Smrg	    struct sockaddr_in *sin = (struct sockaddr_in *) &saddr;
76564ce7165Smrg#ifdef BSD44SOCKETS
76664ce7165Smrg	    sin->sin_len = sizeof(struct sockaddr_in);
76764ce7165Smrg#endif
76864ce7165Smrg	    sin->sin_family = AF_INET;
76964ce7165Smrg	    sin->sin_port = 0;
77064ce7165Smrg	    memcpy(&sin->sin_addr, ha->address, sizeof(sin->sin_addr));
77164ce7165Smrg	    saddrlen = sizeof(struct sockaddr_in);
77264ce7165Smrg	} else {
77364ce7165Smrg	    struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &saddr;
77464ce7165Smrg#ifdef SIN6_LEN
77564ce7165Smrg	    sin6->sin6_len = sizeof(struct sockaddr_in6);
77664ce7165Smrg#endif
77764ce7165Smrg	    sin6->sin6_family = AF_INET6;
77864ce7165Smrg	    sin6->sin6_port = 0;
77964ce7165Smrg	    memcpy(&sin6->sin6_addr, ha->address, sizeof(sin6->sin6_addr));
78064ce7165Smrg	    saddrlen = sizeof(struct sockaddr_in6);
78164ce7165Smrg	}
78264ce7165Smrg
78364ce7165Smrg	/* gethostbyaddr can take a LONG time if the host does not exist.
78464ce7165Smrg	   Assume that if it does not respond in NAMESERVER_TIMEOUT seconds
78564ce7165Smrg	   that something is wrong and do not make the user wait.
78664ce7165Smrg	   gethostbyaddr will continue after a signal, so we have to
78764ce7165Smrg	   jump out of it.
78864ce7165Smrg	   */
78964ce7165Smrg#ifndef X_NOT_POSIX
79064ce7165Smrg	memset(&sa, 0, sizeof sa);
79164ce7165Smrg	sa.sa_handler = nameserver_lost;
79264ce7165Smrg	sa.sa_flags = 0;	/* don't restart syscalls */
79364ce7165Smrg	sigaction(SIGALRM, &sa, NULL);
79464ce7165Smrg#else
79564ce7165Smrg	signal(SIGALRM, nameserver_lost);
79664ce7165Smrg#endif
79764ce7165Smrg	alarm(NAMESERVER_TIMEOUT);
79864ce7165Smrg#ifdef X_NOT_POSIX
79964ce7165Smrg	if (setjmp(env) == 0)
80064ce7165Smrg#endif
80164ce7165Smrg	{
80264ce7165Smrg	    getnameinfo((struct sockaddr *) &saddr, saddrlen, inetname,
80364ce7165Smrg	      sizeof(inetname), NULL, 0, 0);
80464ce7165Smrg	}
80564ce7165Smrg	alarm(0);
80664ce7165Smrg	if (nameserver_timedout || inetname[0] == '\0')
80764ce7165Smrg	    inet_ntop(((struct sockaddr *)&saddr)->sa_family, ha->address,
80864ce7165Smrg		inetname, sizeof(inetname));
80964ce7165Smrg	return inetname;
81064ce7165Smrg    }
81164ce7165Smrg#else
81264ce7165Smrg    if (ha->family == FamilyInternet) {
81364ce7165Smrg#ifdef CRAY
81464ce7165Smrg	struct in_addr t_addr;
81564ce7165Smrg	bzero((char *)&t_addr, sizeof(t_addr));
81664ce7165Smrg	bcopy(ha->address, (char *)&t_addr, 4);
81764ce7165Smrg	ha->address = (char *)&t_addr;
81864ce7165Smrg#endif
81964ce7165Smrg	/* gethostbyaddr can take a LONG time if the host does not exist.
82064ce7165Smrg	   Assume that if it does not respond in NAMESERVER_TIMEOUT seconds
82164ce7165Smrg	   that something is wrong and do not make the user wait.
82264ce7165Smrg	   gethostbyaddr will continue after a signal, so we have to
82364ce7165Smrg	   jump out of it.
82464ce7165Smrg	   */
82564ce7165Smrg#ifndef X_NOT_POSIX
82664ce7165Smrg	memset(&sa, 0, sizeof sa);
82764ce7165Smrg	sa.sa_handler = nameserver_lost;
82864ce7165Smrg	sa.sa_flags = 0;	/* don't restart syscalls */
82964ce7165Smrg	sigaction(SIGALRM, &sa, NULL);
83064ce7165Smrg#else
83164ce7165Smrg	signal(SIGALRM, nameserver_lost);
83264ce7165Smrg#endif
83364ce7165Smrg	alarm(4);
83464ce7165Smrg#ifdef X_NOT_POSIX
83564ce7165Smrg	if (setjmp(env) == 0) {
83664ce7165Smrg#endif
83764ce7165Smrg	    hp = gethostbyaddr (ha->address, ha->length, AF_INET);
83864ce7165Smrg#ifdef X_NOT_POSIX
83964ce7165Smrg	}
84064ce7165Smrg#endif
84164ce7165Smrg	alarm(0);
84264ce7165Smrg	if (hp)
84364ce7165Smrg	    return (hp->h_name);
84464ce7165Smrg	else return (inet_ntoa(*((struct in_addr *)(ha->address))));
84564ce7165Smrg    }
84664ce7165Smrg#endif /* IPv6 */
84764ce7165Smrg#endif
84864ce7165Smrg    if (ha->family == FamilyNetname) {
84964ce7165Smrg	static char netname[512];
85064ce7165Smrg	int len;
85164ce7165Smrg#ifdef SECURE_RPC
85264ce7165Smrg	int gidlen;
85364ce7165Smrg	uid_t uid;
85464ce7165Smrg	gid_t gid, gidlist[NGROUPS_MAX];
85564ce7165Smrg#endif
85664ce7165Smrg
85764ce7165Smrg	if (ha->length < sizeof(netname) - 1)
85864ce7165Smrg	    len = ha->length;
85964ce7165Smrg	else
86064ce7165Smrg	    len = sizeof(netname) - 1;
86164ce7165Smrg	memmove( netname, ha->address, len);
86264ce7165Smrg	netname[len] = '\0';
86364ce7165Smrg#ifdef SECURE_RPC
86464ce7165Smrg	if (netname2user(netname, &uid, &gid, &gidlen, gidlist)) {
86564ce7165Smrg	    struct passwd *pwd;
86664ce7165Smrg
86764ce7165Smrg	    pwd = getpwuid(uid);
86864ce7165Smrg	    if (pwd)
86964ce7165Smrg		sprintf(netname, "%s@ (%*.*s)", pwd->pw_name,
87064ce7165Smrg			ha->length, ha->length, ha->address);
87164ce7165Smrg	}
87264ce7165Smrg#endif
87364ce7165Smrg	return (netname);
87464ce7165Smrg    }
87564ce7165Smrg#ifdef DNETCONN
87664ce7165Smrg    if (ha->family == FamilyDECnet) {
87764ce7165Smrg	struct dn_naddr *addr_ptr = (struct dn_naddr *) ha->address;
87864ce7165Smrg
87964ce7165Smrg	if (np = getnodebyaddr(addr_ptr->a_addr, addr_ptr->a_len, AF_DECnet)) {
88064ce7165Smrg	    sprintf(nodeaddr, "%s", np->n_name);
88164ce7165Smrg	} else {
88264ce7165Smrg	    sprintf(nodeaddr, "%s", dnet_htoa(ha->address));
88364ce7165Smrg	}
88464ce7165Smrg	return(nodeaddr);
88564ce7165Smrg    }
88664ce7165Smrg#endif
88764ce7165Smrg#ifdef K5AUTH
88864ce7165Smrg    if (ha->family == FamilyKrb5Principal) {
88964ce7165Smrg	kbuf.data = ha->address;
89064ce7165Smrg	kbuf.length = ha->length;
89164ce7165Smrg	XauKrb5Decode(kbuf, &princ);
89264ce7165Smrg	krb5_unparse_name(princ, &kname);
89364ce7165Smrg	krb5_free_principal(princ);
89464ce7165Smrg	strncpy(kname_out, kname, sizeof (kname_out));
89564ce7165Smrg	free(kname);
89664ce7165Smrg	return kname_out;
89764ce7165Smrg    }
89864ce7165Smrg#endif
89964ce7165Smrg    if (ha->family == FamilyLocalHost) {
90064ce7165Smrg	return "";
90164ce7165Smrg    }
90264ce7165Smrg    if (ha->family == FamilyServerInterpreted) {
90364ce7165Smrg	XServerInterpretedAddress *sip;
90464ce7165Smrg	static char *addressString;
90564ce7165Smrg	static size_t addressStringSize;
90664ce7165Smrg	size_t neededSize;
90764ce7165Smrg
90864ce7165Smrg	sip = (XServerInterpretedAddress *) ha->address;
90964ce7165Smrg	neededSize = sip->typelength + sip->valuelength + 2;
91064ce7165Smrg
91164ce7165Smrg	if (addressStringSize < neededSize) {
91264ce7165Smrg	    if (addressString != NULL) {
91364ce7165Smrg		free(addressString);
91464ce7165Smrg	    }
91564ce7165Smrg	    addressStringSize = neededSize;
91664ce7165Smrg	    addressString = malloc(addressStringSize);
91764ce7165Smrg	}
91864ce7165Smrg	if (addressString != NULL) {
91964ce7165Smrg	    char *cp = addressString;
92064ce7165Smrg
92164ce7165Smrg	    memcpy(cp, sip->type, sip->typelength);
92264ce7165Smrg	    cp += sip->typelength;
92364ce7165Smrg	    *cp++ = ':';
92464ce7165Smrg	    memcpy(cp, sip->value, sip->valuelength);
92564ce7165Smrg	    cp += sip->valuelength;
92664ce7165Smrg	    *cp = '\0';
92764ce7165Smrg	}
92864ce7165Smrg	return addressString;
92964ce7165Smrg    }
93064ce7165Smrg    return (NULL);
93164ce7165Smrg}
93264ce7165Smrg
93364ce7165Smrg/*ARGUSED*/
93464ce7165Smrgstatic signal_t
93564ce7165Smrgnameserver_lost(int sig)
93664ce7165Smrg{
93764ce7165Smrg    nameserver_timedout = 1;
93864ce7165Smrg#ifdef X_NOT_POSIX
93964ce7165Smrg    /* not needed with POSIX signals - stuck syscalls will not
94064ce7165Smrg       be restarted after signal delivery */
94164ce7165Smrg    longjmp(env, -1);
94264ce7165Smrg#endif
94364ce7165Smrg}
94464ce7165Smrg
94564ce7165Smrg/*
94664ce7165Smrg * local_xerror - local non-fatal error handling routine. If the error was
94764ce7165Smrg * that an X_GetHosts request for an unknown address format was received, just
94864ce7165Smrg * return, otherwise print the normal error message and continue.
94964ce7165Smrg */
95064ce7165Smrgstatic int
95164ce7165Smrglocal_xerror(Display *dpy, XErrorEvent *rep)
95264ce7165Smrg{
95364ce7165Smrg    if ((rep->error_code == BadAccess) && (rep->request_code == X_ChangeHosts)) {
95464ce7165Smrg	fprintf (stderr,
95564ce7165Smrg		 "%s:  must be on local machine to add or remove hosts.\n",
95664ce7165Smrg		 ProgramName);
95764ce7165Smrg	return 1;
95864ce7165Smrg    } else if ((rep->error_code == BadAccess) &&
95964ce7165Smrg	       (rep->request_code == X_SetAccessControl)) {
96064ce7165Smrg	fprintf (stderr,
96164ce7165Smrg	"%s:  must be on local machine to enable or disable access control.\n",
96264ce7165Smrg		 ProgramName);
96364ce7165Smrg	return 1;
96464ce7165Smrg    } else if ((rep->error_code == BadValue) &&
96564ce7165Smrg	       (rep->request_code == X_ListHosts)) {
96664ce7165Smrg	return 1;
96764ce7165Smrg    }
96864ce7165Smrg
96964ce7165Smrg    XmuPrintDefaultErrorMessage (dpy, rep, stderr);
97064ce7165Smrg    return 0;
97164ce7165Smrg}
97264ce7165Smrg
97364ce7165Smrg#ifdef __CYGWIN__
97464ce7165Smrgvoid sethostent(int x)
97564ce7165Smrg{}
97664ce7165Smrg
97764ce7165Smrgvoid endhostent()
97864ce7165Smrg{}
97964ce7165Smrg#endif
98064ce7165Smrg
981