xhost.c revision 3544ea2e
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);
1463544ea2eSmrgstatic const 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;
2033544ea2eSmrg    const 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
2163544ea2eSmrg    if (argc == 2 && !strcmp(argv[1], "-help")) {
2173544ea2eSmrg	fprintf(stderr, "usage: %s [[+-]hostname ...]\n", argv[0]);
2183544ea2eSmrg	exit(1);
2193544ea2eSmrg    }
2203544ea2eSmrg
22164ce7165Smrg    if ((dpy = XOpenDisplay(NULL)) == NULL) {
22264ce7165Smrg	fprintf(stderr, "%s:  unable to open display \"%s\"\n",
22364ce7165Smrg		ProgramName, XDisplayName (NULL));
22464ce7165Smrg	exit(1);
22564ce7165Smrg    }
22664ce7165Smrg
22764ce7165Smrg    XSetErrorHandler(local_xerror);
22864ce7165Smrg
22964ce7165Smrg
23064ce7165Smrg    if (argc == 1) {
23164ce7165Smrg#ifdef DNETCONN
23264ce7165Smrg	setnodeent(1);		/* keep the database accessed */
23364ce7165Smrg#endif
23464ce7165Smrg	sethostent(1);		/* don't close the data base each time */
23564ce7165Smrg	list = XListHosts(dpy, &nhosts, &enabled);
23664ce7165Smrg	if (enabled)
23764ce7165Smrg	    printf ("access control enabled, only authorized clients can connect\n");
23864ce7165Smrg	else
23964ce7165Smrg	    printf ("access control disabled, clients can connect from any host\n");
24064ce7165Smrg
24164ce7165Smrg	if (nhosts != 0) {
24264ce7165Smrg	    for (i = 0; i < nhosts; i++ )  {
24364ce7165Smrg		hostname = get_hostname(&list[i]);
24464ce7165Smrg		if (hostname) {
24564ce7165Smrg		    switch (list[i].family) {
24664ce7165Smrg		    case FamilyInternet:
24764ce7165Smrg			printf("INET:");
24864ce7165Smrg			break;
24964ce7165Smrg		    case FamilyInternet6:
25064ce7165Smrg			printf("INET6:");
25164ce7165Smrg			break;
25264ce7165Smrg		    case FamilyDECnet:
25364ce7165Smrg			printf("DNET:");
25464ce7165Smrg			break;
25564ce7165Smrg		    case FamilyNetname:
25664ce7165Smrg			printf("NIS:");
25764ce7165Smrg			break;
25864ce7165Smrg		    case FamilyKrb5Principal:
25964ce7165Smrg			printf("KRB:");
26064ce7165Smrg			break;
26164ce7165Smrg		    case FamilyLocalHost:
26264ce7165Smrg			printf("LOCAL:");
26364ce7165Smrg			break;
26464ce7165Smrg		    case FamilyServerInterpreted:
26564ce7165Smrg			printf("SI:");
26664ce7165Smrg			break;
26764ce7165Smrg		    default:
26864ce7165Smrg			printf("<unknown family type %d>:", list[i].family);
26964ce7165Smrg			break;
27064ce7165Smrg		    }
27164ce7165Smrg		    printf ("%s", hostname);
27264ce7165Smrg		} else {
27364ce7165Smrg		    printf ("<unknown address in family %d>",
27464ce7165Smrg			    list[i].family);
27564ce7165Smrg		}
27664ce7165Smrg		if (nameserver_timedout) {
27764ce7165Smrg		    printf("\t(no nameserver response within %d seconds)\n",
27864ce7165Smrg			   NAMESERVER_TIMEOUT);
27964ce7165Smrg		    nameserver_timedout = 0;
28064ce7165Smrg		} else
28164ce7165Smrg		    printf("\n");
28264ce7165Smrg	    }
28364ce7165Smrg	    free(list);
28464ce7165Smrg	    endhostent();
28564ce7165Smrg	}
28664ce7165Smrg	exit(0);
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 */
3583544ea2eSmrg    static const char *add_msg = "being added to access control list";
3593544ea2eSmrg    static const 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;
4533544ea2eSmrg	int rc;
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	}
4623544ea2eSmrg	siaddr.type = name;
4633544ea2eSmrg	siaddr.typelength = cp - name;
4643544ea2eSmrg	siaddr.value = ++cp;
4653544ea2eSmrg	siaddr.valuelength = strlen(cp);
46664ce7165Smrg	ha.family = FamilyServerInterpreted;
46764ce7165Smrg	ha.address = (char *) &siaddr;
46864ce7165Smrg	if (add)
4693544ea2eSmrg	    rc = XAddHost(dpy, &ha);
47064ce7165Smrg	else
4713544ea2eSmrg	    rc = XRemoveHost(dpy, &ha);
4723544ea2eSmrg	printf( "%s %s%s\n", name, rc == 1 ? "" : "failed when ",
4733544ea2eSmrg		add ? add_msg : remove_msg);
4743544ea2eSmrg	if (rc != 1)
4753544ea2eSmrg	    return 0;
47664ce7165Smrg	return 1;
47764ce7165Smrg    }
47864ce7165Smrg
47964ce7165Smrg#ifdef DNETCONN
48064ce7165Smrg    if (family == FamilyDECnet || ((family == FamilyWild) &&
48164ce7165Smrg	(cp = strchr(name, ':')) && (*(cp + 1) == ':') &&
48264ce7165Smrg	!(*cp = '\0'))) {
48364ce7165Smrg	ha.family = FamilyDECnet;
48464ce7165Smrg	if (dnaddrp = dnet_addr(name)) {
48564ce7165Smrg	    dnaddr = *dnaddrp;
48664ce7165Smrg	} else {
48764ce7165Smrg	    if ((np = getnodebyname (name)) == NULL) {
48864ce7165Smrg		fprintf (stderr, "%s:  unable to get node name for \"%s::\"\n",
48964ce7165Smrg			 ProgramName, name);
49064ce7165Smrg		return 0;
49164ce7165Smrg	    }
49264ce7165Smrg	    dnaddr.a_len = np->n_length;
49364ce7165Smrg	    memmove( dnaddr.a_addr, np->n_addr, np->n_length);
49464ce7165Smrg	}
49564ce7165Smrg	ha.length = sizeof(struct dn_naddr);
49664ce7165Smrg	ha.address = (char *)&dnaddr;
49764ce7165Smrg	if (add) {
49864ce7165Smrg	    XAddHost (dpy, &ha);
49964ce7165Smrg	    printf ("%s:: %s\n", name, add_msg);
50064ce7165Smrg	} else {
50164ce7165Smrg	    XRemoveHost (dpy, &ha);
50264ce7165Smrg	    printf ("%s:: %s\n", name, remove_msg);
50364ce7165Smrg	}
50464ce7165Smrg	return 1;
50564ce7165Smrg    }
50664ce7165Smrg#endif				/* DNETCONN */
50764ce7165Smrg#ifdef K5AUTH
50864ce7165Smrg    if (family == FamilyKrb5Principal) {
50964ce7165Smrg	krb5_error_code retval;
51064ce7165Smrg
51164ce7165Smrg	retval = krb5_parse_name(name, &princ);
51264ce7165Smrg	if (retval) {
51364ce7165Smrg	    krb5_init_ets();	/* init krb errs for error_message() */
51464ce7165Smrg	    fprintf(stderr, "%s: cannot parse Kerberos name: %s\n",
51564ce7165Smrg		    ProgramName, error_message(retval));
51664ce7165Smrg	    return 0;
51764ce7165Smrg	}
51864ce7165Smrg	XauKrb5Encode(princ, &kbuf);
51964ce7165Smrg	ha.length = kbuf.length;
52064ce7165Smrg	ha.address = kbuf.data;
52164ce7165Smrg	ha.family = family;
52264ce7165Smrg	if (add)
52364ce7165Smrg	    XAddHost(dpy, &ha);
52464ce7165Smrg	else
52564ce7165Smrg	    XRemoveHost(dpy, &ha);
52664ce7165Smrg	krb5_free_principal(princ);
52764ce7165Smrg	free(kbuf.data);
52864ce7165Smrg	printf( "%s %s\n", name, add ? add_msg : remove_msg);
52964ce7165Smrg	return 1;
53064ce7165Smrg    }
53164ce7165Smrg#endif
53264ce7165Smrg    if (family == FamilyLocalHost) {
53364ce7165Smrg	ha.length = 0;
53464ce7165Smrg	ha.address = "";
53564ce7165Smrg	ha.family = family;
53664ce7165Smrg	if (add)
53764ce7165Smrg	    XAddHost(dpy, &ha);
53864ce7165Smrg	else
53964ce7165Smrg	    XRemoveHost(dpy, &ha);
54064ce7165Smrg	printf( "non-network local connections %s\n", add ? add_msg : remove_msg);
54164ce7165Smrg	return 1;
54264ce7165Smrg    }
54364ce7165Smrg    /*
54464ce7165Smrg     * If it has an '@', it's a netname
54564ce7165Smrg     */
54664ce7165Smrg    if ((family == FamilyNetname && (cp = strchr(name, '@'))) ||
54764ce7165Smrg	(cp = strchr(name, '@'))) {
54864ce7165Smrg        char *netname = name;
54964ce7165Smrg#ifdef SECURE_RPC
55064ce7165Smrg	static char username[MAXNETNAMELEN];
55164ce7165Smrg
55264ce7165Smrg	if (!cp[1]) {
55364ce7165Smrg	    struct passwd *pwd;
55464ce7165Smrg	    static char domainname[128];
55564ce7165Smrg
55664ce7165Smrg	    *cp = '\0';
55764ce7165Smrg	    pwd = getpwnam(name);
55864ce7165Smrg	    if (!pwd) {
55964ce7165Smrg		fprintf(stderr, "no such user \"%s\"\n", name);
56064ce7165Smrg		return 0;
56164ce7165Smrg	    }
56264ce7165Smrg	    getdomainname(domainname, sizeof(domainname));
56364ce7165Smrg	    if (!user2netname(username, pwd->pw_uid, domainname)) {
56464ce7165Smrg		fprintf(stderr, "failed to get netname for \"%s\"\n", name);
56564ce7165Smrg		return 0;
56664ce7165Smrg	    }
56764ce7165Smrg	    netname = username;
56864ce7165Smrg	}
56964ce7165Smrg#endif
57064ce7165Smrg	ha.family = FamilyNetname;
57164ce7165Smrg	ha.length = strlen(netname);
57264ce7165Smrg	ha.address = netname;
57364ce7165Smrg	if (add)
57464ce7165Smrg	    XAddHost (dpy, &ha);
57564ce7165Smrg	else
57664ce7165Smrg	    XRemoveHost (dpy, &ha);
57764ce7165Smrg	if (netname != name)
57864ce7165Smrg	    printf ("%s@ (%s) %s\n", name, netname, add ? add_msg : remove_msg);
57964ce7165Smrg	else
58064ce7165Smrg	    printf ("%s %s\n", netname, add ? add_msg : remove_msg);
58164ce7165Smrg        return 1;
58264ce7165Smrg    }
58364ce7165Smrg#ifdef NEEDSOCKETS
58464ce7165Smrg    /*
58564ce7165Smrg     * First see if inet_addr() can grok the name; if so, then use it.
58664ce7165Smrg     */
58764ce7165Smrg    if (((family == FamilyWild) || (family == FamilyInternet)) &&
58864ce7165Smrg	((addr.s_addr = inet_addr(name)) != -1)) {
58964ce7165Smrg	ha.family = FamilyInternet;
59064ce7165Smrg	ha.length = 4;		/* but for Cray would be sizeof(addr.s_addr) */
59164ce7165Smrg	ha.address = (char *)&addr; /* but for Cray would be &addr.s_addr */
59264ce7165Smrg	if (add) {
59364ce7165Smrg	    XAddHost (dpy, &ha);
59464ce7165Smrg	    printf ("%s %s\n", name, add_msg);
59564ce7165Smrg	} else {
59664ce7165Smrg	    XRemoveHost (dpy, &ha);
59764ce7165Smrg	    printf ("%s %s\n", name, remove_msg);
59864ce7165Smrg	}
59964ce7165Smrg	return 1;
60064ce7165Smrg    }
60164ce7165Smrg#if defined(IPv6) && defined(AF_INET6)
60264ce7165Smrg    /*
60364ce7165Smrg     * Check to see if inet_pton() can grok it as an IPv6 address
60464ce7165Smrg     */
60564ce7165Smrg    else if (((family == FamilyWild) || (family == FamilyInternet6)) &&
60664ce7165Smrg	     (inet_pton(AF_INET6, name, &addr6.s6_addr) == 1)) {
60764ce7165Smrg	ha.family = FamilyInternet6;
60864ce7165Smrg	ha.length = sizeof(addr6.s6_addr);
60964ce7165Smrg	ha.address = (char *) &addr6.s6_addr;
61064ce7165Smrg	if (add) {
61164ce7165Smrg	    XAddHost (dpy, &ha);
61264ce7165Smrg	    printf ("%s %s\n", name, add_msg);
61364ce7165Smrg	} else {
61464ce7165Smrg	    XRemoveHost (dpy, &ha);
61564ce7165Smrg	    printf ("%s %s\n", name, remove_msg);
61664ce7165Smrg	}
61764ce7165Smrg	return 1;
61864ce7165Smrg    } else {
61964ce7165Smrg    /*
62064ce7165Smrg     * Is it in the namespace?
62164ce7165Smrg     *
62264ce7165Smrg     * If no family was specified, use both Internet v4 & v6 addresses.
62364ce7165Smrg     * Otherwise, use only addresses matching specified family.
62464ce7165Smrg     */
62564ce7165Smrg	struct addrinfo *addresses;
62664ce7165Smrg	struct addrinfo *a;
62764ce7165Smrg	Bool didit = False;
62864ce7165Smrg
62964ce7165Smrg	if (getaddrinfo(name, NULL, NULL, &addresses) != 0)
63064ce7165Smrg	    return 0;
63164ce7165Smrg
63264ce7165Smrg	for (a = addresses; a != NULL; a = a->ai_next) {
63364ce7165Smrg	    if ( ((a->ai_family == AF_INET) && (family != FamilyInternet6))
63464ce7165Smrg	      || ((a->ai_family == AF_INET6) && (family != FamilyInternet)) ) {
63564ce7165Smrg		char ad[INET6_ADDRSTRLEN];
63664ce7165Smrg		ha.family = XFamily(a->ai_family);
63764ce7165Smrg		if (a->ai_family == AF_INET6) {
63864ce7165Smrg		    ha.address = (char *)
63964ce7165Smrg		      &((struct sockaddr_in6 *) a->ai_addr)->sin6_addr;
64064ce7165Smrg		    ha.length =
64164ce7165Smrg		      sizeof (((struct sockaddr_in6 *) a->ai_addr)->sin6_addr);
64264ce7165Smrg		} else {
64364ce7165Smrg		    ha.address = (char *)
64464ce7165Smrg		      &((struct sockaddr_in *) a->ai_addr)->sin_addr;
64564ce7165Smrg		    ha.length =
64664ce7165Smrg		      sizeof (((struct sockaddr_in *) a->ai_addr)->sin_addr);
64764ce7165Smrg		}
64864ce7165Smrg		inet_ntop(a->ai_family, ha.address, ad, sizeof(ad));
64964ce7165Smrg	/* printf("Family: %d\nLength: %d\n", a->ai_family, ha.length); */
65064ce7165Smrg		/* printf("Address: %s\n", ad); */
65164ce7165Smrg
65264ce7165Smrg		if (add) {
65364ce7165Smrg		    XAddHost (dpy, &ha);
65464ce7165Smrg		} else {
65564ce7165Smrg		    XRemoveHost (dpy, &ha);
65664ce7165Smrg		}
65764ce7165Smrg		didit = True;
65864ce7165Smrg	    }
65964ce7165Smrg	}
66064ce7165Smrg	if (didit == True) {
66164ce7165Smrg	    printf ("%s %s\n", name, add ? add_msg : remove_msg);
66264ce7165Smrg	} else {
66364ce7165Smrg	    const char *familyMsg = "";
66464ce7165Smrg
66564ce7165Smrg	    if (family == FamilyInternet6) {
66664ce7165Smrg		familyMsg = "inet6 ";
66764ce7165Smrg	    } else if (family == FamilyInternet) {
66864ce7165Smrg		familyMsg = "inet ";
66964ce7165Smrg	    }
67064ce7165Smrg
67164ce7165Smrg	    fprintf(stderr, "%s: unable to get %saddress for \"%s\"\n",
67264ce7165Smrg		ProgramName, familyMsg, name);
67364ce7165Smrg	}
67464ce7165Smrg	freeaddrinfo(addresses);
67564ce7165Smrg	return 1;
67664ce7165Smrg    }
67764ce7165Smrg#else /* !IPv6 */
67864ce7165Smrg    /*
67964ce7165Smrg     * Is it in the namespace?
68064ce7165Smrg     */
68164ce7165Smrg    else if (((hp = gethostbyname(name)) == (struct hostent *)NULL)
68264ce7165Smrg	     || hp->h_addrtype != AF_INET) {
68364ce7165Smrg	return 0;
68464ce7165Smrg    } else {
68564ce7165Smrg	ha.family = XFamily(hp->h_addrtype);
68664ce7165Smrg	ha.length = hp->h_length;
68764ce7165Smrg#ifdef h_addr			/* new 4.3bsd version of gethostent */
68864ce7165Smrg    {
68964ce7165Smrg	char **list;
69064ce7165Smrg
69164ce7165Smrg	/* iterate over the hosts */
69264ce7165Smrg	for (list = hp->h_addr_list; *list; list++) {
69364ce7165Smrg	    ha.address = *list;
69464ce7165Smrg	    if (add) {
69564ce7165Smrg		XAddHost (dpy, &ha);
69664ce7165Smrg	    } else {
69764ce7165Smrg		XRemoveHost (dpy, &ha);
69864ce7165Smrg	    }
69964ce7165Smrg	}
70064ce7165Smrg    }
70164ce7165Smrg#else
70264ce7165Smrg	ha.address = hp->h_addr;
70364ce7165Smrg	if (add) {
70464ce7165Smrg	    XAddHost (dpy, &ha);
70564ce7165Smrg	} else {
70664ce7165Smrg	    XRemoveHost (dpy, &ha);
70764ce7165Smrg	}
70864ce7165Smrg#endif
70964ce7165Smrg	printf ("%s %s\n", name, add ? add_msg : remove_msg);
71064ce7165Smrg	return 1;
71164ce7165Smrg    }
71264ce7165Smrg#endif /* IPv6 */
71364ce7165Smrg#else /* NEEDSOCKETS */
71464ce7165Smrg    return 0;
71564ce7165Smrg#endif /* NEEDSOCKETS */
71664ce7165Smrg}
71764ce7165Smrg
71864ce7165Smrg
71964ce7165Smrg/*
72064ce7165Smrg * get_hostname - Given an internet address, return a name (CHARON.MIT.EDU)
72164ce7165Smrg * or a string representing the address (18.58.0.13) if the name cannot
72264ce7165Smrg * be found.
72364ce7165Smrg */
72464ce7165Smrg
72564ce7165Smrg#ifdef X_NOT_POSIX
72664ce7165Smrgjmp_buf env;
72764ce7165Smrg#endif
72864ce7165Smrg
7293544ea2eSmrgstatic const char *
73064ce7165Smrgget_hostname(XHostAddress *ha)
73164ce7165Smrg{
73264ce7165Smrg#if (defined(TCPCONN) || defined(STREAMSCONN)) &&	\
73364ce7165Smrg     (!defined(IPv6) || !defined(AF_INET6))
73464ce7165Smrg    static struct hostent *hp = NULL;
73564ce7165Smrg#endif
73664ce7165Smrg#ifdef DNETCONN
73764ce7165Smrg    struct nodeent *np;
73864ce7165Smrg    static char nodeaddr[5 + 2 * DN_MAXADDL];
73964ce7165Smrg#endif				/* DNETCONN */
74064ce7165Smrg#ifdef K5AUTH
74164ce7165Smrg    krb5_principal princ;
74264ce7165Smrg    krb5_data kbuf;
74364ce7165Smrg    char *kname;
74464ce7165Smrg    static char kname_out[255];
74564ce7165Smrg#endif
74664ce7165Smrg#ifndef X_NOT_POSIX
74764ce7165Smrg    struct sigaction sa;
74864ce7165Smrg#endif
74964ce7165Smrg
75064ce7165Smrg#if defined(TCPCONN) || defined(STREAMSCONN)
75164ce7165Smrg#if defined(IPv6) && defined(AF_INET6)
75264ce7165Smrg    if ((ha->family == FamilyInternet) || (ha->family == FamilyInternet6)) {
75364ce7165Smrg	struct sockaddr_storage saddr;
75464ce7165Smrg	static char inetname[NI_MAXHOST];
75564ce7165Smrg	int saddrlen;
75664ce7165Smrg
75764ce7165Smrg	inetname[0] = '\0';
75864ce7165Smrg	memset(&saddr, 0, sizeof saddr);
75964ce7165Smrg	if (ha->family == FamilyInternet) {
76064ce7165Smrg	    struct sockaddr_in *sin = (struct sockaddr_in *) &saddr;
76164ce7165Smrg#ifdef BSD44SOCKETS
76264ce7165Smrg	    sin->sin_len = sizeof(struct sockaddr_in);
76364ce7165Smrg#endif
76464ce7165Smrg	    sin->sin_family = AF_INET;
76564ce7165Smrg	    sin->sin_port = 0;
76664ce7165Smrg	    memcpy(&sin->sin_addr, ha->address, sizeof(sin->sin_addr));
76764ce7165Smrg	    saddrlen = sizeof(struct sockaddr_in);
76864ce7165Smrg	} else {
76964ce7165Smrg	    struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &saddr;
77064ce7165Smrg#ifdef SIN6_LEN
77164ce7165Smrg	    sin6->sin6_len = sizeof(struct sockaddr_in6);
77264ce7165Smrg#endif
77364ce7165Smrg	    sin6->sin6_family = AF_INET6;
77464ce7165Smrg	    sin6->sin6_port = 0;
77564ce7165Smrg	    memcpy(&sin6->sin6_addr, ha->address, sizeof(sin6->sin6_addr));
77664ce7165Smrg	    saddrlen = sizeof(struct sockaddr_in6);
77764ce7165Smrg	}
77864ce7165Smrg
77964ce7165Smrg	/* gethostbyaddr can take a LONG time if the host does not exist.
78064ce7165Smrg	   Assume that if it does not respond in NAMESERVER_TIMEOUT seconds
78164ce7165Smrg	   that something is wrong and do not make the user wait.
78264ce7165Smrg	   gethostbyaddr will continue after a signal, so we have to
78364ce7165Smrg	   jump out of it.
78464ce7165Smrg	   */
78564ce7165Smrg#ifndef X_NOT_POSIX
78664ce7165Smrg	memset(&sa, 0, sizeof sa);
78764ce7165Smrg	sa.sa_handler = nameserver_lost;
78864ce7165Smrg	sa.sa_flags = 0;	/* don't restart syscalls */
78964ce7165Smrg	sigaction(SIGALRM, &sa, NULL);
79064ce7165Smrg#else
79164ce7165Smrg	signal(SIGALRM, nameserver_lost);
79264ce7165Smrg#endif
79364ce7165Smrg	alarm(NAMESERVER_TIMEOUT);
79464ce7165Smrg#ifdef X_NOT_POSIX
79564ce7165Smrg	if (setjmp(env) == 0)
79664ce7165Smrg#endif
79764ce7165Smrg	{
79864ce7165Smrg	    getnameinfo((struct sockaddr *) &saddr, saddrlen, inetname,
79964ce7165Smrg	      sizeof(inetname), NULL, 0, 0);
80064ce7165Smrg	}
80164ce7165Smrg	alarm(0);
80264ce7165Smrg	if (nameserver_timedout || inetname[0] == '\0')
80364ce7165Smrg	    inet_ntop(((struct sockaddr *)&saddr)->sa_family, ha->address,
80464ce7165Smrg		inetname, sizeof(inetname));
80564ce7165Smrg	return inetname;
80664ce7165Smrg    }
80764ce7165Smrg#else
80864ce7165Smrg    if (ha->family == FamilyInternet) {
80964ce7165Smrg#ifdef CRAY
81064ce7165Smrg	struct in_addr t_addr;
81164ce7165Smrg	bzero((char *)&t_addr, sizeof(t_addr));
81264ce7165Smrg	bcopy(ha->address, (char *)&t_addr, 4);
81364ce7165Smrg	ha->address = (char *)&t_addr;
81464ce7165Smrg#endif
81564ce7165Smrg	/* gethostbyaddr can take a LONG time if the host does not exist.
81664ce7165Smrg	   Assume that if it does not respond in NAMESERVER_TIMEOUT seconds
81764ce7165Smrg	   that something is wrong and do not make the user wait.
81864ce7165Smrg	   gethostbyaddr will continue after a signal, so we have to
81964ce7165Smrg	   jump out of it.
82064ce7165Smrg	   */
82164ce7165Smrg#ifndef X_NOT_POSIX
82264ce7165Smrg	memset(&sa, 0, sizeof sa);
82364ce7165Smrg	sa.sa_handler = nameserver_lost;
82464ce7165Smrg	sa.sa_flags = 0;	/* don't restart syscalls */
82564ce7165Smrg	sigaction(SIGALRM, &sa, NULL);
82664ce7165Smrg#else
82764ce7165Smrg	signal(SIGALRM, nameserver_lost);
82864ce7165Smrg#endif
82964ce7165Smrg	alarm(4);
83064ce7165Smrg#ifdef X_NOT_POSIX
83164ce7165Smrg	if (setjmp(env) == 0) {
83264ce7165Smrg#endif
83364ce7165Smrg	    hp = gethostbyaddr (ha->address, ha->length, AF_INET);
83464ce7165Smrg#ifdef X_NOT_POSIX
83564ce7165Smrg	}
83664ce7165Smrg#endif
83764ce7165Smrg	alarm(0);
83864ce7165Smrg	if (hp)
83964ce7165Smrg	    return (hp->h_name);
84064ce7165Smrg	else return (inet_ntoa(*((struct in_addr *)(ha->address))));
84164ce7165Smrg    }
84264ce7165Smrg#endif /* IPv6 */
84364ce7165Smrg#endif
84464ce7165Smrg    if (ha->family == FamilyNetname) {
84564ce7165Smrg	static char netname[512];
84664ce7165Smrg	int len;
84764ce7165Smrg#ifdef SECURE_RPC
84864ce7165Smrg	int gidlen;
84964ce7165Smrg	uid_t uid;
85064ce7165Smrg	gid_t gid, gidlist[NGROUPS_MAX];
85164ce7165Smrg#endif
85264ce7165Smrg
85364ce7165Smrg	if (ha->length < sizeof(netname) - 1)
85464ce7165Smrg	    len = ha->length;
85564ce7165Smrg	else
85664ce7165Smrg	    len = sizeof(netname) - 1;
85764ce7165Smrg	memmove( netname, ha->address, len);
85864ce7165Smrg	netname[len] = '\0';
85964ce7165Smrg#ifdef SECURE_RPC
86064ce7165Smrg	if (netname2user(netname, &uid, &gid, &gidlen, gidlist)) {
86164ce7165Smrg	    struct passwd *pwd;
86264ce7165Smrg
86364ce7165Smrg	    pwd = getpwuid(uid);
86464ce7165Smrg	    if (pwd)
86564ce7165Smrg		sprintf(netname, "%s@ (%*.*s)", pwd->pw_name,
86664ce7165Smrg			ha->length, ha->length, ha->address);
86764ce7165Smrg	}
86864ce7165Smrg#endif
86964ce7165Smrg	return (netname);
87064ce7165Smrg    }
87164ce7165Smrg#ifdef DNETCONN
87264ce7165Smrg    if (ha->family == FamilyDECnet) {
87364ce7165Smrg	struct dn_naddr *addr_ptr = (struct dn_naddr *) ha->address;
87464ce7165Smrg
87564ce7165Smrg	if (np = getnodebyaddr(addr_ptr->a_addr, addr_ptr->a_len, AF_DECnet)) {
87664ce7165Smrg	    sprintf(nodeaddr, "%s", np->n_name);
87764ce7165Smrg	} else {
87864ce7165Smrg	    sprintf(nodeaddr, "%s", dnet_htoa(ha->address));
87964ce7165Smrg	}
88064ce7165Smrg	return(nodeaddr);
88164ce7165Smrg    }
88264ce7165Smrg#endif
88364ce7165Smrg#ifdef K5AUTH
88464ce7165Smrg    if (ha->family == FamilyKrb5Principal) {
88564ce7165Smrg	kbuf.data = ha->address;
88664ce7165Smrg	kbuf.length = ha->length;
88764ce7165Smrg	XauKrb5Decode(kbuf, &princ);
88864ce7165Smrg	krb5_unparse_name(princ, &kname);
88964ce7165Smrg	krb5_free_principal(princ);
89064ce7165Smrg	strncpy(kname_out, kname, sizeof (kname_out));
89164ce7165Smrg	free(kname);
89264ce7165Smrg	return kname_out;
89364ce7165Smrg    }
89464ce7165Smrg#endif
89564ce7165Smrg    if (ha->family == FamilyLocalHost) {
89664ce7165Smrg	return "";
89764ce7165Smrg    }
89864ce7165Smrg    if (ha->family == FamilyServerInterpreted) {
89964ce7165Smrg	XServerInterpretedAddress *sip;
90064ce7165Smrg	static char *addressString;
90164ce7165Smrg	static size_t addressStringSize;
90264ce7165Smrg	size_t neededSize;
90364ce7165Smrg
90464ce7165Smrg	sip = (XServerInterpretedAddress *) ha->address;
90564ce7165Smrg	neededSize = sip->typelength + sip->valuelength + 2;
90664ce7165Smrg
90764ce7165Smrg	if (addressStringSize < neededSize) {
90864ce7165Smrg	    if (addressString != NULL) {
90964ce7165Smrg		free(addressString);
91064ce7165Smrg	    }
91164ce7165Smrg	    addressStringSize = neededSize;
91264ce7165Smrg	    addressString = malloc(addressStringSize);
91364ce7165Smrg	}
91464ce7165Smrg	if (addressString != NULL) {
91564ce7165Smrg	    char *cp = addressString;
91664ce7165Smrg
91764ce7165Smrg	    memcpy(cp, sip->type, sip->typelength);
91864ce7165Smrg	    cp += sip->typelength;
91964ce7165Smrg	    *cp++ = ':';
92064ce7165Smrg	    memcpy(cp, sip->value, sip->valuelength);
92164ce7165Smrg	    cp += sip->valuelength;
92264ce7165Smrg	    *cp = '\0';
92364ce7165Smrg	}
92464ce7165Smrg	return addressString;
92564ce7165Smrg    }
92664ce7165Smrg    return (NULL);
92764ce7165Smrg}
92864ce7165Smrg
92964ce7165Smrg/*ARGUSED*/
93064ce7165Smrgstatic signal_t
93164ce7165Smrgnameserver_lost(int sig)
93264ce7165Smrg{
93364ce7165Smrg    nameserver_timedout = 1;
93464ce7165Smrg#ifdef X_NOT_POSIX
93564ce7165Smrg    /* not needed with POSIX signals - stuck syscalls will not
93664ce7165Smrg       be restarted after signal delivery */
93764ce7165Smrg    longjmp(env, -1);
93864ce7165Smrg#endif
93964ce7165Smrg}
94064ce7165Smrg
94164ce7165Smrg/*
94264ce7165Smrg * local_xerror - local non-fatal error handling routine. If the error was
94364ce7165Smrg * that an X_GetHosts request for an unknown address format was received, just
94464ce7165Smrg * return, otherwise print the normal error message and continue.
94564ce7165Smrg */
94664ce7165Smrgstatic int
94764ce7165Smrglocal_xerror(Display *dpy, XErrorEvent *rep)
94864ce7165Smrg{
94964ce7165Smrg    if ((rep->error_code == BadAccess) && (rep->request_code == X_ChangeHosts)) {
95064ce7165Smrg	fprintf (stderr,
95164ce7165Smrg		 "%s:  must be on local machine to add or remove hosts.\n",
95264ce7165Smrg		 ProgramName);
95364ce7165Smrg	return 1;
95464ce7165Smrg    } else if ((rep->error_code == BadAccess) &&
95564ce7165Smrg	       (rep->request_code == X_SetAccessControl)) {
95664ce7165Smrg	fprintf (stderr,
95764ce7165Smrg	"%s:  must be on local machine to enable or disable access control.\n",
95864ce7165Smrg		 ProgramName);
95964ce7165Smrg	return 1;
96064ce7165Smrg    } else if ((rep->error_code == BadValue) &&
96164ce7165Smrg	       (rep->request_code == X_ListHosts)) {
96264ce7165Smrg	return 1;
96364ce7165Smrg    }
96464ce7165Smrg
96564ce7165Smrg    XmuPrintDefaultErrorMessage (dpy, rep, stderr);
96664ce7165Smrg    return 0;
96764ce7165Smrg}
96864ce7165Smrg
96964ce7165Smrg#ifdef __CYGWIN__
97064ce7165Smrgvoid sethostent(int x)
97164ce7165Smrg{}
97264ce7165Smrg
97364ce7165Smrgvoid endhostent()
97464ce7165Smrg{}
97564ce7165Smrg#endif
97664ce7165Smrg
977