~ubuntu-branches/ubuntu/karmic/x11-xserver-utils/karmic

« back to all changes in this revision

Viewing changes to xhost/xhost.c

  • Committer: Bazaar Package Importer
  • Author(s): Brice Goglin, Julien Cristau, Brice Goglin
  • Date: 2007-08-17 09:58:34 UTC
  • Revision ID: james.westby@ubuntu.com-20070817095834-ywge2nyzj1s3rqnd
Tags: 7.3+1
[ Julien Cristau ]
* iceauth 1.0.2.
  + removes blank line in the manpage (closes: #25285).
* xmodmap 1.0.3.
  + manpage updated to state that -pm is the default (closes: #236198)
* xgamma 1.0.2.
  + the manpage now explains how to print the gamma value more clearly
    (closes: #296021).
* xsetroot 1.0.2.
* xrdb 1.0.4.
  + fixes manpage typo (closes: #276286).
* Add upstream URL to debian/copyright, and update it from xgamma's COPYING
  file.

[ Brice Goglin ]
* Add menu entries for xrefresh and xvidtune.
* sessreg 1.0.3.
* xset 1.0.3.
* Add myself to Uploaders, and remove Branden with his permission.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Xorg: xhost.c,v 1.4 2001/02/09 02:05:46 xorgcvs Exp $ */
 
2
/* $XdotOrg: app/xhost/xhost.c,v 1.4 2005/06/18 08:03:35 alanc Exp $ */
 
3
/*
 
4
 
 
5
Copyright 1985, 1986, 1987, 1998  The Open Group
 
6
Copyright 2004 Sun Microsystems, Inc.
 
7
 
 
8
All rights reserved.
 
9
 
 
10
Permission is hereby granted, free of charge, to any person obtaining a
 
11
copy of this software and associated documentation files (the
 
12
"Software"), to deal in the Software without restriction, including
 
13
without limitation the rights to use, copy, modify, merge, publish,
 
14
distribute, and/or sell copies of the Software, and to permit persons
 
15
to whom the Software is furnished to do so, provided that the above
 
16
copyright notice(s) and this permission notice appear in all copies of
 
17
the Software and that both the above copyright notice(s) and this
 
18
permission notice appear in supporting documentation.
 
19
 
 
20
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 
21
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
22
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
 
23
OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 
24
HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
 
25
INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
 
26
FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 
27
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 
28
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
29
 
 
30
Except as contained in this notice, the name of a copyright holder
 
31
shall not be used in advertising or otherwise to promote the sale, use
 
32
or other dealings in this Software without prior written authorization
 
33
of the copyright holder.
 
34
 
 
35
X Window System is a trademark of The Open Group.
 
36
 
 
37
*/
 
38
/* $XFree86: xc/programs/xhost/xhost.c,v 3.26 2003/07/27 14:05:45 herrb Exp $ */
 
39
 
 
40
#ifdef HAVE_CONFIG_H
 
41
#include "config.h"
 
42
#endif
 
43
 
 
44
#if defined(TCPCONN) || defined(STREAMSCONN)
 
45
#define NEEDSOCKETS
 
46
#endif
 
47
#ifdef UNIXCONN
 
48
#define NEEDSOCKETS
 
49
#endif
 
50
#ifdef DNETCONN
 
51
#define NEEDSOCKETS
 
52
#endif
 
53
 
 
54
#include <X11/Xlib.h>
 
55
#include <X11/Xos.h>
 
56
#include <X11/Xproto.h>
 
57
#include <X11/Xfuncs.h>
 
58
#include <stdio.h>
 
59
#include <stdlib.h>
 
60
#include <signal.h>
 
61
#ifdef X_NOT_POSIX
 
62
#include <setjmp.h>
 
63
#endif
 
64
#include <ctype.h>
 
65
#include <X11/Xauth.h>
 
66
#include <X11/Xmu/Error.h>
 
67
#include <stdlib.h>
 
68
 
 
69
#ifdef NEEDSOCKETS
 
70
#ifdef att
 
71
typedef unsigned short unsign16;
 
72
typedef unsigned long unsign32;
 
73
typedef short sign16;
 
74
typedef long sign32;
 
75
#include <interlan/socket.h>
 
76
#include <interlan/netdb.h>
 
77
#include <interlan/in.h>
 
78
#else
 
79
#ifndef Lynx
 
80
#include <sys/socket.h>
 
81
#else
 
82
#include <socket.h>
 
83
#endif
 
84
#include <netdb.h>
 
85
#include <netinet/in.h>
 
86
#endif
 
87
#endif /* NEEDSOCKETS */
 
88
 
 
89
#ifndef BAD_ARPAINET
 
90
#include <arpa/inet.h>
 
91
#else
 
92
/* bogus definition of inet_makeaddr() in BSD 4.2 and Ultrix */
 
93
extern unsigned long inet_makeaddr();
 
94
#endif
 
95
 
 
96
#ifdef DNETCONN
 
97
#include <netdnet/dn.h>
 
98
#include <netdnet/dnetdb.h>
 
99
#endif
 
100
 
 
101
#ifdef SECURE_RPC
 
102
#include <pwd.h>
 
103
#include <rpc/rpc.h>
 
104
#ifdef X_POSIX_C_SOURCE
 
105
#define _POSIX_C_SOURCE X_POSIX_C_SOURCE
 
106
#include <limits.h>
 
107
#undef _POSIX_C_SOURCE
 
108
#else
 
109
#if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE)
 
110
#include <limits.h>
 
111
#else
 
112
#define _POSIX_SOURCE
 
113
#include <limits.h>
 
114
#undef _POSIX_SOURCE
 
115
#endif
 
116
#endif
 
117
#ifndef NGROUPS_MAX
 
118
#include <sys/param.h>
 
119
#define NGROUPS_MAX NGROUPS
 
120
#endif
 
121
#ifdef sun
 
122
/* Go figure, there's no getdomainname() prototype available */
 
123
extern int getdomainname(char *name, size_t len);
 
124
#endif
 
125
#endif
 
126
 
 
127
static int change_host(Display *dpy, char *name, Bool add);
 
128
static char *get_hostname(XHostAddress *ha);
 
129
static int local_xerror(Display *dpy, XErrorEvent *rep);
 
130
 
 
131
#ifdef RETSIGTYPE /* autoconf AC_TYPE_SIGNAL */
 
132
# define signal_t RETSIGTYPE
 
133
#else /* Imake */
 
134
#ifdef SIGNALRETURNSINT
 
135
#define signal_t int
 
136
#else
 
137
#define signal_t void
 
138
#endif
 
139
#endif /* RETSIGTYPE */
 
140
static signal_t nameserver_lost(int sig);
 
141
 
 
142
#define NAMESERVER_TIMEOUT 5    /* time to wait for nameserver */
 
143
 
 
144
volatile int nameserver_timedout;
 
145
 
 
146
char *ProgramName;
 
147
 
 
148
#ifdef NEEDSOCKETS
 
149
static int 
 
150
XFamily(int af)
 
151
{
 
152
    int i;
 
153
    static struct _familyMap {
 
154
        int af, xf;
 
155
    } familyMap[] = {
 
156
#ifdef  AF_DECnet
 
157
        { AF_DECnet, FamilyDECnet },
 
158
#endif
 
159
#ifdef  AF_CHAOS
 
160
        { AF_CHAOS, FamilyChaos },
 
161
#endif
 
162
#ifdef  AF_INET
 
163
        { AF_INET, FamilyInternet },
 
164
#if defined(IPv6) && defined(AF_INET6)
 
165
        { AF_INET6, FamilyInternet6 },
 
166
#endif
 
167
#endif
 
168
};
 
169
 
 
170
#define FAMILIES ((sizeof familyMap)/(sizeof familyMap[0]))
 
171
 
 
172
    for (i = 0; i < FAMILIES; i++)
 
173
        if (familyMap[i].af == af) return familyMap[i].xf;
 
174
    return -1;
 
175
}
 
176
#endif /* NEEDSOCKETS */
 
177
 
 
178
Display *dpy;
 
179
 
 
180
int
 
181
main(int argc, char *argv[])
 
182
{
 
183
    register char *arg;
 
184
    int i, nhosts = 0;
 
185
    char *hostname;
 
186
    int nfailed = 0;
 
187
    XHostAddress *list;
 
188
    Bool enabled = False;
 
189
#ifdef DNETCONN
 
190
    char *dnet_htoa();
 
191
    struct nodeent *np;
 
192
    struct dn_naddr *nlist, dnaddr, *dnaddrp, *dnet_addr();
 
193
    char *cp;
 
194
#endif
 
195
 
 
196
    ProgramName = argv[0];
 
197
 
 
198
    if ((dpy = XOpenDisplay(NULL)) == NULL) {
 
199
        fprintf(stderr, "%s:  unable to open display \"%s\"\n",
 
200
                ProgramName, XDisplayName (NULL));
 
201
        exit(1);
 
202
    }
 
203
 
 
204
    XSetErrorHandler(local_xerror);
 
205
 
 
206
 
 
207
    if (argc == 1) {
 
208
#ifdef DNETCONN
 
209
        setnodeent(1);          /* keep the database accessed */
 
210
#endif
 
211
        sethostent(1);          /* don't close the data base each time */
 
212
        list = XListHosts(dpy, &nhosts, &enabled);
 
213
        if (enabled)
 
214
            printf ("access control enabled, only authorized clients can connect\n");
 
215
        else
 
216
            printf ("access control disabled, clients can connect from any host\n");
 
217
 
 
218
        if (nhosts != 0) {
 
219
            for (i = 0; i < nhosts; i++ )  {
 
220
                hostname = get_hostname(&list[i]);
 
221
                if (hostname) {
 
222
                    switch (list[i].family) {
 
223
                    case FamilyInternet:
 
224
                        printf("INET:");
 
225
                        break;
 
226
                    case FamilyInternet6:
 
227
                        printf("INET6:");
 
228
                        break;
 
229
                    case FamilyDECnet:
 
230
                        printf("DNET:");
 
231
                        break;
 
232
                    case FamilyNetname:
 
233
                        printf("NIS:");
 
234
                        break;
 
235
                    case FamilyKrb5Principal:
 
236
                        printf("KRB:");
 
237
                        break;
 
238
                    case FamilyLocalHost:
 
239
                        printf("LOCAL:");
 
240
                        break;
 
241
                    case FamilyServerInterpreted:
 
242
                        printf("SI:");
 
243
                        break;
 
244
                    default:
 
245
                        printf("<unknown family type %d>:", list[i].family);
 
246
                        break;
 
247
                    }
 
248
                    printf ("%s", hostname);
 
249
                } else {
 
250
                    printf ("<unknown address in family %d>",
 
251
                            list[i].family);
 
252
                }
 
253
                if (nameserver_timedout) {
 
254
                    printf("\t(no nameserver response within %d seconds)\n",
 
255
                           NAMESERVER_TIMEOUT);
 
256
                    nameserver_timedout = 0;
 
257
                } else
 
258
                    printf("\n");
 
259
            }
 
260
            free(list);
 
261
            endhostent();
 
262
        }
 
263
        exit(0);
 
264
    }
 
265
 
 
266
    if (argc == 2 && !strcmp(argv[1], "-help")) {
 
267
        fprintf(stderr, "usage: %s [[+-]hostname ...]\n", argv[0]);
 
268
        exit(1);
 
269
    }
 
270
 
 
271
    for (i = 1; i < argc; i++) {
 
272
        arg = argv[i];
 
273
        if (*arg == '-') {
 
274
            
 
275
            if (!argv[i][1] && ((i+1) == argc)) {
 
276
                printf ("access control enabled, only authorized clients can connect\n");
 
277
                XEnableAccessControl(dpy);
 
278
            } else {
 
279
                arg = argv[i][1]? &argv[i][1] : argv[++i];
 
280
                if (!change_host (dpy, arg, False)) {
 
281
                    fprintf (stderr, "%s:  bad hostname \"%s\"\n",
 
282
                             ProgramName, arg);
 
283
                    nfailed++;
 
284
                }
 
285
            }
 
286
        } else {
 
287
            if (*arg == '+' && !argv[i][1] && ((i+1) == argc)) {
 
288
                printf ("access control disabled, clients can connect from any host\n");
 
289
                XDisableAccessControl(dpy);
 
290
            } else {
 
291
                if (*arg == '+') {
 
292
                    arg = argv[i][1]? &argv[i][1] : argv[++i];
 
293
                }
 
294
                if (!change_host (dpy, arg, True)) {
 
295
                    fprintf (stderr, "%s:  bad hostname \"%s\"\n",
 
296
                             ProgramName, arg);
 
297
                    nfailed++;
 
298
                }
 
299
            }
 
300
        }
 
301
    }
 
302
    XCloseDisplay (dpy);        /* does an XSync first */
 
303
    exit(nfailed);
 
304
}
 
305
 
 
306
 
 
307
 
 
308
/*
 
309
 * change_host - edit the list of hosts that may connect to the server;
 
310
 * it parses DECnet names (expo::), Internet addresses (18.30.0.212), or
 
311
 * Internet names (expo.lcs.mit.edu); if 4.3bsd macro h_addr is defined
 
312
 * (from <netdb.h>), it will add or remove all addresses with the given
 
313
 * address.
 
314
 */
 
315
 
 
316
static int 
 
317
change_host(Display *dpy, char *name, Bool add)
 
318
{
 
319
    XHostAddress ha;
 
320
    char *lname;
 
321
    int namelen, i, family = FamilyWild;
 
322
#ifdef K5AUTH
 
323
    krb5_principal princ;
 
324
    krb5_data kbuf;
 
325
#endif
 
326
#ifdef NEEDSOCKETS
 
327
    static struct in_addr addr; /* so we can point at it */
 
328
#if defined(IPv6) && defined(AF_INET6)
 
329
    static struct in6_addr addr6; /* so we can point at it */
 
330
#else
 
331
    struct hostent *hp;
 
332
#endif
 
333
#endif
 
334
    char *cp;
 
335
#ifdef DNETCONN
 
336
    struct dn_naddr *dnaddrp;
 
337
    struct nodeent *np;
 
338
    static struct dn_naddr dnaddr;
 
339
#endif                          /* DNETCONN */
 
340
    static char *add_msg = "being added to access control list";
 
341
    static char *remove_msg = "being removed from access control list";
 
342
 
 
343
    namelen = strlen(name);
 
344
    if ((lname = (char *)malloc(namelen+1)) == NULL) {
 
345
        fprintf (stderr, "%s: malloc bombed in change_host\n", ProgramName);
 
346
        exit (1);
 
347
    }
 
348
    for (i = 0; i < namelen; i++) {
 
349
        lname[i] = tolower(name[i]);
 
350
    }
 
351
    lname[namelen] = '\0';
 
352
    if (!strncmp("inet:", lname, 5)) {
 
353
#if defined(TCPCONN) || defined(STREAMSCONN)
 
354
        family = FamilyInternet;
 
355
        name += 5;
 
356
#else
 
357
        fprintf (stderr, "%s: not compiled for TCP/IP\n", ProgramName);
 
358
        free(lname);
 
359
        return 0;
 
360
#endif
 
361
    }
 
362
    else if (!strncmp("inet6:", lname, 6)) {
 
363
#if (defined(TCPCONN) || defined(STREAMSCONN)) && \
 
364
    defined(IPv6) && defined(AF_INET6)
 
365
        family = FamilyInternet6;
 
366
        name += 6;
 
367
#else
 
368
        fprintf (stderr, "%s: not compiled for IPv6\n", ProgramName);
 
369
        free(lname);
 
370
        return 0;
 
371
#endif
 
372
    }
 
373
#ifdef ACCEPT_INETV6 /* Allow inetv6 as an alias for inet6 for compatibility
 
374
                        with original X11 over IPv6 draft. */
 
375
    else if (!strncmp("inetv6:", lname, 7)) {
 
376
#if (defined(TCPCONN) || defined(STREAMSCONN)) && \
 
377
    defined(IPv6) && defined(AF_INET6)
 
378
        family = FamilyInternet6;
 
379
        name += 7;
 
380
#else
 
381
        fprintf (stderr, "%s: not compiled for IPv6\n", ProgramName);
 
382
        free(lname);
 
383
        return 0;
 
384
#endif
 
385
    }
 
386
#endif /* ACCEPT_INETV6 */
 
387
    else if (!strncmp("dnet:", lname, 5)) {
 
388
#ifdef DNETCONN
 
389
        family = FamilyDECnet;
 
390
        name += 5;
 
391
#else
 
392
        fprintf (stderr, "%s: not compiled for DECnet\n", ProgramName);
 
393
        free(lname);
 
394
        return 0;
 
395
#endif
 
396
    }
 
397
    else if (!strncmp("nis:", lname, 4)) {
 
398
#ifdef SECURE_RPC
 
399
        family = FamilyNetname;
 
400
        name += 4;
 
401
#else
 
402
        fprintf (stderr, "%s: not compiled for Secure RPC\n", ProgramName);
 
403
        free(lname);
 
404
        return 0;
 
405
#endif
 
406
    }
 
407
    else if (!strncmp("krb:", lname, 4)) {
 
408
#ifdef K5AUTH
 
409
        family = FamilyKrb5Principal;
 
410
        name +=4;
 
411
#else
 
412
        fprintf (stderr, "%s: not compiled for Kerberos 5\n", ProgramName);
 
413
        free(lname);
 
414
        return 0;
 
415
#endif
 
416
    }
 
417
    else if (!strncmp("local:", lname, 6)) {
 
418
        family = FamilyLocalHost;
 
419
    }
 
420
    else if (!strncmp("si:", lname, 3)) {
 
421
        family = FamilyServerInterpreted;
 
422
        name += 3;
 
423
    }
 
424
    if (family == FamilyWild && (cp = strchr(lname, ':'))) {
 
425
        *cp = '\0';
 
426
        fprintf (stderr, "%s: unknown address family \"%s\"\n",
 
427
                 ProgramName, lname);
 
428
        free(lname);
 
429
        return 0;
 
430
    }
 
431
    free(lname);
 
432
 
 
433
    if (family == FamilyServerInterpreted) {
 
434
        XServerInterpretedAddress siaddr;
 
435
        int namelen;
 
436
 
 
437
        cp = strchr(name, ':');
 
438
        if (cp == NULL || cp == name) {
 
439
            fprintf(stderr, 
 
440
           "%s: type must be specified for server interpreted family \"%s\"\n",
 
441
              ProgramName, name);
 
442
            return 0;
 
443
        }
 
444
        ha.family = FamilyServerInterpreted;
 
445
        ha.address = (char *) &siaddr;
 
446
        namelen = strlen(name);
 
447
        siaddr.type = malloc(namelen);
 
448
        if (siaddr.type == NULL) {
 
449
            return 0;
 
450
        }
 
451
        memcpy(siaddr.type, name, namelen);
 
452
        siaddr.typelength = cp - name;
 
453
        siaddr.type[siaddr.typelength] = '\0';
 
454
        siaddr.value = siaddr.type + siaddr.typelength + 1;
 
455
        siaddr.valuelength = namelen - (siaddr.typelength + 1);
 
456
        if (add)
 
457
            XAddHost(dpy, &ha);
 
458
        else
 
459
            XRemoveHost(dpy, &ha);
 
460
        free(siaddr.type);
 
461
        printf( "%s %s\n", name, add ? add_msg : remove_msg);
 
462
        return 1;
 
463
    }
 
464
 
 
465
#ifdef DNETCONN
 
466
    if (family == FamilyDECnet || ((family == FamilyWild) &&
 
467
        (cp = strchr(name, ':')) && (*(cp + 1) == ':') &&
 
468
        !(*cp = '\0'))) {
 
469
        ha.family = FamilyDECnet;
 
470
        if (dnaddrp = dnet_addr(name)) {
 
471
            dnaddr = *dnaddrp;
 
472
        } else {
 
473
            if ((np = getnodebyname (name)) == NULL) {
 
474
                fprintf (stderr, "%s:  unable to get node name for \"%s::\"\n",
 
475
                         ProgramName, name);
 
476
                return 0;
 
477
            }
 
478
            dnaddr.a_len = np->n_length;
 
479
            memmove( dnaddr.a_addr, np->n_addr, np->n_length);
 
480
        }
 
481
        ha.length = sizeof(struct dn_naddr);
 
482
        ha.address = (char *)&dnaddr;
 
483
        if (add) {
 
484
            XAddHost (dpy, &ha);
 
485
            printf ("%s:: %s\n", name, add_msg);
 
486
        } else {
 
487
            XRemoveHost (dpy, &ha);
 
488
            printf ("%s:: %s\n", name, remove_msg);
 
489
        }
 
490
        return 1;
 
491
    }
 
492
#endif                          /* DNETCONN */
 
493
#ifdef K5AUTH
 
494
    if (family == FamilyKrb5Principal) {
 
495
        krb5_error_code retval;
 
496
 
 
497
        retval = krb5_parse_name(name, &princ);
 
498
        if (retval) {
 
499
            krb5_init_ets();    /* init krb errs for error_message() */
 
500
            fprintf(stderr, "%s: cannot parse Kerberos name: %s\n",
 
501
                    ProgramName, error_message(retval));
 
502
            return 0;
 
503
        }
 
504
        XauKrb5Encode(princ, &kbuf);
 
505
        ha.length = kbuf.length;
 
506
        ha.address = kbuf.data;
 
507
        ha.family = family;
 
508
        if (add)
 
509
            XAddHost(dpy, &ha);
 
510
        else
 
511
            XRemoveHost(dpy, &ha);
 
512
        krb5_free_principal(princ);
 
513
        free(kbuf.data);
 
514
        printf( "%s %s\n", name, add ? add_msg : remove_msg);
 
515
        return 1;
 
516
    }
 
517
#endif
 
518
    if (family == FamilyLocalHost) {
 
519
        ha.length = 0;
 
520
        ha.address = "";
 
521
        ha.family = family;
 
522
        if (add)
 
523
            XAddHost(dpy, &ha);
 
524
        else
 
525
            XRemoveHost(dpy, &ha);
 
526
        printf( "non-network local connections %s\n", add ? add_msg : remove_msg);
 
527
        return 1;
 
528
    }
 
529
    /*
 
530
     * If it has an '@', it's a netname
 
531
     */
 
532
    if ((family == FamilyNetname && (cp = strchr(name, '@'))) ||
 
533
        (cp = strchr(name, '@'))) {
 
534
        char *netname = name;
 
535
#ifdef SECURE_RPC
 
536
        static char username[MAXNETNAMELEN];
 
537
 
 
538
        if (!cp[1]) {
 
539
            struct passwd *pwd;
 
540
            static char domainname[128];
 
541
 
 
542
            *cp = '\0';
 
543
            pwd = getpwnam(name);
 
544
            if (!pwd) {
 
545
                fprintf(stderr, "no such user \"%s\"\n", name);
 
546
                return 0;
 
547
            }
 
548
            getdomainname(domainname, sizeof(domainname));
 
549
            if (!user2netname(username, pwd->pw_uid, domainname)) {
 
550
                fprintf(stderr, "failed to get netname for \"%s\"\n", name);
 
551
                return 0;
 
552
            }
 
553
            netname = username;
 
554
        }
 
555
#endif
 
556
        ha.family = FamilyNetname;
 
557
        ha.length = strlen(netname);
 
558
        ha.address = netname;
 
559
        if (add)
 
560
            XAddHost (dpy, &ha);
 
561
        else
 
562
            XRemoveHost (dpy, &ha);
 
563
        if (netname != name)
 
564
            printf ("%s@ (%s) %s\n", name, netname, add ? add_msg : remove_msg);
 
565
        else
 
566
            printf ("%s %s\n", netname, add ? add_msg : remove_msg);
 
567
        return 1;
 
568
    }
 
569
#ifdef NEEDSOCKETS
 
570
    /*
 
571
     * First see if inet_addr() can grok the name; if so, then use it.
 
572
     */
 
573
    if (((family == FamilyWild) || (family == FamilyInternet)) &&
 
574
        ((addr.s_addr = inet_addr(name)) != -1)) {
 
575
        ha.family = FamilyInternet;
 
576
        ha.length = 4;          /* but for Cray would be sizeof(addr.s_addr) */
 
577
        ha.address = (char *)&addr; /* but for Cray would be &addr.s_addr */
 
578
        if (add) {
 
579
            XAddHost (dpy, &ha);
 
580
            printf ("%s %s\n", name, add_msg);
 
581
        } else {
 
582
            XRemoveHost (dpy, &ha);
 
583
            printf ("%s %s\n", name, remove_msg);
 
584
        }
 
585
        return 1;
 
586
    } 
 
587
#if defined(IPv6) && defined(AF_INET6)
 
588
    /*
 
589
     * Check to see if inet_pton() can grok it as an IPv6 address
 
590
     */
 
591
    else if (((family == FamilyWild) || (family == FamilyInternet6)) &&
 
592
             (inet_pton(AF_INET6, name, &addr6.s6_addr) == 1)) {
 
593
        ha.family = FamilyInternet6;
 
594
        ha.length = sizeof(addr6.s6_addr);              
 
595
        ha.address = (char *) &addr6.s6_addr; 
 
596
        if (add) {
 
597
            XAddHost (dpy, &ha);
 
598
            printf ("%s %s\n", name, add_msg);
 
599
        } else {
 
600
            XRemoveHost (dpy, &ha);
 
601
            printf ("%s %s\n", name, remove_msg);
 
602
        }
 
603
        return 1;
 
604
    } else {
 
605
    /*
 
606
     * Is it in the namespace?  
 
607
     *
 
608
     * If no family was specified, use both Internet v4 & v6 addresses.
 
609
     * Otherwise, use only addresses matching specified family.
 
610
     */
 
611
        struct addrinfo *addresses;
 
612
        struct addrinfo *a;
 
613
        Bool didit = False;
 
614
 
 
615
        if (getaddrinfo(name, NULL, NULL, &addresses) != 0)
 
616
            return 0;
 
617
 
 
618
        for (a = addresses; a != NULL; a = a->ai_next) {
 
619
            if ( ((a->ai_family == AF_INET) && (family != FamilyInternet6))
 
620
              || ((a->ai_family == AF_INET6) && (family != FamilyInternet)) ) {
 
621
                char ad[INET6_ADDRSTRLEN];
 
622
                ha.family = XFamily(a->ai_family);
 
623
                if (a->ai_family == AF_INET6) {
 
624
                    ha.address = (char *)
 
625
                      &((struct sockaddr_in6 *) a->ai_addr)->sin6_addr;
 
626
                    ha.length = 
 
627
                      sizeof (((struct sockaddr_in6 *) a->ai_addr)->sin6_addr);
 
628
                } else {
 
629
                    ha.address = (char *)
 
630
                      &((struct sockaddr_in *) a->ai_addr)->sin_addr;
 
631
                    ha.length = 
 
632
                      sizeof (((struct sockaddr_in *) a->ai_addr)->sin_addr);
 
633
                }
 
634
                inet_ntop(a->ai_family, ha.address, ad, sizeof(ad));
 
635
        /* printf("Family: %d\nLength: %d\n", a->ai_family, ha.length); */
 
636
                /* printf("Address: %s\n", ad); */
 
637
 
 
638
                if (add) {
 
639
                    XAddHost (dpy, &ha);
 
640
                } else {
 
641
                    XRemoveHost (dpy, &ha);
 
642
                }
 
643
                didit = True;
 
644
            }
 
645
        }
 
646
        if (didit == True) {
 
647
            printf ("%s %s\n", name, add ? add_msg : remove_msg);
 
648
        } else {
 
649
            const char *familyMsg = "";
 
650
 
 
651
            if (family == FamilyInternet6) {
 
652
                familyMsg = "inet6 ";
 
653
            } else if (family == FamilyInternet) {
 
654
                familyMsg = "inet ";
 
655
            }
 
656
 
 
657
            fprintf(stderr, "%s: unable to get %saddress for \"%s\"\n",
 
658
                ProgramName, familyMsg, name);
 
659
        }
 
660
        freeaddrinfo(addresses);
 
661
        return 1;
 
662
    }
 
663
#else /* !IPv6 */
 
664
    /*
 
665
     * Is it in the namespace?
 
666
     */
 
667
    else if (((hp = gethostbyname(name)) == (struct hostent *)NULL)
 
668
             || hp->h_addrtype != AF_INET) {
 
669
        return 0;
 
670
    } else {
 
671
        ha.family = XFamily(hp->h_addrtype);
 
672
        ha.length = hp->h_length;
 
673
#ifdef h_addr                   /* new 4.3bsd version of gethostent */
 
674
    {
 
675
        char **list;
 
676
 
 
677
        /* iterate over the hosts */
 
678
        for (list = hp->h_addr_list; *list; list++) {
 
679
            ha.address = *list;
 
680
            if (add) {
 
681
                XAddHost (dpy, &ha);
 
682
            } else {
 
683
                XRemoveHost (dpy, &ha);
 
684
            }
 
685
        }
 
686
    }
 
687
#else
 
688
        ha.address = hp->h_addr;
 
689
        if (add) {
 
690
            XAddHost (dpy, &ha);
 
691
        } else {
 
692
            XRemoveHost (dpy, &ha);
 
693
        }
 
694
#endif
 
695
        printf ("%s %s\n", name, add ? add_msg : remove_msg);
 
696
        return 1;
 
697
    }
 
698
#endif /* IPv6 */
 
699
#else /* NEEDSOCKETS */
 
700
    return 0;
 
701
#endif /* NEEDSOCKETS */
 
702
}
 
703
 
 
704
 
 
705
/*
 
706
 * get_hostname - Given an internet address, return a name (CHARON.MIT.EDU)
 
707
 * or a string representing the address (18.58.0.13) if the name cannot
 
708
 * be found.
 
709
 */
 
710
 
 
711
#ifdef X_NOT_POSIX
 
712
jmp_buf env;
 
713
#endif
 
714
 
 
715
static char *
 
716
get_hostname(XHostAddress *ha)
 
717
{
 
718
#if (defined(TCPCONN) || defined(STREAMSCONN)) &&       \
 
719
     (!defined(IPv6) || !defined(AF_INET6))
 
720
    static struct hostent *hp = NULL;
 
721
#endif
 
722
#ifdef DNETCONN
 
723
    struct nodeent *np;
 
724
    static char nodeaddr[5 + 2 * DN_MAXADDL];
 
725
#endif                          /* DNETCONN */
 
726
#ifdef K5AUTH
 
727
    krb5_principal princ;
 
728
    krb5_data kbuf;
 
729
    char *kname;
 
730
    static char kname_out[255];
 
731
#endif
 
732
#ifndef X_NOT_POSIX
 
733
    struct sigaction sa;
 
734
#endif
 
735
 
 
736
#if defined(TCPCONN) || defined(STREAMSCONN)
 
737
#if defined(IPv6) && defined(AF_INET6)
 
738
    if ((ha->family == FamilyInternet) || (ha->family == FamilyInternet6)) {
 
739
        struct sockaddr_storage saddr;
 
740
        static char inetname[NI_MAXHOST];
 
741
        int saddrlen;
 
742
 
 
743
        inetname[0] = '\0';
 
744
        memset(&saddr, 0, sizeof saddr);
 
745
        if (ha->family == FamilyInternet) {
 
746
            struct sockaddr_in *sin = (struct sockaddr_in *) &saddr;
 
747
#ifdef BSD44SOCKETS
 
748
            sin->sin_len = sizeof(struct sockaddr_in);
 
749
#endif
 
750
            sin->sin_family = AF_INET;
 
751
            sin->sin_port = 0;
 
752
            memcpy(&sin->sin_addr, ha->address, sizeof(sin->sin_addr));
 
753
            saddrlen = sizeof(struct sockaddr_in);
 
754
        } else {
 
755
            struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &saddr;
 
756
#ifdef SIN6_LEN
 
757
            sin6->sin6_len = sizeof(struct sockaddr_in6);
 
758
#endif
 
759
            sin6->sin6_family = AF_INET6;
 
760
            sin6->sin6_port = 0;
 
761
            memcpy(&sin6->sin6_addr, ha->address, sizeof(sin6->sin6_addr));
 
762
            saddrlen = sizeof(struct sockaddr_in6);
 
763
        }
 
764
 
 
765
        /* gethostbyaddr can take a LONG time if the host does not exist.
 
766
           Assume that if it does not respond in NAMESERVER_TIMEOUT seconds
 
767
           that something is wrong and do not make the user wait.
 
768
           gethostbyaddr will continue after a signal, so we have to
 
769
           jump out of it. 
 
770
           */
 
771
#ifndef X_NOT_POSIX
 
772
        memset(&sa, 0, sizeof sa);
 
773
        sa.sa_handler = nameserver_lost;
 
774
        sa.sa_flags = 0;        /* don't restart syscalls */
 
775
        sigaction(SIGALRM, &sa, NULL);
 
776
#else
 
777
        signal(SIGALRM, nameserver_lost);
 
778
#endif
 
779
        alarm(NAMESERVER_TIMEOUT);
 
780
#ifdef X_NOT_POSIX
 
781
        if (setjmp(env) == 0) 
 
782
#endif
 
783
        { 
 
784
            getnameinfo((struct sockaddr *) &saddr, saddrlen, inetname,
 
785
              sizeof(inetname), NULL, 0, 0);
 
786
        }
 
787
        alarm(0);
 
788
        if (nameserver_timedout || inetname[0] == '\0')
 
789
            inet_ntop(((struct sockaddr *)&saddr)->sa_family, ha->address,
 
790
                inetname, sizeof(inetname));
 
791
        return inetname;              
 
792
    }
 
793
#else
 
794
    if (ha->family == FamilyInternet) {
 
795
#ifdef CRAY
 
796
        struct in_addr t_addr;
 
797
        bzero((char *)&t_addr, sizeof(t_addr));
 
798
        bcopy(ha->address, (char *)&t_addr, 4);
 
799
        ha->address = (char *)&t_addr;
 
800
#endif
 
801
        /* gethostbyaddr can take a LONG time if the host does not exist.
 
802
           Assume that if it does not respond in NAMESERVER_TIMEOUT seconds
 
803
           that something is wrong and do not make the user wait.
 
804
           gethostbyaddr will continue after a signal, so we have to
 
805
           jump out of it. 
 
806
           */
 
807
#ifndef X_NOT_POSIX
 
808
        memset(&sa, 0, sizeof sa);
 
809
        sa.sa_handler = nameserver_lost;
 
810
        sa.sa_flags = 0;        /* don't restart syscalls */
 
811
        sigaction(SIGALRM, &sa, NULL);
 
812
#else
 
813
        signal(SIGALRM, nameserver_lost);
 
814
#endif
 
815
        alarm(4);
 
816
#ifdef X_NOT_POSIX
 
817
        if (setjmp(env) == 0) {
 
818
#endif
 
819
            hp = gethostbyaddr (ha->address, ha->length, AF_INET);
 
820
#ifdef X_NOT_POSIX
 
821
        }
 
822
#endif
 
823
        alarm(0);
 
824
        if (hp)
 
825
            return (hp->h_name);
 
826
        else return (inet_ntoa(*((struct in_addr *)(ha->address))));
 
827
    }
 
828
#endif /* IPv6 */
 
829
#endif
 
830
    if (ha->family == FamilyNetname) {
 
831
        static char netname[512];
 
832
        int len;
 
833
#ifdef SECURE_RPC
 
834
        int gidlen;
 
835
        uid_t uid;
 
836
        gid_t gid, gidlist[NGROUPS_MAX];
 
837
#endif
 
838
 
 
839
        if (ha->length < sizeof(netname) - 1)
 
840
            len = ha->length;
 
841
        else
 
842
            len = sizeof(netname) - 1;
 
843
        memmove( netname, ha->address, len);
 
844
        netname[len] = '\0';
 
845
#ifdef SECURE_RPC
 
846
        if (netname2user(netname, &uid, &gid, &gidlen, gidlist)) {
 
847
            struct passwd *pwd;
 
848
 
 
849
            pwd = getpwuid(uid);
 
850
            if (pwd)
 
851
                sprintf(netname, "%s@ (%*.*s)", pwd->pw_name,
 
852
                        ha->length, ha->length, ha->address);
 
853
        }
 
854
#endif
 
855
        return (netname);
 
856
    }
 
857
#ifdef DNETCONN
 
858
    if (ha->family == FamilyDECnet) {
 
859
        struct dn_naddr *addr_ptr = (struct dn_naddr *) ha->address;
 
860
 
 
861
        if (np = getnodebyaddr(addr_ptr->a_addr, addr_ptr->a_len, AF_DECnet)) {
 
862
            sprintf(nodeaddr, "%s", np->n_name);
 
863
        } else {
 
864
            sprintf(nodeaddr, "%s", dnet_htoa(ha->address));
 
865
        }
 
866
        return(nodeaddr);
 
867
    }
 
868
#endif
 
869
#ifdef K5AUTH
 
870
    if (ha->family == FamilyKrb5Principal) {
 
871
        kbuf.data = ha->address;
 
872
        kbuf.length = ha->length;
 
873
        XauKrb5Decode(kbuf, &princ);
 
874
        krb5_unparse_name(princ, &kname);
 
875
        krb5_free_principal(princ);
 
876
        strncpy(kname_out, kname, sizeof (kname_out));
 
877
        free(kname);
 
878
        return kname_out;
 
879
    }
 
880
#endif
 
881
    if (ha->family == FamilyLocalHost) {
 
882
        return "";
 
883
    }
 
884
    if (ha->family == FamilyServerInterpreted) {
 
885
        XServerInterpretedAddress *sip;
 
886
        static char *addressString;
 
887
        static size_t addressStringSize;
 
888
        size_t neededSize;
 
889
 
 
890
        sip = (XServerInterpretedAddress *) ha->address;
 
891
        neededSize = sip->typelength + sip->valuelength + 2;
 
892
 
 
893
        if (addressStringSize < neededSize) {
 
894
            if (addressString != NULL) {
 
895
                free(addressString);
 
896
            }
 
897
            addressStringSize = neededSize;
 
898
            addressString = malloc(addressStringSize);
 
899
        }
 
900
        if (addressString != NULL) {
 
901
            char *cp = addressString;
 
902
 
 
903
            memcpy(cp, sip->type, sip->typelength);
 
904
            cp += sip->typelength;
 
905
            *cp++ = ':';
 
906
            memcpy(cp, sip->value, sip->valuelength);
 
907
            cp += sip->valuelength;
 
908
            *cp = '\0';
 
909
        }
 
910
        return addressString;
 
911
    }
 
912
    return (NULL);
 
913
}
 
914
 
 
915
/*ARGUSED*/
 
916
static signal_t 
 
917
nameserver_lost(int sig)
 
918
{
 
919
    nameserver_timedout = 1;
 
920
#ifdef X_NOT_POSIX
 
921
    /* not needed with POSIX signals - stuck syscalls will not 
 
922
       be restarted after signal delivery */
 
923
    longjmp(env, -1);
 
924
#endif
 
925
}
 
926
 
 
927
/*
 
928
 * local_xerror - local non-fatal error handling routine. If the error was
 
929
 * that an X_GetHosts request for an unknown address format was received, just
 
930
 * return, otherwise print the normal error message and continue.
 
931
 */
 
932
static int 
 
933
local_xerror(Display *dpy, XErrorEvent *rep)
 
934
{
 
935
    if ((rep->error_code == BadAccess) && (rep->request_code == X_ChangeHosts)) {
 
936
        fprintf (stderr, 
 
937
                 "%s:  must be on local machine to add or remove hosts.\n",
 
938
                 ProgramName);
 
939
        return 1;
 
940
    } else if ((rep->error_code == BadAccess) && 
 
941
               (rep->request_code == X_SetAccessControl)) {
 
942
        fprintf (stderr, 
 
943
        "%s:  must be on local machine to enable or disable access control.\n",
 
944
                 ProgramName);
 
945
        return 1;
 
946
    } else if ((rep->error_code == BadValue) && 
 
947
               (rep->request_code == X_ListHosts)) {
 
948
        return 1;
 
949
    }
 
950
 
 
951
    XmuPrintDefaultErrorMessage (dpy, rep, stderr);
 
952
    return 0;
 
953
}
 
954
 
 
955
#ifdef __CYGWIN__
 
956
void sethostent(int x)
 
957
{}
 
958
 
 
959
void endhostent()
 
960
{}
 
961
#endif
 
962