1169a0819Smrg/*
2b71ad168Smrg * Copyright (c) 2000, 2004, 2022, Oracle and/or its affiliates.
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
6281440437Smrg#ifdef TCPCONN
6364ce7165Smrg#define NEEDSOCKETS
6464ce7165Smrg#endif
6564ce7165Smrg#ifdef UNIXCONN
6664ce7165Smrg#define NEEDSOCKETS
6764ce7165Smrg#endif
6864ce7165Smrg
6964ce7165Smrg#include <X11/Xlib.h>
7064ce7165Smrg#include <X11/Xos.h>
7164ce7165Smrg#include <X11/Xproto.h>
7264ce7165Smrg#include <X11/Xfuncs.h>
7364ce7165Smrg#include <stdio.h>
7464ce7165Smrg#include <stdlib.h>
7564ce7165Smrg#include <signal.h>
7664ce7165Smrg#include <ctype.h>
7764ce7165Smrg#include <X11/Xauth.h>
7864ce7165Smrg#include <X11/Xmu/Error.h>
7964ce7165Smrg#include <stdlib.h>
8064ce7165Smrg
8164ce7165Smrg#ifdef NEEDSOCKETS
8281440437Smrg#ifdef WIN32
8381440437Smrg#include <X11/Xwinsock.h>
8464ce7165Smrg#else
8564ce7165Smrg#include <sys/socket.h>
8664ce7165Smrg#include <netdb.h>
8764ce7165Smrg#include <netinet/in.h>
8864ce7165Smrg#endif
8964ce7165Smrg#endif /* NEEDSOCKETS */
9064ce7165Smrg
9181440437Smrg#ifndef WIN32
9264ce7165Smrg#include <arpa/inet.h>
9364ce7165Smrg#endif
9464ce7165Smrg
9564ce7165Smrg
9664ce7165Smrg#ifdef SECURE_RPC
9764ce7165Smrg#include <pwd.h>
9864ce7165Smrg#include <rpc/rpc.h>
9964ce7165Smrg#ifdef X_POSIX_C_SOURCE
10064ce7165Smrg#define _POSIX_C_SOURCE X_POSIX_C_SOURCE
10164ce7165Smrg#include <limits.h>
10264ce7165Smrg#undef _POSIX_C_SOURCE
10364ce7165Smrg#else
10481440437Smrg#ifdef _POSIX_SOURCE
10564ce7165Smrg#include <limits.h>
10664ce7165Smrg#else
10764ce7165Smrg#define _POSIX_SOURCE
10864ce7165Smrg#include <limits.h>
10964ce7165Smrg#undef _POSIX_SOURCE
11064ce7165Smrg#endif
11164ce7165Smrg#endif
11264ce7165Smrg#ifndef NGROUPS_MAX
11364ce7165Smrg#include <sys/param.h>
11464ce7165Smrg#define NGROUPS_MAX NGROUPS
11564ce7165Smrg#endif
11664ce7165Smrg#ifdef sun
11764ce7165Smrg/* Go figure, there's no getdomainname() prototype available */
11864ce7165Smrgextern int getdomainname(char *name, size_t len);
11964ce7165Smrg#endif
12064ce7165Smrg#endif
12164ce7165Smrg
122b71ad168Smrg#ifdef USE_GETTEXT
123b71ad168Smrg# include <locale.h>	/* setlocale()  */
124b71ad168Smrg# include <libintl.h>	/* gettext(), textdomain(), etc. */
125b71ad168Smrg#else
126b71ad168Smrg# define gettext(a) (a)
127b71ad168Smrg#endif
128b71ad168Smrg
12964ce7165Smrgstatic int change_host(Display *dpy, char *name, Bool add);
1303544ea2eSmrgstatic const char *get_hostname(XHostAddress *ha);
13164ce7165Smrgstatic int local_xerror(Display *dpy, XErrorEvent *rep);
13281440437Smrgstatic void nameserver_lost(int sig);
13364ce7165Smrg
13464ce7165Smrg#define NAMESERVER_TIMEOUT 5	/* time to wait for nameserver */
13564ce7165Smrg
136fb23d3a8Smrgstatic volatile int nameserver_timedout;
137fb23d3a8Smrg
138fb23d3a8Smrgstatic char *ProgramName;
13964ce7165Smrg
14064ce7165Smrg#ifdef NEEDSOCKETS
14164ce7165Smrgstatic int
14264ce7165SmrgXFamily(int af)
14364ce7165Smrg{
14481440437Smrg    unsigned int i;
14564ce7165Smrg    static struct _familyMap {
14664ce7165Smrg	int af, xf;
14764ce7165Smrg    } familyMap[] = {
14864ce7165Smrg#ifdef	AF_DECnet
14964ce7165Smrg        { AF_DECnet, FamilyDECnet },
15064ce7165Smrg#endif
15164ce7165Smrg#ifdef	AF_CHAOS
15264ce7165Smrg        { AF_CHAOS, FamilyChaos },
15364ce7165Smrg#endif
15464ce7165Smrg#ifdef	AF_INET
15564ce7165Smrg        { AF_INET, FamilyInternet },
15664ce7165Smrg#if defined(IPv6) && defined(AF_INET6)
15764ce7165Smrg        { AF_INET6, FamilyInternet6 },
15864ce7165Smrg#endif
15964ce7165Smrg#endif
16064ce7165Smrg};
16164ce7165Smrg
16264ce7165Smrg#define FAMILIES ((sizeof familyMap)/(sizeof familyMap[0]))
16364ce7165Smrg
16464ce7165Smrg    for (i = 0; i < FAMILIES; i++)
16564ce7165Smrg	if (familyMap[i].af == af) return familyMap[i].xf;
16664ce7165Smrg    return -1;
16764ce7165Smrg}
16864ce7165Smrg#endif /* NEEDSOCKETS */
16964ce7165Smrg
170aadd013eSmrg#if defined(__CYGWIN__) || defined(WIN32)
171aadd013eSmrgvoid sethostent(int x)
172aadd013eSmrg{}
173aadd013eSmrg
174aadd013eSmrgvoid endhostent()
175aadd013eSmrg{}
176aadd013eSmrg#endif
177aadd013eSmrg
17864ce7165Smrgint
17964ce7165Smrgmain(int argc, char *argv[])
18064ce7165Smrg{
18164ce7165Smrg    register char *arg;
18264ce7165Smrg    int i, nhosts = 0;
1833544ea2eSmrg    const char *hostname;
18464ce7165Smrg    int nfailed = 0;
18564ce7165Smrg    XHostAddress *list;
18664ce7165Smrg    Bool enabled = False;
18781440437Smrg    Display *dpy;
18864ce7165Smrg
189b71ad168Smrg#ifdef USE_GETTEXT
190b71ad168Smrg    const char *domaindir;
191b71ad168Smrg
192b71ad168Smrg    setlocale(LC_ALL, "");
193b71ad168Smrg    textdomain("xhost");
194b71ad168Smrg
195b71ad168Smrg    /* mainly for debugging */
196b71ad168Smrg    if ((domaindir = getenv("TEXTDOMAINDIR")) == NULL) {
197b71ad168Smrg	domaindir = LOCALEDIR;
198b71ad168Smrg    }
199b71ad168Smrg    bindtextdomain("xhost", domaindir);
200b71ad168Smrg#endif
201b71ad168Smrg
20264ce7165Smrg    ProgramName = argv[0];
20364ce7165Smrg
2043544ea2eSmrg    if (argc == 2 && !strcmp(argv[1], "-help")) {
205b71ad168Smrg	fprintf(stderr, gettext("usage: %s [[+-]hostname ...]\n"), argv[0]);
2063544ea2eSmrg	exit(1);
2073544ea2eSmrg    }
2083544ea2eSmrg
20964ce7165Smrg    if ((dpy = XOpenDisplay(NULL)) == NULL) {
210b71ad168Smrg	fprintf(stderr,
211b71ad168Smrg		gettext("%s:  unable to open display \"%s\"\n"),
21264ce7165Smrg		ProgramName, XDisplayName (NULL));
21364ce7165Smrg	exit(1);
21464ce7165Smrg    }
21564ce7165Smrg
21664ce7165Smrg    XSetErrorHandler(local_xerror);
21764ce7165Smrg
21864ce7165Smrg
21964ce7165Smrg    if (argc == 1) {
22064ce7165Smrg	sethostent(1);		/* don't close the data base each time */
22164ce7165Smrg	list = XListHosts(dpy, &nhosts, &enabled);
22264ce7165Smrg	if (enabled)
223b71ad168Smrg	    printf (gettext("access control enabled, only authorized clients can connect\n"));
22464ce7165Smrg	else
225b71ad168Smrg	    printf (gettext("access control disabled, clients can connect from any host\n"));
22664ce7165Smrg
22764ce7165Smrg	if (nhosts != 0) {
22864ce7165Smrg	    for (i = 0; i < nhosts; i++ )  {
22964ce7165Smrg		hostname = get_hostname(&list[i]);
23064ce7165Smrg		if (hostname) {
23164ce7165Smrg		    switch (list[i].family) {
23264ce7165Smrg		    case FamilyInternet:
23364ce7165Smrg			printf("INET:");
23464ce7165Smrg			break;
23564ce7165Smrg		    case FamilyInternet6:
23664ce7165Smrg			printf("INET6:");
23764ce7165Smrg			break;
23864ce7165Smrg		    case FamilyDECnet:
23964ce7165Smrg			printf("DNET:");
24064ce7165Smrg			break;
24164ce7165Smrg		    case FamilyNetname:
24264ce7165Smrg			printf("NIS:");
24364ce7165Smrg			break;
24464ce7165Smrg		    case FamilyKrb5Principal:
24564ce7165Smrg			printf("KRB:");
24664ce7165Smrg			break;
24764ce7165Smrg		    case FamilyLocalHost:
24864ce7165Smrg			printf("LOCAL:");
24964ce7165Smrg			break;
25064ce7165Smrg		    case FamilyServerInterpreted:
25164ce7165Smrg			printf("SI:");
25264ce7165Smrg			break;
25364ce7165Smrg		    default:
254b71ad168Smrg			printf(gettext("<unknown family type %d>:"), list[i].family);
25564ce7165Smrg			break;
25664ce7165Smrg		    }
25764ce7165Smrg		    printf ("%s", hostname);
25864ce7165Smrg		} else {
259b71ad168Smrg		    printf (gettext("<unknown address in family %d>"),
26064ce7165Smrg			    list[i].family);
26164ce7165Smrg		}
26264ce7165Smrg		if (nameserver_timedout) {
263b71ad168Smrg		    printf(gettext("\t(no nameserver response within %d seconds)\n"),
26464ce7165Smrg			   NAMESERVER_TIMEOUT);
26564ce7165Smrg		    nameserver_timedout = 0;
26664ce7165Smrg		} else
26764ce7165Smrg		    printf("\n");
26864ce7165Smrg	    }
26964ce7165Smrg	    free(list);
27064ce7165Smrg	    endhostent();
27164ce7165Smrg	}
27264ce7165Smrg	exit(0);
27364ce7165Smrg    }
27464ce7165Smrg
27564ce7165Smrg    for (i = 1; i < argc; i++) {
27664ce7165Smrg	arg = argv[i];
27764ce7165Smrg	if (*arg == '-') {
27864ce7165Smrg
27964ce7165Smrg	    if (!argv[i][1] && ((i+1) == argc)) {
280b71ad168Smrg		printf (gettext("access control enabled, only authorized clients can connect\n"));
28164ce7165Smrg		XEnableAccessControl(dpy);
28264ce7165Smrg	    } else {
28364ce7165Smrg		arg = argv[i][1]? &argv[i][1] : argv[++i];
28464ce7165Smrg		if (!change_host (dpy, arg, False)) {
285b71ad168Smrg		    fprintf (stderr, gettext("%s:  bad hostname \"%s\"\n"),
28664ce7165Smrg			     ProgramName, arg);
28764ce7165Smrg		    nfailed++;
28864ce7165Smrg		}
28964ce7165Smrg	    }
29064ce7165Smrg	} else {
29164ce7165Smrg	    if (*arg == '+' && !argv[i][1] && ((i+1) == argc)) {
292b71ad168Smrg		printf (gettext("access control disabled, clients can connect from any host\n"));
29364ce7165Smrg		XDisableAccessControl(dpy);
29464ce7165Smrg	    } else {
29564ce7165Smrg		if (*arg == '+') {
29664ce7165Smrg		    arg = argv[i][1]? &argv[i][1] : argv[++i];
29764ce7165Smrg		}
29864ce7165Smrg		if (!change_host (dpy, arg, True)) {
299b71ad168Smrg		    fprintf (stderr, gettext("%s:  bad hostname \"%s\"\n"),
30064ce7165Smrg			     ProgramName, arg);
30164ce7165Smrg		    nfailed++;
30264ce7165Smrg		}
30364ce7165Smrg	    }
30464ce7165Smrg	}
30564ce7165Smrg    }
30664ce7165Smrg    XCloseDisplay (dpy);	/* does an XSync first */
30764ce7165Smrg    exit(nfailed);
30864ce7165Smrg}
30964ce7165Smrg
31064ce7165Smrg
31164ce7165Smrg
31264ce7165Smrg/*
31364ce7165Smrg * change_host - edit the list of hosts that may connect to the server;
31464ce7165Smrg * it parses DECnet names (expo::), Internet addresses (18.30.0.212), or
31564ce7165Smrg * Internet names (expo.lcs.mit.edu); if 4.3bsd macro h_addr is defined
31664ce7165Smrg * (from <netdb.h>), it will add or remove all addresses with the given
31764ce7165Smrg * address.
31864ce7165Smrg */
31964ce7165Smrg
32064ce7165Smrgstatic int
32164ce7165Smrgchange_host(Display *dpy, char *name, Bool add)
32264ce7165Smrg{
32364ce7165Smrg    XHostAddress ha;
32464ce7165Smrg    char *lname;
32581440437Smrg    size_t namelen, i;
32681440437Smrg    int family = FamilyWild;
32764ce7165Smrg#ifdef K5AUTH
32864ce7165Smrg    krb5_principal princ;
32964ce7165Smrg    krb5_data kbuf;
33064ce7165Smrg#endif
33164ce7165Smrg#ifdef NEEDSOCKETS
33264ce7165Smrg    static struct in_addr addr;	/* so we can point at it */
33364ce7165Smrg#if defined(IPv6) && defined(AF_INET6)
33464ce7165Smrg    static struct in6_addr addr6; /* so we can point at it */
33564ce7165Smrg#else
33664ce7165Smrg    struct hostent *hp;
33764ce7165Smrg#endif
33864ce7165Smrg#endif
33964ce7165Smrg    char *cp;
340b71ad168Smrg    const char *add_msg = gettext("being added to access control list");
341b71ad168Smrg    const char *remove_msg = gettext("being removed from access control list");
34264ce7165Smrg
34364ce7165Smrg    namelen = strlen(name);
34464ce7165Smrg    if ((lname = (char *)malloc(namelen+1)) == NULL) {
345b71ad168Smrg	fprintf (stderr, gettext("%s: malloc bombed in change_host\n"),
346b71ad168Smrg		 ProgramName);
34764ce7165Smrg	exit (1);
34864ce7165Smrg    }
34964ce7165Smrg    for (i = 0; i < namelen; i++) {
35064ce7165Smrg	lname[i] = tolower(name[i]);
35164ce7165Smrg    }
35264ce7165Smrg    lname[namelen] = '\0';
35364ce7165Smrg    if (!strncmp("inet:", lname, 5)) {
35481440437Smrg#ifdef TCPCONN
35564ce7165Smrg	family = FamilyInternet;
35664ce7165Smrg	name += 5;
35764ce7165Smrg#else
358b71ad168Smrg	fprintf (stderr, gettext("%s: not compiled for TCP/IP\n"), ProgramName);
35964ce7165Smrg	free(lname);
36064ce7165Smrg	return 0;
36164ce7165Smrg#endif
36264ce7165Smrg    }
36364ce7165Smrg    else if (!strncmp("inet6:", lname, 6)) {
36481440437Smrg#if defined(TCPCONN) && defined(IPv6) && defined(AF_INET6)
36564ce7165Smrg	family = FamilyInternet6;
36664ce7165Smrg	name += 6;
36764ce7165Smrg#else
368b71ad168Smrg	fprintf (stderr, gettext("%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)) {
37681440437Smrg#if defined(TCPCONN) && defined(IPv6) && defined(AF_INET6)
37764ce7165Smrg	family = FamilyInternet6;
37864ce7165Smrg	name += 7;
37964ce7165Smrg#else
380b71ad168Smrg	fprintf (stderr, gettext("%s: not compiled for IPv6\n"), ProgramName);
38164ce7165Smrg	free(lname);
38264ce7165Smrg	return 0;
38364ce7165Smrg#endif
38464ce7165Smrg    }
38564ce7165Smrg#endif /* ACCEPT_INETV6 */
38664ce7165Smrg    else if (!strncmp("dnet:", lname, 5)) {
387b71ad168Smrg	fprintf (stderr, gettext("%s: not compiled for DECnet\n"), ProgramName);
38864ce7165Smrg	free(lname);
38964ce7165Smrg	return 0;
39064ce7165Smrg    }
39164ce7165Smrg    else if (!strncmp("nis:", lname, 4)) {
39264ce7165Smrg#ifdef SECURE_RPC
39364ce7165Smrg	family = FamilyNetname;
39464ce7165Smrg	name += 4;
39564ce7165Smrg#else
396b71ad168Smrg	fprintf (stderr, gettext("%s: not compiled for Secure RPC\n"), ProgramName);
39764ce7165Smrg	free(lname);
39864ce7165Smrg	return 0;
39964ce7165Smrg#endif
40064ce7165Smrg    }
40164ce7165Smrg    else if (!strncmp("krb:", lname, 4)) {
40264ce7165Smrg#ifdef K5AUTH
40364ce7165Smrg	family = FamilyKrb5Principal;
40464ce7165Smrg	name +=4;
40564ce7165Smrg#else
406b71ad168Smrg	fprintf (stderr, gettext("%s: not compiled for Kerberos 5\n"), ProgramName);
40764ce7165Smrg	free(lname);
40864ce7165Smrg	return 0;
40964ce7165Smrg#endif
41064ce7165Smrg    }
41164ce7165Smrg    else if (!strncmp("local:", lname, 6)) {
41264ce7165Smrg	family = FamilyLocalHost;
41364ce7165Smrg    }
41464ce7165Smrg    else if (!strncmp("si:", lname, 3)) {
41564ce7165Smrg	family = FamilyServerInterpreted;
41664ce7165Smrg	name += 3;
41764ce7165Smrg    }
41864ce7165Smrg    if (family == FamilyWild && (cp = strchr(lname, ':'))) {
419b71ad168Smrg#ifdef IPv6
420b71ad168Smrg	/*
421b71ad168Smrg	 * Check to see if inet_pton() can grok it as an IPv6 address
422b71ad168Smrg	 */
423b71ad168Smrg	if (inet_pton(AF_INET6, lname, &addr6.s6_addr) == 1) {
424b71ad168Smrg	    family = FamilyInternet6;
425b71ad168Smrg	} else
426b71ad168Smrg#endif
427b71ad168Smrg	{
428b71ad168Smrg	    *cp = '\0';
429b71ad168Smrg	    fprintf (stderr, gettext("%s: unknown address family \"%s\"\n"),
430b71ad168Smrg		     ProgramName, lname);
431b71ad168Smrg	    free(lname);
432b71ad168Smrg	    return 0;
433b71ad168Smrg	}
43464ce7165Smrg    }
43564ce7165Smrg    free(lname);
43664ce7165Smrg
43764ce7165Smrg    if (family == FamilyServerInterpreted) {
43864ce7165Smrg	XServerInterpretedAddress siaddr;
4393544ea2eSmrg	int rc;
44064ce7165Smrg
44164ce7165Smrg	cp = strchr(name, ':');
44264ce7165Smrg	if (cp == NULL || cp == name) {
443b71ad168Smrg	    fprintf(stderr, gettext(
444b71ad168Smrg	  "%s: type must be specified for server interpreted family \"%s\"\n"),
44564ce7165Smrg	      ProgramName, name);
44664ce7165Smrg	    return 0;
44764ce7165Smrg	}
4483544ea2eSmrg	siaddr.type = name;
4493544ea2eSmrg	siaddr.typelength = cp - name;
4503544ea2eSmrg	siaddr.value = ++cp;
4513544ea2eSmrg	siaddr.valuelength = strlen(cp);
45264ce7165Smrg	ha.family = FamilyServerInterpreted;
45364ce7165Smrg	ha.address = (char *) &siaddr;
45464ce7165Smrg	if (add)
4553544ea2eSmrg	    rc = XAddHost(dpy, &ha);
45664ce7165Smrg	else
4573544ea2eSmrg	    rc = XRemoveHost(dpy, &ha);
4583544ea2eSmrg	printf( "%s %s%s\n", name, rc == 1 ? "" : "failed when ",
4593544ea2eSmrg		add ? add_msg : remove_msg);
4603544ea2eSmrg	if (rc != 1)
4613544ea2eSmrg	    return 0;
46264ce7165Smrg	return 1;
46364ce7165Smrg    }
46464ce7165Smrg
46564ce7165Smrg#ifdef K5AUTH
46664ce7165Smrg    if (family == FamilyKrb5Principal) {
46764ce7165Smrg	krb5_error_code retval;
46864ce7165Smrg
46964ce7165Smrg	retval = krb5_parse_name(name, &princ);
47064ce7165Smrg	if (retval) {
47164ce7165Smrg	    krb5_init_ets();	/* init krb errs for error_message() */
472b71ad168Smrg	    fprintf(stderr, gettext("%s: cannot parse Kerberos name: %s\n"),
47364ce7165Smrg		    ProgramName, error_message(retval));
47464ce7165Smrg	    return 0;
47564ce7165Smrg	}
47664ce7165Smrg	XauKrb5Encode(princ, &kbuf);
47764ce7165Smrg	ha.length = kbuf.length;
47864ce7165Smrg	ha.address = kbuf.data;
47964ce7165Smrg	ha.family = family;
48064ce7165Smrg	if (add)
48164ce7165Smrg	    XAddHost(dpy, &ha);
48264ce7165Smrg	else
48364ce7165Smrg	    XRemoveHost(dpy, &ha);
48464ce7165Smrg	krb5_free_principal(princ);
48564ce7165Smrg	free(kbuf.data);
48664ce7165Smrg	printf( "%s %s\n", name, add ? add_msg : remove_msg);
48764ce7165Smrg	return 1;
48864ce7165Smrg    }
48964ce7165Smrg#endif
49064ce7165Smrg    if (family == FamilyLocalHost) {
49181440437Smrg	char empty[] = "";
49264ce7165Smrg	ha.length = 0;
49381440437Smrg	ha.address = empty;
49464ce7165Smrg	ha.family = family;
49564ce7165Smrg	if (add)
49664ce7165Smrg	    XAddHost(dpy, &ha);
49764ce7165Smrg	else
49864ce7165Smrg	    XRemoveHost(dpy, &ha);
499b71ad168Smrg	printf( gettext("non-network local connections %s\n"), add ? add_msg : remove_msg);
50064ce7165Smrg	return 1;
50164ce7165Smrg    }
50264ce7165Smrg    /*
50364ce7165Smrg     * If it has an '@', it's a netname
50464ce7165Smrg     */
50564ce7165Smrg    if ((family == FamilyNetname && (cp = strchr(name, '@'))) ||
50664ce7165Smrg	(cp = strchr(name, '@'))) {
50764ce7165Smrg        char *netname = name;
50864ce7165Smrg#ifdef SECURE_RPC
50964ce7165Smrg	static char username[MAXNETNAMELEN];
51064ce7165Smrg
51164ce7165Smrg	if (!cp[1]) {
51264ce7165Smrg	    struct passwd *pwd;
51364ce7165Smrg	    static char domainname[128];
51464ce7165Smrg
51564ce7165Smrg	    *cp = '\0';
51664ce7165Smrg	    pwd = getpwnam(name);
51764ce7165Smrg	    if (!pwd) {
518b71ad168Smrg		fprintf(stderr, gettext("no such user \"%s\"\n"), name);
51964ce7165Smrg		return 0;
52064ce7165Smrg	    }
52164ce7165Smrg	    getdomainname(domainname, sizeof(domainname));
52264ce7165Smrg	    if (!user2netname(username, pwd->pw_uid, domainname)) {
523b71ad168Smrg		fprintf(stderr, gettext("failed to get netname for \"%s\"\n"), name);
52464ce7165Smrg		return 0;
52564ce7165Smrg	    }
52664ce7165Smrg	    netname = username;
52764ce7165Smrg	}
52864ce7165Smrg#endif
52964ce7165Smrg	ha.family = FamilyNetname;
53064ce7165Smrg	ha.length = strlen(netname);
53164ce7165Smrg	ha.address = netname;
53264ce7165Smrg	if (add)
53364ce7165Smrg	    XAddHost (dpy, &ha);
53464ce7165Smrg	else
53564ce7165Smrg	    XRemoveHost (dpy, &ha);
53664ce7165Smrg	if (netname != name)
53764ce7165Smrg	    printf ("%s@ (%s) %s\n", name, netname, add ? add_msg : remove_msg);
53864ce7165Smrg	else
53964ce7165Smrg	    printf ("%s %s\n", netname, add ? add_msg : remove_msg);
54064ce7165Smrg        return 1;
54164ce7165Smrg    }
54264ce7165Smrg#ifdef NEEDSOCKETS
54364ce7165Smrg    /*
544aadd013eSmrg     * First see if inet_aton/inet_addr can grok the name; if so, then use it.
54564ce7165Smrg     */
54664ce7165Smrg    if (((family == FamilyWild) || (family == FamilyInternet)) &&
547aadd013eSmrg#ifdef HAVE_INET_ATON
548aadd013eSmrg	(inet_aton (name, &addr) != 0)
549aadd013eSmrg#else
550aadd013eSmrg	((addr.s_addr = inet_addr(name)) != -1)
551aadd013eSmrg#endif
552aadd013eSmrg        ) {
55364ce7165Smrg	ha.family = FamilyInternet;
554aadd013eSmrg	ha.length = sizeof(addr.s_addr);
555aadd013eSmrg	ha.address = (char *) &addr.s_addr;
55664ce7165Smrg	if (add) {
55764ce7165Smrg	    XAddHost (dpy, &ha);
55864ce7165Smrg	    printf ("%s %s\n", name, add_msg);
55964ce7165Smrg	} else {
56064ce7165Smrg	    XRemoveHost (dpy, &ha);
56164ce7165Smrg	    printf ("%s %s\n", name, remove_msg);
56264ce7165Smrg	}
56364ce7165Smrg	return 1;
56464ce7165Smrg    }
56564ce7165Smrg#if defined(IPv6) && defined(AF_INET6)
56664ce7165Smrg    /*
56764ce7165Smrg     * Check to see if inet_pton() can grok it as an IPv6 address
56864ce7165Smrg     */
56964ce7165Smrg    else if (((family == FamilyWild) || (family == FamilyInternet6)) &&
57064ce7165Smrg	     (inet_pton(AF_INET6, name, &addr6.s6_addr) == 1)) {
57164ce7165Smrg	ha.family = FamilyInternet6;
57264ce7165Smrg	ha.length = sizeof(addr6.s6_addr);
57364ce7165Smrg	ha.address = (char *) &addr6.s6_addr;
57464ce7165Smrg	if (add) {
57564ce7165Smrg	    XAddHost (dpy, &ha);
57664ce7165Smrg	    printf ("%s %s\n", name, add_msg);
57764ce7165Smrg	} else {
57864ce7165Smrg	    XRemoveHost (dpy, &ha);
57964ce7165Smrg	    printf ("%s %s\n", name, remove_msg);
58064ce7165Smrg	}
58164ce7165Smrg	return 1;
58264ce7165Smrg    } else {
58364ce7165Smrg    /*
58464ce7165Smrg     * Is it in the namespace?
58564ce7165Smrg     *
58664ce7165Smrg     * If no family was specified, use both Internet v4 & v6 addresses.
58764ce7165Smrg     * Otherwise, use only addresses matching specified family.
58864ce7165Smrg     */
58964ce7165Smrg	struct addrinfo *addresses;
59064ce7165Smrg	struct addrinfo *a;
59164ce7165Smrg	Bool didit = False;
59264ce7165Smrg
59364ce7165Smrg	if (getaddrinfo(name, NULL, NULL, &addresses) != 0)
59464ce7165Smrg	    return 0;
59564ce7165Smrg
59664ce7165Smrg	for (a = addresses; a != NULL; a = a->ai_next) {
59764ce7165Smrg	    if ( ((a->ai_family == AF_INET) && (family != FamilyInternet6))
59864ce7165Smrg	      || ((a->ai_family == AF_INET6) && (family != FamilyInternet)) ) {
59964ce7165Smrg		char ad[INET6_ADDRSTRLEN];
60064ce7165Smrg		ha.family = XFamily(a->ai_family);
60164ce7165Smrg		if (a->ai_family == AF_INET6) {
60264ce7165Smrg		    ha.address = (char *)
60364ce7165Smrg		      &((struct sockaddr_in6 *) a->ai_addr)->sin6_addr;
60464ce7165Smrg		    ha.length =
60564ce7165Smrg		      sizeof (((struct sockaddr_in6 *) a->ai_addr)->sin6_addr);
60664ce7165Smrg		} else {
60764ce7165Smrg		    ha.address = (char *)
60864ce7165Smrg		      &((struct sockaddr_in *) a->ai_addr)->sin_addr;
60964ce7165Smrg		    ha.length =
61064ce7165Smrg		      sizeof (((struct sockaddr_in *) a->ai_addr)->sin_addr);
61164ce7165Smrg		}
61264ce7165Smrg		inet_ntop(a->ai_family, ha.address, ad, sizeof(ad));
61364ce7165Smrg	/* printf("Family: %d\nLength: %d\n", a->ai_family, ha.length); */
61464ce7165Smrg		/* printf("Address: %s\n", ad); */
61564ce7165Smrg
61664ce7165Smrg		if (add) {
61764ce7165Smrg		    XAddHost (dpy, &ha);
61864ce7165Smrg		} else {
61964ce7165Smrg		    XRemoveHost (dpy, &ha);
62064ce7165Smrg		}
62164ce7165Smrg		didit = True;
62264ce7165Smrg	    }
62364ce7165Smrg	}
62464ce7165Smrg	if (didit == True) {
62564ce7165Smrg	    printf ("%s %s\n", name, add ? add_msg : remove_msg);
62664ce7165Smrg	} else {
62764ce7165Smrg	    const char *familyMsg = "";
62864ce7165Smrg
62964ce7165Smrg	    if (family == FamilyInternet6) {
63064ce7165Smrg		familyMsg = "inet6 ";
63164ce7165Smrg	    } else if (family == FamilyInternet) {
63264ce7165Smrg		familyMsg = "inet ";
63364ce7165Smrg	    }
63464ce7165Smrg
635b71ad168Smrg	    fprintf(stderr, gettext("%s: unable to get %saddress for \"%s\"\n"),
63664ce7165Smrg		ProgramName, familyMsg, name);
63764ce7165Smrg	}
63864ce7165Smrg	freeaddrinfo(addresses);
63964ce7165Smrg	return 1;
64064ce7165Smrg    }
64164ce7165Smrg#else /* !IPv6 */
64264ce7165Smrg    /*
64364ce7165Smrg     * Is it in the namespace?
64464ce7165Smrg     */
64564ce7165Smrg    else if (((hp = gethostbyname(name)) == (struct hostent *)NULL)
64664ce7165Smrg	     || hp->h_addrtype != AF_INET) {
64764ce7165Smrg	return 0;
64864ce7165Smrg    } else {
64964ce7165Smrg	ha.family = XFamily(hp->h_addrtype);
65064ce7165Smrg	ha.length = hp->h_length;
65164ce7165Smrg#ifdef h_addr			/* new 4.3bsd version of gethostent */
65264ce7165Smrg    {
65364ce7165Smrg	char **list;
65464ce7165Smrg
65564ce7165Smrg	/* iterate over the hosts */
65664ce7165Smrg	for (list = hp->h_addr_list; *list; list++) {
65764ce7165Smrg	    ha.address = *list;
65864ce7165Smrg	    if (add) {
65964ce7165Smrg		XAddHost (dpy, &ha);
66064ce7165Smrg	    } else {
66164ce7165Smrg		XRemoveHost (dpy, &ha);
66264ce7165Smrg	    }
66364ce7165Smrg	}
66464ce7165Smrg    }
66564ce7165Smrg#else
66664ce7165Smrg	ha.address = hp->h_addr;
66764ce7165Smrg	if (add) {
66864ce7165Smrg	    XAddHost (dpy, &ha);
66964ce7165Smrg	} else {
67064ce7165Smrg	    XRemoveHost (dpy, &ha);
67164ce7165Smrg	}
67264ce7165Smrg#endif
67364ce7165Smrg	printf ("%s %s\n", name, add ? add_msg : remove_msg);
67464ce7165Smrg	return 1;
67564ce7165Smrg    }
67664ce7165Smrg#endif /* IPv6 */
67764ce7165Smrg#else /* NEEDSOCKETS */
67864ce7165Smrg    return 0;
67964ce7165Smrg#endif /* NEEDSOCKETS */
68064ce7165Smrg}
68164ce7165Smrg
68264ce7165Smrg
68364ce7165Smrg/*
68464ce7165Smrg * get_hostname - Given an internet address, return a name (CHARON.MIT.EDU)
68564ce7165Smrg * or a string representing the address (18.58.0.13) if the name cannot
68664ce7165Smrg * be found.
68764ce7165Smrg */
68864ce7165Smrg
68964ce7165Smrg
6903544ea2eSmrgstatic const char *
69164ce7165Smrgget_hostname(XHostAddress *ha)
69264ce7165Smrg{
69381440437Smrg#if defined(TCPCONN) && (!defined(IPv6) || !defined(AF_INET6))
69464ce7165Smrg    static struct hostent *hp = NULL;
69564ce7165Smrg#endif
69664ce7165Smrg#ifdef K5AUTH
69764ce7165Smrg    krb5_principal princ;
69864ce7165Smrg    krb5_data kbuf;
69964ce7165Smrg    char *kname;
70064ce7165Smrg    static char kname_out[255];
70164ce7165Smrg#endif
70281440437Smrg#ifdef SIGALRM
70364ce7165Smrg    struct sigaction sa;
70464ce7165Smrg#endif
70564ce7165Smrg
70681440437Smrg#ifdef TCPCONN
70764ce7165Smrg#if defined(IPv6) && defined(AF_INET6)
70864ce7165Smrg    if ((ha->family == FamilyInternet) || (ha->family == FamilyInternet6)) {
70964ce7165Smrg	struct sockaddr_storage saddr;
71064ce7165Smrg	static char inetname[NI_MAXHOST];
71181440437Smrg	unsigned int saddrlen;
71264ce7165Smrg
71364ce7165Smrg	inetname[0] = '\0';
71464ce7165Smrg	memset(&saddr, 0, sizeof saddr);
71564ce7165Smrg	if (ha->family == FamilyInternet) {
71664ce7165Smrg	    struct sockaddr_in *sin = (struct sockaddr_in *) &saddr;
71764ce7165Smrg#ifdef BSD44SOCKETS
71864ce7165Smrg	    sin->sin_len = sizeof(struct sockaddr_in);
71964ce7165Smrg#endif
72064ce7165Smrg	    sin->sin_family = AF_INET;
72164ce7165Smrg	    sin->sin_port = 0;
722aadd013eSmrg	    if (sizeof(sin->sin_addr) > ha->length)
723aadd013eSmrg		return "";
72464ce7165Smrg	    memcpy(&sin->sin_addr, ha->address, sizeof(sin->sin_addr));
72564ce7165Smrg	    saddrlen = sizeof(struct sockaddr_in);
72664ce7165Smrg	} else {
72764ce7165Smrg	    struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &saddr;
72864ce7165Smrg#ifdef SIN6_LEN
72964ce7165Smrg	    sin6->sin6_len = sizeof(struct sockaddr_in6);
73064ce7165Smrg#endif
73164ce7165Smrg	    sin6->sin6_family = AF_INET6;
73264ce7165Smrg	    sin6->sin6_port = 0;
733aadd013eSmrg	    if (sizeof(sin6->sin6_addr) > ha->length)
734aadd013eSmrg		return "";
73564ce7165Smrg	    memcpy(&sin6->sin6_addr, ha->address, sizeof(sin6->sin6_addr));
73664ce7165Smrg	    saddrlen = sizeof(struct sockaddr_in6);
73764ce7165Smrg	}
73864ce7165Smrg
73964ce7165Smrg	/* gethostbyaddr can take a LONG time if the host does not exist.
74064ce7165Smrg	   Assume that if it does not respond in NAMESERVER_TIMEOUT seconds
74164ce7165Smrg	   that something is wrong and do not make the user wait.
74264ce7165Smrg	   gethostbyaddr will continue after a signal, so we have to
74364ce7165Smrg	   jump out of it.
74464ce7165Smrg	   */
74581440437Smrg#ifdef SIGALRM
74664ce7165Smrg	memset(&sa, 0, sizeof sa);
74764ce7165Smrg	sa.sa_handler = nameserver_lost;
74864ce7165Smrg	sa.sa_flags = 0;	/* don't restart syscalls */
74964ce7165Smrg	sigaction(SIGALRM, &sa, NULL);
75064ce7165Smrg	alarm(NAMESERVER_TIMEOUT);
75164ce7165Smrg#endif
75281440437Smrg	getnameinfo((struct sockaddr *) &saddr, saddrlen, inetname,
75381440437Smrg		    sizeof(inetname), NULL, 0, 0);
75481440437Smrg#ifdef SIGALRM
75564ce7165Smrg	alarm(0);
75681440437Smrg#endif
75764ce7165Smrg	if (nameserver_timedout || inetname[0] == '\0')
75864ce7165Smrg	    inet_ntop(((struct sockaddr *)&saddr)->sa_family, ha->address,
75964ce7165Smrg		inetname, sizeof(inetname));
76064ce7165Smrg	return inetname;
76164ce7165Smrg    }
76264ce7165Smrg#else
76364ce7165Smrg    if (ha->family == FamilyInternet) {
76464ce7165Smrg	/* gethostbyaddr can take a LONG time if the host does not exist.
76564ce7165Smrg	   Assume that if it does not respond in NAMESERVER_TIMEOUT seconds
76664ce7165Smrg	   that something is wrong and do not make the user wait.
76764ce7165Smrg	   gethostbyaddr will continue after a signal, so we have to
76864ce7165Smrg	   jump out of it.
76964ce7165Smrg	   */
77081440437Smrg#ifdef SIGALRM
77164ce7165Smrg	memset(&sa, 0, sizeof sa);
77264ce7165Smrg	sa.sa_handler = nameserver_lost;
77364ce7165Smrg	sa.sa_flags = 0;	/* don't restart syscalls */
77464ce7165Smrg	sigaction(SIGALRM, &sa, NULL);
77564ce7165Smrg	alarm(4);
77664ce7165Smrg#endif
77781440437Smrg	hp = gethostbyaddr (ha->address, ha->length, AF_INET);
77881440437Smrg#ifdef SIGALRM
77964ce7165Smrg	alarm(0);
78081440437Smrg#endif
78164ce7165Smrg	if (hp)
78264ce7165Smrg	    return (hp->h_name);
78364ce7165Smrg	else return (inet_ntoa(*((struct in_addr *)(ha->address))));
78464ce7165Smrg    }
78564ce7165Smrg#endif /* IPv6 */
78664ce7165Smrg#endif
78764ce7165Smrg    if (ha->family == FamilyNetname) {
78864ce7165Smrg	static char netname[512];
78964ce7165Smrg	int len;
79064ce7165Smrg#ifdef SECURE_RPC
79164ce7165Smrg	int gidlen;
79264ce7165Smrg	uid_t uid;
79364ce7165Smrg	gid_t gid, gidlist[NGROUPS_MAX];
79464ce7165Smrg#endif
79564ce7165Smrg
79664ce7165Smrg	if (ha->length < sizeof(netname) - 1)
79764ce7165Smrg	    len = ha->length;
79864ce7165Smrg	else
79964ce7165Smrg	    len = sizeof(netname) - 1;
80064ce7165Smrg	memmove( netname, ha->address, len);
80164ce7165Smrg	netname[len] = '\0';
80264ce7165Smrg#ifdef SECURE_RPC
80364ce7165Smrg	if (netname2user(netname, &uid, &gid, &gidlen, gidlist)) {
80464ce7165Smrg	    struct passwd *pwd;
80564ce7165Smrg
80664ce7165Smrg	    pwd = getpwuid(uid);
80764ce7165Smrg	    if (pwd)
80881440437Smrg		snprintf(netname, sizeof(netname), "%s@ (%*.*s)",
80981440437Smrg			 pwd->pw_name, ha->length, ha->length, ha->address);
81064ce7165Smrg	}
81164ce7165Smrg#endif
81264ce7165Smrg	return (netname);
81364ce7165Smrg    }
81464ce7165Smrg#ifdef K5AUTH
81564ce7165Smrg    if (ha->family == FamilyKrb5Principal) {
81664ce7165Smrg	kbuf.data = ha->address;
81764ce7165Smrg	kbuf.length = ha->length;
81864ce7165Smrg	XauKrb5Decode(kbuf, &princ);
81964ce7165Smrg	krb5_unparse_name(princ, &kname);
82064ce7165Smrg	krb5_free_principal(princ);
82164ce7165Smrg	strncpy(kname_out, kname, sizeof (kname_out));
82264ce7165Smrg	free(kname);
82364ce7165Smrg	return kname_out;
82464ce7165Smrg    }
82564ce7165Smrg#endif
82664ce7165Smrg    if (ha->family == FamilyLocalHost) {
82764ce7165Smrg	return "";
82864ce7165Smrg    }
82964ce7165Smrg    if (ha->family == FamilyServerInterpreted) {
83064ce7165Smrg	XServerInterpretedAddress *sip;
83164ce7165Smrg	static char *addressString;
83264ce7165Smrg	static size_t addressStringSize;
83364ce7165Smrg	size_t neededSize;
83464ce7165Smrg
83564ce7165Smrg	sip = (XServerInterpretedAddress *) ha->address;
83664ce7165Smrg	neededSize = sip->typelength + sip->valuelength + 2;
83764ce7165Smrg
83864ce7165Smrg	if (addressStringSize < neededSize) {
83964ce7165Smrg	    if (addressString != NULL) {
84064ce7165Smrg		free(addressString);
84164ce7165Smrg	    }
84264ce7165Smrg	    addressStringSize = neededSize;
84364ce7165Smrg	    addressString = malloc(addressStringSize);
84464ce7165Smrg	}
84564ce7165Smrg	if (addressString != NULL) {
84664ce7165Smrg	    char *cp = addressString;
84764ce7165Smrg
84864ce7165Smrg	    memcpy(cp, sip->type, sip->typelength);
84964ce7165Smrg	    cp += sip->typelength;
85064ce7165Smrg	    *cp++ = ':';
85164ce7165Smrg	    memcpy(cp, sip->value, sip->valuelength);
85264ce7165Smrg	    cp += sip->valuelength;
85364ce7165Smrg	    *cp = '\0';
85464ce7165Smrg	}
85564ce7165Smrg	return addressString;
85664ce7165Smrg    }
85764ce7165Smrg    return (NULL);
85864ce7165Smrg}
85964ce7165Smrg
86064ce7165Smrg/*ARGUSED*/
86181440437Smrgstatic void
86281440437Smrgnameserver_lost(_X_UNUSED int sig)
86364ce7165Smrg{
86464ce7165Smrg    nameserver_timedout = 1;
86564ce7165Smrg}
86664ce7165Smrg
86764ce7165Smrg/*
86864ce7165Smrg * local_xerror - local non-fatal error handling routine. If the error was
86964ce7165Smrg * that an X_GetHosts request for an unknown address format was received, just
87064ce7165Smrg * return, otherwise print the normal error message and continue.
87164ce7165Smrg */
87264ce7165Smrgstatic int
87364ce7165Smrglocal_xerror(Display *dpy, XErrorEvent *rep)
87464ce7165Smrg{
87564ce7165Smrg    if ((rep->error_code == BadAccess) && (rep->request_code == X_ChangeHosts)) {
87664ce7165Smrg	fprintf (stderr,
877b71ad168Smrg		 gettext("%s:  must be on local machine to add or remove hosts.\n"),
87864ce7165Smrg		 ProgramName);
87964ce7165Smrg	return 1;
88064ce7165Smrg    } else if ((rep->error_code == BadAccess) &&
88164ce7165Smrg	       (rep->request_code == X_SetAccessControl)) {
88264ce7165Smrg	fprintf (stderr,
883b71ad168Smrg		 gettext("%s:  must be on local machine to enable or disable access control.\n"),
88464ce7165Smrg		 ProgramName);
88564ce7165Smrg	return 1;
88664ce7165Smrg    } else if ((rep->error_code == BadValue) &&
88764ce7165Smrg	       (rep->request_code == X_ListHosts)) {
88864ce7165Smrg	return 1;
88964ce7165Smrg    }
89064ce7165Smrg
89164ce7165Smrg    XmuPrintDefaultErrorMessage (dpy, rep, stderr);
89264ce7165Smrg    return 0;
89364ce7165Smrg}
894