|
|
1.1 root 1: /*
2:
3: Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
4:
5: Permission to use, copy, modify, and distribute this
6: software and its documentation for any purpose and without
7: fee is hereby granted, provided that the above copyright
8: notice appear in all copies and that both that copyright
9: notice and this permission notice appear in supporting
10: documentation, and that the name of M.I.T. not be used in
11: advertising or publicity pertaining to distribution of the
12: software without specific, written prior permission.
13: M.I.T. makes no representations about the suitability of
14: this software for any purpose. It is provided "as is"
15: without express or implied warranty.
16:
17: */
18:
19: #ifndef lint
20: static char *rcsid_xhost_c = "$Header: xhost.c,v 11.11 87/08/26 21:14:06 toddb Exp $";
21: #endif
22:
23: #include <signal.h>
24: #include <setjmp.h>
25: #include <ctype.h>
26: #include <sys/types.h>
27: #include <sys/socket.h>
28: #include <stdio.h>
29: #include <netdb.h>
30: #include <netinet/in.h>
31: #ifdef notdef
32: #include <arpa/inet.h>
33: bogus definition of inet_makeaddr() in BSD 4.2 and Ultrix
34: #else
35: extern unsigned long inet_makeaddr();
36: #endif
37: #ifdef DNETCONN
38: #include <netdnet/dn.h>
39: #include <netdnet/dnetdb.h>
40: #endif
41: #include <X11/Xlib.h>
42: #include <X11/Xproto.h>
43:
44: char *index();
45: int local_xerror();
46:
47: #define NAMESERVER_TIMEOUT 5 /* time to wait for nameserver */
48:
49: typedef struct {
50: int af, xf;
51: } FamilyMap;
52:
53: static FamilyMap familyMap[] = {
54: #ifdef AF_DECnet
55: {AF_DECnet, FamilyDECnet},
56: #endif
57: #ifdef AF_CHAOS
58: {AF_CHAOS, FamilyChaos},
59: #endif
60: #ifdef AF_INET
61: {AF_INET, FamilyInternet}
62: #endif
63: };
64:
65: #define FAMILIES ((sizeof familyMap)/(sizeof familyMap[0]))
66:
67: int nameserver_timedout;
68:
69: static int XFamily(af)
70: int af;
71: {
72: int i;
73: for (i = 0; i < FAMILIES; i++)
74: if (familyMap[i].af == af)
75: return familyMap[i].xf;
76: return -1;
77: }
78:
79: main(argc, argv)
80: int argc;
81: char **argv;
82: {
83: Display *dpy;
84: char host[256];
85: register char *arg;
86: int display, i, w, nhosts;
87: XHostAddress *address, *get_address();
88: char *hostname, *get_hostname();
89: XHostAddress *list;
90: Bool enabled = False;
91: #ifdef DNETCONN
92: char *dnet_htoa();
93: struct nodeent *np;
94: struct dn_naddr *nlist, dnaddr, *dnaddrp, *dnet_addr();
95: char *cp, *index();
96: #endif
97:
98: if ((dpy = XOpenDisplay(NULL)) == NULL) {
99: fprintf(stderr, "%s: Can't open display /* '%s' */\n",
100: argv[0]/*, XDisplayName("\0")*/);
101: exit(1);
102: }
103:
104: XSetCloseDownMode(dpy, RetainPermanent);
105:
106: XSetErrorHandler(local_xerror);
107:
108:
109: if (argc == 1) {
110: #ifdef DNETCONN
111: setnodeent(1); /* keep the database accessed */
112: #endif
113: sethostent(1); /* don't close the data base each time */
114: list = XListHosts(dpy, &nhosts, &enabled);
115: printf ("Host Access Control %s.\n",
116: enabled ? "enabled": "disabled");
117: if (nhosts != 0) {
118: for (i = 0; i < nhosts; i++ ) {
119: hostname = get_hostname(&list[i]);
120: printf("%s\t", hostname);
121: if (nameserver_timedout)
122: printf("(nameserver did not respond in %d seconds)\n",
123: NAMESERVER_TIMEOUT);
124: else printf("\n");
125: }
126: free(list);
127: endhostent();
128: }
129: exit(0);
130: }
131:
132: for (i = 1; i < argc; i++) {
133: arg = argv[i];
134: if (*arg == '-') {
135:
136: if (!argv[i][1] && ((i+1) == argc))
137: XEnableAccessControl(dpy);
138: else {
139: arg = argv[i][1]? &argv[i][1] : argv[++i];
140: if ((address = get_address(arg)) == NULL)
141: fprintf(stderr, "%s: bad host: %s\n", argv[0], arg);
142: else XRemoveHost(dpy, address);
143: }
144: } else {
145: if (*arg == '+' && !argv[i][1] && ((i+1) == argc))
146: XDisableAccessControl(dpy);
147: else {
148: if (*arg == '+') {
149: arg = argv[i][1]? &argv[i][1] : argv[++i];
150: }
151: if ((address = get_address(arg)) == NULL)
152: fprintf(stderr, "%s: bad host: %s\n", argv[0], arg);
153: else XAddHost(dpy, address);
154: }
155: }
156: }
157: XCloseDisplay (dpy); /* does an XSync first */
158: exit(0);
159: }
160:
161:
162:
163: /*
164: * get_address - return a pointer to an internet address given
165: * either a name (CHARON.MIT.EDU) or a string with the raw
166: * address (18.58.0.13)
167: */
168:
169: XHostAddress *get_address (name)
170: char *name;
171: {
172: struct hostent *hp;
173: static XHostAddress ha;
174: static struct in_addr addr; /* so we can point at it */
175: #ifdef DNETCONN
176: struct dn_naddr *dnaddrp;
177: struct nodeent *np;
178: char *cp, *index();
179: static struct dn_naddr dnaddr;
180: #endif /* DNETCONN */
181:
182: #ifdef DNETCONN
183: if ((cp = index (name, ':')) && (*(cp + 1) == ':')) {
184: *cp = '\0';
185: ha.family = FamilyDECnet;
186: if (dnaddrp = dnet_addr(name)) {
187: dnaddr = *dnaddrp;
188: } else {
189: if ((np = getnodebyname (name)) == NULL)
190: return (NULL);
191: dnaddr.a_len = np->n_length;
192: bcopy (np->n_addr, dnaddr.a_addr, np->n_length);
193: }
194: ha.length = sizeof(struct dn_naddr);
195: ha.address = (char *)&dnaddr;
196: return(&ha); /* Found it */
197: }
198: #endif /* DNETCONN */
199: /*
200: * First see if inet_addr() can grok the name; if so, then use it.
201: */
202: if ((addr.s_addr = inet_addr(name)) != -1) {
203: ha.family = FamilyInternet;
204: ha.length = sizeof(addr.s_addr);
205: ha.address = (char *)&addr.s_addr;
206: return(&ha); /* Found it */
207: }
208: /*
209: * Is it in the namespace?
210: */
211: else if (((hp = gethostbyname(name)) == (struct hostent *)NULL)
212: || hp->h_addrtype != AF_INET) {
213: return (NULL); /* Sorry, you lose */
214: } else {
215: ha.family = XFamily(hp->h_addrtype);
216: ha.length = hp->h_length;
217: ha.address = hp->h_addr;
218: return (&ha); /* Found it. */
219: }
220: }
221:
222:
223: /*
224: * get_hostname - Given an internet address, return a name (CHARON.MIT.EDU)
225: * or a string representing the address (18.58.0.13) if the name cannot
226: * be found.
227: */
228:
229: jmp_buf env;
230:
231: char *get_hostname (ha)
232: XHostAddress *ha;
233: {
234: struct hostent *hp = NULL;
235: int nameserver_lost();
236: char *inet_ntoa();
237: #ifdef DNETCONN
238: struct nodeent *np;
239: static char nodeaddr[16];
240: #endif /* DNETCONN */
241:
242: if (ha->family == FamilyInternet) {
243: /* gethostbyaddr can take a LONG time if the host does not exist.
244: Assume that if it does not respond in NAMESERVER_TIMEOUT seconds
245: that something is wrong and do not make the user wait.
246: gethostbyaddr will continue after a signal, so we have to
247: jump out of it.
248: */
249: nameserver_timedout = 0;
250: signal(SIGALRM, nameserver_lost);
251: alarm(4);
252: if (setjmp(env) == 0) {
253: hp = gethostbyaddr (ha->address, ha->length, AF_INET);
254: }
255: alarm(0);
256: if (hp)
257: return (hp->h_name);
258: else return (inet_ntoa(*((int *)ha->address)));
259: }
260: #ifdef DNETCONN
261: if (ha->family == FamilyDECnet) {
262: if (np = getnodebyaddr(ha->address, ha->length, AF_DECnet)) {
263: sprintf(nodeaddr, "%s::", np->n_name);
264: } else {
265: sprintf(nodeaddr, "%s::", dnet_htoa(ha->address));
266: }
267: return(nodeaddr);
268: }
269: #endif
270:
271: return (NULL);
272: }
273:
274: nameserver_lost()
275: {
276: nameserver_timedout = 1;
277: longjmp(env, -1);
278: }
279:
280: /*
281: * local_xerror - local non-fatal error handling routine. If the error was
282: * that an X_GetHosts request for an unknown address format was received, just
283: * return, otherwise call the default error handler _XDefaultError.
284: */
285: local_xerror (dpy, rep)
286: Display *dpy;
287: XErrorEvent *rep;
288: {
289: if ((rep->error_code == BadValue) && (rep->request_code == X_ListHosts)) {
290: return;
291: } else {
292: _XDefaultError(dpy, rep);
293: }
294: }
295:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.