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