~ubuntu-branches/ubuntu/feisty/xdm/feisty

« back to all changes in this revision

Viewing changes to chooser.c

  • Committer: Bazaar Package Importer
  • Author(s): Fabio M. Di Nitto
  • Date: 2005-09-08 09:43:15 UTC
  • Revision ID: james.westby@ubuntu.com-20050908094315-ceggae9y1p4fgvia
Tags: upstream-0.99.1
ImportĀ upstreamĀ versionĀ 0.99.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * $XdotOrg: xc/programs/xdm/chooser.c,v 1.2 2004/04/23 19:54:42 eich Exp $
 
3
 * $Xorg: chooser.c,v 1.4 2001/02/09 02:05:40 xorgcvs Exp $
 
4
 *
 
5
Copyright 1990, 1998  The Open Group
 
6
 
 
7
Permission to use, copy, modify, distribute, and sell this software and its
 
8
documentation for any purpose is hereby granted without fee, provided that
 
9
the above copyright notice appear in all copies and that both that
 
10
copyright notice and this permission notice appear in supporting
 
11
documentation.
 
12
 
 
13
The above copyright notice and this permission notice shall be included in
 
14
all copies or substantial portions of the Software.
 
15
 
 
16
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
17
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
18
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 
19
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 
20
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
21
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
22
 
 
23
Except as contained in this notice, the name of The Open Group shall not be
 
24
used in advertising or otherwise to promote the sale, use or other dealings
 
25
in this Software without prior written authorization from The Open Group.
 
26
 *
 
27
 * Author:  Keith Packard, MIT X Consortium
 
28
 */
 
29
 
 
30
/* $XFree86: xc/programs/xdm/chooser.c,v 3.26 2003/07/18 15:53:28 tsi Exp $ */
 
31
 
 
32
/*
 
33
 * Chooser - display a menu of names and let the user select one
 
34
 */
 
35
 
 
36
/*
 
37
 * Layout:
 
38
 *
 
39
 *  +--------------------------------------------------+
 
40
 *  |             +------------------+                 |
 
41
 *  |             |      Label       |                 |
 
42
 *  |             +------------------+                 |
 
43
 *  |    +-+--------------+                            |
 
44
 *  |    |^| name-1       |                            |
 
45
 *  |    ||| name-2       |                            |
 
46
 *  |    |v| name-3       |                            |
 
47
 *  |    | | name-4       |                            |
 
48
 *  |    | | name-5       |                            |
 
49
 *  |    | | name-6       |                            |
 
50
 *  |    +----------------+                            |
 
51
 *  |    cancel  accept  ping                          |
 
52
 *  +--------------------------------------------------+
 
53
 */
 
54
 
 
55
#include    <X11/Intrinsic.h>
 
56
#include    <X11/StringDefs.h>
 
57
#include    <X11/Xatom.h>
 
58
 
 
59
#include    <X11/Xaw/Paned.h>
 
60
#include    <X11/Xaw/Label.h>
 
61
#include    <X11/Xaw/Viewport.h>
 
62
#include    <X11/Xaw/List.h>
 
63
#include    <X11/Xaw/Box.h>
 
64
#include    <X11/Xaw/Command.h>
 
65
 
 
66
#include    "dm.h"
 
67
 
 
68
#include    <X11/Xdmcp.h>
 
69
 
 
70
#include    <sys/types.h>
 
71
#include    <stdio.h>
 
72
#include    <ctype.h>
 
73
 
 
74
#ifdef USE_XINERAMA
 
75
#include    <X11/extensions/Xinerama.h>
 
76
#endif
 
77
 
 
78
#if defined(SVR4) && !defined(SCO325)
 
79
#include    <sys/sockio.h>
 
80
#endif
 
81
#if defined(SVR4) && defined(PowerMAX_OS)
 
82
#include    <sys/stropts.h>
 
83
#endif
 
84
#if defined(SYSV) && defined(i386)
 
85
#include    <sys/stream.h>
 
86
#ifdef ISC
 
87
#include    <sys/sioctl.h>
 
88
#include    <sys/stropts.h>
 
89
#endif
 
90
#endif
 
91
 
 
92
#include    "dm_socket.h"
 
93
 
 
94
#include    <arpa/inet.h>
 
95
 
 
96
#include    <sys/ioctl.h>
 
97
#ifdef STREAMSCONN
 
98
#ifdef WINTCP /* NCR with Wollongong TCP */
 
99
#include    <netinet/ip.h>
 
100
#endif
 
101
#include    <stropts.h>
 
102
#include    <tiuser.h>
 
103
#include    <netconfig.h>
 
104
#include    <netdir.h>
 
105
#endif
 
106
 
 
107
#ifdef CSRG_BASED
 
108
#include <sys/param.h>
 
109
#if (BSD >= 199103)
 
110
#define VARIABLE_IFREQ
 
111
#endif
 
112
#endif
 
113
 
 
114
#ifdef XKB
 
115
#include <X11/extensions/XKBbells.h>
 
116
#endif
 
117
 
 
118
#define BROADCAST_HOSTNAME  "BROADCAST"
 
119
 
 
120
#ifndef ishexdigit
 
121
#define ishexdigit(c)   (isdigit(c) || ('a' <= (c) && (c) <= 'f'))
 
122
#endif
 
123
 
 
124
#ifdef hpux
 
125
# include <sys/utsname.h>
 
126
# ifdef HAS_IFREQ
 
127
#  include <net/if.h>
 
128
# endif
 
129
#else
 
130
#ifdef __convex__
 
131
# include <sync/queue.h>
 
132
# include <sync/sema.h>
 
133
#endif
 
134
#include <net/if.h>
 
135
#endif /* hpux */
 
136
 
 
137
#include    <netdb.h>
 
138
#include    <X11/keysym.h>
 
139
 
 
140
static int FromHex (char *s, char *d, int len);
 
141
static int oldline;
 
142
 
 
143
Widget      toplevel, label, viewport, paned, list, box, cancel, acceptit, ping;
 
144
 
 
145
static void     CvtStringToARRAY8(
 
146
    XrmValuePtr args,
 
147
    Cardinal    *num_args,
 
148
    XrmValuePtr fromVal,
 
149
    XrmValuePtr toVal);
 
150
 
 
151
static struct _app_resources {
 
152
    ARRAY8Ptr   xdmAddress;
 
153
    ARRAY8Ptr   clientAddress;
 
154
    int         connectionType;
 
155
} app_resources;
 
156
 
 
157
#define offset(field) XtOffsetOf(struct _app_resources, field)
 
158
 
 
159
#define XtRARRAY8   "ARRAY8"
 
160
 
 
161
static XtResource  resources[] = {
 
162
    {"xdmAddress",      "XdmAddress",  XtRARRAY8,       sizeof (ARRAY8Ptr),
 
163
        offset (xdmAddress),        XtRString,  NULL },
 
164
    {"clientAddress",   "ClientAddress",  XtRARRAY8,    sizeof (ARRAY8Ptr),
 
165
        offset (clientAddress),     XtRString,  NULL },
 
166
    {"connectionType",  "ConnectionType",   XtRInt,     sizeof (int),
 
167
        offset (connectionType),    XtRImmediate,       (XtPointer) 0 }
 
168
};
 
169
#undef offset
 
170
 
 
171
static XrmOptionDescRec options[] = {
 
172
    { "-xdmaddress",    "*xdmAddress",      XrmoptionSepArg,    NULL },
 
173
    { "-clientaddress", "*clientAddress",   XrmoptionSepArg,    NULL },
 
174
    { "-connectionType","*connectionType",  XrmoptionSepArg,    NULL },
 
175
};
 
176
 
 
177
typedef struct _hostAddr {
 
178
    struct _hostAddr    *next;
 
179
    struct sockaddr     *addr;
 
180
    int                 addrlen;
 
181
    xdmOpCode           type;
 
182
} HostAddr;
 
183
 
 
184
static HostAddr    *hostAddrdb;
 
185
 
 
186
typedef struct _hostName {
 
187
    struct _hostName    *next;
 
188
    char                *fullname;
 
189
    int                 willing;
 
190
    ARRAY8              hostname, status;
 
191
    CARD16              connectionType;
 
192
    ARRAY8              hostaddr;
 
193
} HostName;
 
194
 
 
195
static HostName    *hostNamedb;
 
196
 
 
197
static int  socketFD;
 
198
#if defined(IPv6) && defined(AF_INET6)
 
199
static int  socket6FD;
 
200
#endif
 
201
 
 
202
static int  pingTry;
 
203
 
 
204
#define PING_INTERVAL   2000
 
205
#define TRIES           3
 
206
 
 
207
static XdmcpBuffer      directBuffer, broadcastBuffer;
 
208
static XdmcpBuffer      buffer;
 
209
 
 
210
#if ((defined(SVR4) && !defined(sun) && !defined(__sgi) && !defined(NCR)) || defined(ISC)) && defined(SIOCGIFCONF)
 
211
 
 
212
/* Deal with different SIOCGIFCONF ioctl semantics on these OSs */
 
213
 
 
214
static int
 
215
ifioctl (int fd, int cmd, char *arg)
 
216
{
 
217
    struct strioctl ioc;
 
218
    int ret;
 
219
 
 
220
    bzero((char *) &ioc, sizeof(ioc));
 
221
    ioc.ic_cmd = cmd;
 
222
    ioc.ic_timout = 0;
 
223
    if (cmd == SIOCGIFCONF)
 
224
    {
 
225
        ioc.ic_len = ((struct ifconf *) arg)->ifc_len;
 
226
        ioc.ic_dp = ((struct ifconf *) arg)->ifc_buf;
 
227
#ifdef ISC
 
228
        /* SIOCGIFCONF is somewhat brain damaged on ISC. The argument
 
229
         * buffer must contain the ifconf structure as header. Ifc_req
 
230
         * is also not a pointer but a one element array of ifreq
 
231
         * structures. On return this array is extended by enough
 
232
         * ifreq fields to hold all interfaces. The return buffer length
 
233
         * is placed in the buffer header.
 
234
         */
 
235
        ((struct ifconf *) ioc.ic_dp)->ifc_len =
 
236
                                         ioc.ic_len - sizeof(struct ifconf);
 
237
#endif
 
238
    }
 
239
    else
 
240
    {
 
241
        ioc.ic_len = sizeof(struct ifreq);
 
242
        ioc.ic_dp = arg;
 
243
    }
 
244
    ret = ioctl(fd, I_STR, (char *) &ioc);
 
245
    if (ret >= 0 && cmd == SIOCGIFCONF)
 
246
#ifdef SVR4
 
247
        ((struct ifconf *) arg)->ifc_len = ioc.ic_len;
 
248
#endif
 
249
#ifdef ISC
 
250
    {
 
251
        ((struct ifconf *) arg)->ifc_len =
 
252
                                 ((struct ifconf *)ioc.ic_dp)->ifc_len;
 
253
        ((struct ifconf *) arg)->ifc_buf = 
 
254
                        (caddr_t)((struct ifconf *)ioc.ic_dp)->ifc_req;
 
255
    }
 
256
#endif
 
257
    return(ret);
 
258
}
 
259
#else /* ((SVR4 && !sun && !NCR) || ISC) && SIOCGIFCONF */
 
260
#define ifioctl ioctl
 
261
#endif /* ((SVR4 && !sun) || ISC) && SIOCGIFCONF */
 
262
 
 
263
 
 
264
/* ARGSUSED */
 
265
static void
 
266
PingHosts (XtPointer closure, XtIntervalId *id)
 
267
{
 
268
    HostAddr    *hosts;
 
269
    int          sfd = socketFD;
 
270
 
 
271
    for (hosts = hostAddrdb; hosts; hosts = hosts->next)
 
272
    {
 
273
#if defined(IPv6) && defined(AF_INET6)
 
274
        if ( ((struct sockaddr *) hosts->addr)->sa_family == AF_INET6 )
 
275
            sfd = socket6FD;
 
276
        else
 
277
            sfd = socketFD;
 
278
#endif
 
279
        if (hosts->type == QUERY)
 
280
            XdmcpFlush (sfd, &directBuffer, 
 
281
                        (XdmcpNetaddr) hosts->addr, hosts->addrlen);
 
282
        else
 
283
            XdmcpFlush (sfd, &broadcastBuffer, 
 
284
                        (XdmcpNetaddr) hosts->addr, hosts->addrlen);
 
285
    }
 
286
    if (++pingTry < TRIES)
 
287
        XtAddTimeOut (PING_INTERVAL, PingHosts, (XtPointer) 0);
 
288
}
 
289
 
 
290
char    **NameTable;
 
291
int     NameTableSize;
 
292
 
 
293
static int
 
294
HostnameCompare (const void *a, const void *b)
 
295
{
 
296
    return strcmp (*(char **)a, *(char **)b);
 
297
}
 
298
 
 
299
static void
 
300
RebuildTable (int size)
 
301
{
 
302
    char        **newTable = 0;
 
303
    HostName    *names;
 
304
    int         i;
 
305
 
 
306
    if (size)
 
307
    {
 
308
        newTable = (char **) malloc (size * sizeof (char *));
 
309
        if (!newTable)
 
310
            return;
 
311
        for (names = hostNamedb, i = 0; names; names = names->next, i++)
 
312
            newTable[i] = names->fullname;
 
313
        qsort (newTable, size, sizeof (char *), HostnameCompare);
 
314
    }
 
315
    XawListChange (list, newTable, size, 0, TRUE);
 
316
    if (NameTable)
 
317
        free ((char *) NameTable);
 
318
    NameTable = newTable;
 
319
    NameTableSize = size;
 
320
}
 
321
 
 
322
static int
 
323
AddHostname (ARRAY8Ptr hostname, ARRAY8Ptr status, struct sockaddr *addr, int willing)
 
324
{
 
325
    HostName    *new, **names, *name;
 
326
    ARRAY8      hostAddr;
 
327
    CARD16      connectionType;
 
328
    int         fulllen;
 
329
 
 
330
    switch (addr->sa_family)
 
331
    {
 
332
    case AF_INET:
 
333
        hostAddr.data = (CARD8 *) &((struct sockaddr_in *) addr)->sin_addr;
 
334
        hostAddr.length = 4;
 
335
        connectionType = FamilyInternet;
 
336
        break;
 
337
#if defined(IPv6) && defined(AF_INET6)
 
338
    case AF_INET6:
 
339
        hostAddr.data = (CARD8 *) &((struct sockaddr_in6 *) addr)->sin6_addr;
 
340
        hostAddr.length = 16;
 
341
        connectionType = FamilyInternet6;
 
342
        break;
 
343
#endif
 
344
    default:
 
345
        hostAddr.data = (CARD8 *) "";
 
346
        hostAddr.length = 0;
 
347
        connectionType = FamilyLocal;
 
348
        break;
 
349
    }
 
350
    for (names = &hostNamedb; *names; names = & (*names)->next)
 
351
    {
 
352
        name = *names;
 
353
        if (connectionType == name->connectionType &&
 
354
            XdmcpARRAY8Equal (&hostAddr, &name->hostaddr))
 
355
        {
 
356
            if (XdmcpARRAY8Equal (status, &name->status))
 
357
            {
 
358
                return 0;
 
359
            }
 
360
            break;
 
361
        }
 
362
    }
 
363
    if (!*names)
 
364
    {
 
365
        new = (HostName *) malloc (sizeof (HostName));
 
366
        if (!new)
 
367
            return 0;
 
368
        if (hostname->length)
 
369
        {
 
370
            switch (addr->sa_family)
 
371
            {
 
372
            case AF_INET:
 
373
#if defined(IPv6) && defined(AF_INET6)
 
374
            case AF_INET6:
 
375
#endif
 
376
                {
 
377
                    struct hostent  *hostent;
 
378
                    char            *host;
 
379
        
 
380
                    hostent = gethostbyaddr ((char *)hostAddr.data, hostAddr.length, addr->sa_family);
 
381
                    if (hostent)
 
382
                    {
 
383
                        XdmcpDisposeARRAY8 (hostname);
 
384
                        host = (char *)hostent->h_name;
 
385
                        XdmcpAllocARRAY8 (hostname, strlen (host));
 
386
                        memmove( hostname->data, host, hostname->length);
 
387
                    }
 
388
                }
 
389
            }
 
390
        }
 
391
        if (!XdmcpAllocARRAY8 (&new->hostaddr, hostAddr.length))
 
392
        {
 
393
            free ((char *) new->fullname);
 
394
            free ((char *) new);
 
395
            return 0;
 
396
        }
 
397
        memmove( new->hostaddr.data, hostAddr.data, hostAddr.length);
 
398
        new->connectionType = connectionType;
 
399
        new->hostname = *hostname;
 
400
 
 
401
        *names = new;
 
402
        new->next = 0;
 
403
        NameTableSize++;
 
404
    }
 
405
    else
 
406
    {
 
407
        new = *names;
 
408
        free (new->fullname);
 
409
        XdmcpDisposeARRAY8 (&new->status);
 
410
        XdmcpDisposeARRAY8 (hostname);
 
411
    }
 
412
    new->willing = willing;
 
413
    new->status = *status;
 
414
 
 
415
    hostname = &new->hostname;
 
416
    fulllen = hostname->length;
 
417
    if (fulllen < 30)
 
418
        fulllen = 30;
 
419
    new->fullname = malloc (fulllen + status->length + 10);
 
420
    if (!new->fullname)
 
421
    {
 
422
        new->fullname = "Unknown";
 
423
    }
 
424
    else
 
425
    {
 
426
        sprintf (new->fullname, "%-30.*s %*.*s",
 
427
                 hostname->length, hostname->data,
 
428
                 status->length, status->length, status->data);
 
429
    }
 
430
    RebuildTable (NameTableSize);
 
431
    return 1;
 
432
}
 
433
 
 
434
static void
 
435
DisposeHostname (HostName *host)
 
436
{
 
437
    XdmcpDisposeARRAY8 (&host->hostname);
 
438
    XdmcpDisposeARRAY8 (&host->hostaddr);
 
439
    XdmcpDisposeARRAY8 (&host->status);
 
440
    free ((char *) host->fullname);
 
441
    free ((char *) host);
 
442
}
 
443
 
 
444
#if 0
 
445
static void
 
446
RemoveHostname (HostName *host)
 
447
{
 
448
    HostName    **prev, *hosts;
 
449
 
 
450
    prev = &hostNamedb;;
 
451
    for (hosts = hostNamedb; hosts; hosts = hosts->next)
 
452
    {
 
453
        if (hosts == host)
 
454
            break;
 
455
        prev = &hosts->next;
 
456
    }
 
457
    if (!hosts)
 
458
        return;
 
459
    *prev = host->next;
 
460
    DisposeHostname (host);
 
461
    NameTableSize--;
 
462
    RebuildTable (NameTableSize);
 
463
}
 
464
#endif
 
465
 
 
466
static void
 
467
EmptyHostnames (void)
 
468
{
 
469
    HostName    *hosts, *next;
 
470
 
 
471
    for (hosts = hostNamedb; hosts; hosts = next)
 
472
    {
 
473
        next = hosts->next;
 
474
        DisposeHostname (hosts);
 
475
    }
 
476
    NameTableSize = 0;
 
477
    hostNamedb = 0;
 
478
    RebuildTable (NameTableSize);
 
479
}
 
480
 
 
481
/* ARGSUSED */
 
482
static void
 
483
ReceivePacket (XtPointer closure, int *source, XtInputId *id)
 
484
{
 
485
    XdmcpHeader     header;
 
486
    ARRAY8          authenticationName;
 
487
    ARRAY8          hostname;
 
488
    ARRAY8          status;
 
489
    int             saveHostname = 0;
 
490
#if defined(IPv6) && defined(AF_INET6)
 
491
    struct sockaddr_storage addr;
 
492
#else
 
493
    struct sockaddr addr;
 
494
#endif
 
495
    int             addrlen;
 
496
    int             sfd = * (int *) closure;
 
497
 
 
498
    addrlen = sizeof (addr);
 
499
    if (!XdmcpFill (sfd, &buffer, (XdmcpNetaddr) &addr, &addrlen))
 
500
        return;
 
501
    if (!XdmcpReadHeader (&buffer, &header))
 
502
        return;
 
503
    if (header.version != XDM_PROTOCOL_VERSION)
 
504
        return;
 
505
    hostname.data = 0;
 
506
    status.data = 0;
 
507
    authenticationName.data = 0;
 
508
    switch (header.opcode) {
 
509
    case WILLING:
 
510
        if (XdmcpReadARRAY8 (&buffer, &authenticationName) &&
 
511
            XdmcpReadARRAY8 (&buffer, &hostname) &&
 
512
            XdmcpReadARRAY8 (&buffer, &status))
 
513
        {
 
514
            if (header.length == 6 + authenticationName.length +
 
515
                hostname.length + status.length)
 
516
            {
 
517
                if (AddHostname (&hostname, &status, (struct sockaddr *) &addr,
 
518
                                 header.opcode == (int) WILLING))
 
519
                    saveHostname = 1;
 
520
            }
 
521
        }
 
522
        XdmcpDisposeARRAY8 (&authenticationName);
 
523
        break;
 
524
    case UNWILLING:
 
525
        if (XdmcpReadARRAY8 (&buffer, &hostname) &&
 
526
            XdmcpReadARRAY8 (&buffer, &status))
 
527
        {
 
528
            if (header.length == 4 + hostname.length + status.length)
 
529
            {
 
530
                if (AddHostname (&hostname, &status, (struct sockaddr *) &addr,
 
531
                                 header.opcode == (int) WILLING))
 
532
                    saveHostname = 1;
 
533
 
 
534
            }
 
535
        }
 
536
        break;
 
537
    default:
 
538
        break;
 
539
    }
 
540
    if (!saveHostname)
 
541
    {
 
542
        XdmcpDisposeARRAY8 (&hostname);
 
543
        XdmcpDisposeARRAY8 (&status);
 
544
    }
 
545
}
 
546
 
 
547
static void
 
548
RegisterHostaddr (struct sockaddr *addr, int len, xdmOpCode type)
 
549
{
 
550
    HostAddr            *host, **prev;
 
551
 
 
552
    host = (HostAddr *) malloc (sizeof (HostAddr));
 
553
    if (!host)
 
554
        return;
 
555
    host->addr = (struct sockaddr *) malloc (len);
 
556
    if (!host->addr)
 
557
    {
 
558
        free ((char *) host);
 
559
        return;
 
560
    }
 
561
    memmove( (char *) host->addr, (char *) addr, len);
 
562
    host->addrlen = len;
 
563
    host->type = type;
 
564
    for (prev = &hostAddrdb; *prev; prev = &(*prev)->next)
 
565
        ;
 
566
    *prev = host;
 
567
    host->next = NULL;
 
568
}
 
569
 
 
570
/*
 
571
 * Register the address for this host.
 
572
 * Called with each of the names on the command line.
 
573
 * The special name "BROADCAST" looks up all the broadcast
 
574
 *  addresses on the local host.
 
575
 */
 
576
 
 
577
/* Handle variable length ifreq in BNR2 and later */
 
578
#ifdef VARIABLE_IFREQ
 
579
#define ifr_size(p) (sizeof (struct ifreq) + \
 
580
                     (p->ifr_addr.sa_len > sizeof (p->ifr_addr) ? \
 
581
                      p->ifr_addr.sa_len - sizeof (p->ifr_addr) : 0))
 
582
#else
 
583
#define ifr_size(p) (sizeof (struct ifreq))
 
584
#endif
 
585
 
 
586
static void
 
587
RegisterHostname (char *name)
 
588
{
 
589
#if !defined(IPv6) || !defined(AF_INET6)
 
590
    struct hostent      *hostent;
 
591
#endif
 
592
    struct sockaddr_in  in_addr;
 
593
    struct ifconf       ifc;
 
594
    register struct ifreq *ifr;
 
595
    struct sockaddr     broad_addr;
 
596
    char                buf[2048], *cp, *cplim;
 
597
 
 
598
    if (!strcmp (name, BROADCAST_HOSTNAME))
 
599
    {
 
600
#ifdef WINTCP /* NCR with Wollongong TCP */
 
601
    int                 ipfd;
 
602
    struct ifconf       *ifcp;
 
603
    struct strioctl     ioc;
 
604
    int                 n;
 
605
 
 
606
        ifcp = (struct ifconf *)buf;
 
607
        ifcp->ifc_buf = buf+4;
 
608
        ifcp->ifc_len = sizeof (buf) - 4;
 
609
 
 
610
        if ((ipfd=open( "/dev/ip", O_RDONLY )) < 0 )
 
611
            {
 
612
            t_error( "RegisterHostname() t_open(/dev/ip) failed" );
 
613
            return;
 
614
            }
 
615
 
 
616
        ioc.ic_cmd = IPIOC_GETIFCONF;
 
617
        ioc.ic_timout = 60;
 
618
        ioc.ic_len = sizeof( buf );
 
619
        ioc.ic_dp = (char *)ifcp;
 
620
 
 
621
        if (ioctl (ipfd, (int) I_STR, (char *) &ioc) < 0)
 
622
            {
 
623
            perror( "RegisterHostname() ioctl(I_STR(IPIOC_GETIFCONF)) failed" );
 
624
            close( ipfd );
 
625
            return;
 
626
            }
 
627
 
 
628
        for (ifr = ifcp->ifc_req, n = ifcp->ifc_len / sizeof (struct ifreq);
 
629
            --n >= 0;
 
630
            ifr++)
 
631
#else /* WINTCP */
 
632
        ifc.ifc_len = sizeof (buf);
 
633
        ifc.ifc_buf = buf;
 
634
        if (ifioctl (socketFD, (int) SIOCGIFCONF, (char *) &ifc) < 0)
 
635
            return;
 
636
 
 
637
#ifdef ISC
 
638
#define IFC_IFC_REQ (struct ifreq *) ifc.ifc_buf
 
639
#else
 
640
#define IFC_IFC_REQ ifc.ifc_req
 
641
#endif
 
642
 
 
643
        cplim = (char *) IFC_IFC_REQ + ifc.ifc_len;
 
644
 
 
645
        for (cp = (char *) IFC_IFC_REQ; cp < cplim; cp += ifr_size (ifr))
 
646
#endif /* WINTCP */
 
647
        {
 
648
#ifndef WINTCP
 
649
            ifr = (struct ifreq *) cp;
 
650
#endif
 
651
            if (ifr->ifr_addr.sa_family != AF_INET)
 
652
                continue;
 
653
 
 
654
            broad_addr = ifr->ifr_addr;
 
655
            ((struct sockaddr_in *) &broad_addr)->sin_addr.s_addr =
 
656
                htonl (INADDR_BROADCAST);
 
657
#ifdef SIOCGIFBRDADDR
 
658
            {
 
659
                struct ifreq    broad_req;
 
660
    
 
661
                broad_req = *ifr;
 
662
#ifdef WINTCP /* NCR with Wollongong TCP */
 
663
                ioc.ic_cmd = IPIOC_GETIFFLAGS;
 
664
                ioc.ic_timout = 0;
 
665
                ioc.ic_len = sizeof( broad_req );
 
666
                ioc.ic_dp = (char *)&broad_req;
 
667
 
 
668
                if (ioctl (ipfd, I_STR, (char *) &ioc) != -1 &&
 
669
#else /* WINTCP */
 
670
                if (ifioctl (socketFD, SIOCGIFFLAGS, (char *) &broad_req) != -1 &&
 
671
#endif /* WINTCP */
 
672
                    (broad_req.ifr_flags & IFF_BROADCAST) &&
 
673
                    (broad_req.ifr_flags & IFF_UP)
 
674
                    )
 
675
                {
 
676
                    broad_req = *ifr;
 
677
#ifdef WINTCP /* NCR with Wollongong TCP */
 
678
                    ioc.ic_cmd = IPIOC_GETIFBRDADDR;
 
679
                    ioc.ic_timout = 0;
 
680
                    ioc.ic_len = sizeof( broad_req );
 
681
                    ioc.ic_dp = (char *)&broad_req;
 
682
 
 
683
                    if (ioctl (ipfd, I_STR, (char *) &ioc) != -1)
 
684
#else /* WINTCP */
 
685
                    if (ifioctl (socketFD, SIOCGIFBRDADDR, &broad_req) != -1)
 
686
#endif /* WINTCP */
 
687
                        broad_addr = broad_req.ifr_addr;
 
688
                    else
 
689
                        continue;
 
690
                }
 
691
                else
 
692
                    continue;
 
693
            }
 
694
#endif
 
695
            in_addr = *((struct sockaddr_in *) &broad_addr);
 
696
            in_addr.sin_port = htons (XDM_UDP_PORT);
 
697
#ifdef BSD44SOCKETS
 
698
            in_addr.sin_len = sizeof(in_addr);
 
699
#endif
 
700
            RegisterHostaddr ((struct sockaddr *)&in_addr, sizeof (in_addr),
 
701
                              BROADCAST_QUERY);
 
702
        }
 
703
    }
 
704
    else
 
705
    {
 
706
        /* address as hex string, e.g., "12180022" (deprecated) */
 
707
        if (strlen(name) == 8 &&
 
708
            FromHex(name, (char *)&in_addr.sin_addr, strlen(name)) == 0)
 
709
        {
 
710
            in_addr.sin_family = AF_INET;
 
711
            in_addr.sin_port = htons (XDM_UDP_PORT);
 
712
#ifdef BSD44SOCKETS
 
713
            in_addr.sin_len = sizeof(in_addr);
 
714
#endif
 
715
            RegisterHostaddr ((struct sockaddr *)&in_addr, sizeof (in_addr),
 
716
                                QUERY);
 
717
        }
 
718
#if defined(IPv6) && defined(AF_INET6)
 
719
        else {
 
720
            char sport[8];
 
721
            struct addrinfo *ai, *nai, hints;
 
722
            bzero(&hints,sizeof(hints));
 
723
            hints.ai_socktype = SOCK_DGRAM;
 
724
            sprintf(sport, "%d", XDM_UDP_PORT);
 
725
            if (getaddrinfo(name, sport, &hints, &ai) == 0) {
 
726
                for (nai = ai ; nai != NULL ; nai = nai->ai_next) {
 
727
                    if ((nai->ai_family == AF_INET) || 
 
728
                        (nai->ai_family == AF_INET6)) {
 
729
                        if (((nai->ai_family == AF_INET) && 
 
730
                          IN_MULTICAST(((struct sockaddr_in *) nai->ai_addr)
 
731
                            ->sin_addr.s_addr))
 
732
                          || ((nai->ai_family == AF_INET6) && 
 
733
                            IN6_IS_ADDR_MULTICAST(
 
734
                                &((struct sockaddr_in6 *) nai->ai_addr)
 
735
                                  ->sin6_addr))) 
 
736
                        {
 
737
                            RegisterHostaddr(nai->ai_addr, nai->ai_addrlen, 
 
738
                              BROADCAST_QUERY);
 
739
                        } else {
 
740
                            RegisterHostaddr(nai->ai_addr, nai->ai_addrlen, 
 
741
                              QUERY);
 
742
                        }
 
743
                    }
 
744
                }
 
745
            }
 
746
        }
 
747
#else
 
748
        /* Per RFC 1123, check first for IP address in dotted-decimal form */
 
749
        else if ((in_addr.sin_addr.s_addr = inet_addr(name)) != -1)
 
750
            in_addr.sin_family = AF_INET;
 
751
        else
 
752
        {
 
753
            hostent = gethostbyname (name);
 
754
            if (!hostent)
 
755
                return;
 
756
            if (hostent->h_addrtype != AF_INET || hostent->h_length != 4)
 
757
                return;
 
758
            in_addr.sin_family = hostent->h_addrtype;
 
759
            memmove( &in_addr.sin_addr, hostent->h_addr, 4);
 
760
        }
 
761
        in_addr.sin_port = htons (XDM_UDP_PORT);
 
762
#ifdef BSD44SOCKETS
 
763
        in_addr.sin_len = sizeof(in_addr);
 
764
#endif
 
765
        RegisterHostaddr ((struct sockaddr *)&in_addr, sizeof (in_addr),
 
766
                          QUERY);
 
767
#endif /* IPv6 */
 
768
    }
 
769
}
 
770
 
 
771
static ARRAYofARRAY8    AuthenticationNames;
 
772
 
 
773
#if 0
 
774
static void
 
775
RegisterAuthenticationName (char *name, int namelen)
 
776
{
 
777
    ARRAY8Ptr   authName;
 
778
    if (!XdmcpReallocARRAYofARRAY8 (&AuthenticationNames,
 
779
                                    AuthenticationNames.length + 1))
 
780
        return;
 
781
    authName = &AuthenticationNames.data[AuthenticationNames.length-1];
 
782
    if (!XdmcpAllocARRAY8 (authName, namelen))
 
783
        return;
 
784
    memmove( authName->data, name, namelen);
 
785
}
 
786
#endif
 
787
 
 
788
static int
 
789
InitXDMCP (char **argv)
 
790
{
 
791
    int soopts = 1;
 
792
    XdmcpHeader header;
 
793
    int i;
 
794
 
 
795
    header.version = XDM_PROTOCOL_VERSION;
 
796
    header.opcode = (CARD16) BROADCAST_QUERY;
 
797
    header.length = 1;
 
798
    for (i = 0; i < (int)AuthenticationNames.length; i++)
 
799
        header.length += 2 + AuthenticationNames.data[i].length;
 
800
    XdmcpWriteHeader (&broadcastBuffer, &header);
 
801
    XdmcpWriteARRAYofARRAY8 (&broadcastBuffer, &AuthenticationNames);
 
802
 
 
803
    header.version = XDM_PROTOCOL_VERSION;
 
804
    header.opcode = (CARD16) QUERY;
 
805
    header.length = 1;
 
806
    for (i = 0; i < (int)AuthenticationNames.length; i++)
 
807
        header.length += 2 + AuthenticationNames.data[i].length;
 
808
    XdmcpWriteHeader (&directBuffer, &header);
 
809
    XdmcpWriteARRAYofARRAY8 (&directBuffer, &AuthenticationNames);
 
810
#if defined(STREAMSCONN)
 
811
    if ((socketFD = t_open ("/dev/udp", O_RDWR, 0)) < 0)
 
812
        return 0;
 
813
 
 
814
    if (t_bind( socketFD, NULL, NULL ) < 0)
 
815
        {
 
816
        t_close(socketFD);
 
817
        return 0;
 
818
        }
 
819
 
 
820
    /*
 
821
     * This part of the code looks contrived. It will actually fit in nicely
 
822
     * when the CLTS part of Xtrans is implemented.
 
823
     */
 
824
    {
 
825
    struct netconfig *nconf;
 
826
 
 
827
    if( (nconf=getnetconfigent("udp")) == NULL )
 
828
        {
 
829
        t_unbind(socketFD);
 
830
        t_close(socketFD);
 
831
        return 0;
 
832
        }
 
833
 
 
834
    if( netdir_options(nconf, ND_SET_BROADCAST, socketFD, NULL) )
 
835
        {
 
836
        freenetconfigent(nconf);
 
837
        t_unbind(socketFD);
 
838
        t_close(socketFD);
 
839
        return 0;
 
840
        }
 
841
 
 
842
    freenetconfigent(nconf);
 
843
    }
 
844
#else
 
845
    if ((socketFD = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
 
846
        return 0;
 
847
#if defined(IPv6) && defined(AF_INET6)
 
848
    socket6FD = socket (AF_INET6, SOCK_DGRAM, 0);
 
849
#endif
 
850
#endif
 
851
#ifndef STREAMSCONN
 
852
#ifdef SO_BROADCAST
 
853
    soopts = 1;
 
854
    if (setsockopt (socketFD, SOL_SOCKET, SO_BROADCAST, (char *)&soopts, sizeof (soopts)) < 0)
 
855
        perror ("setsockopt");
 
856
#endif
 
857
#endif
 
858
    
 
859
    XtAddInput (socketFD, (XtPointer) XtInputReadMask, ReceivePacket,
 
860
                (XtPointer) &socketFD);
 
861
#if defined(IPv6) && defined(AF_INET6)
 
862
    if (socket6FD != -1)
 
863
    XtAddInput (socket6FD, (XtPointer) XtInputReadMask, ReceivePacket,
 
864
                (XtPointer) &socket6FD);
 
865
#endif
 
866
    while (*argv)
 
867
    {
 
868
        RegisterHostname (*argv);
 
869
        ++argv;
 
870
    }
 
871
    pingTry = 0;
 
872
    PingHosts ((XtPointer)NULL, (XtIntervalId *)NULL);
 
873
    return 1;
 
874
}
 
875
 
 
876
static void
 
877
Choose (HostName *h)
 
878
{
 
879
    if (app_resources.xdmAddress)
 
880
    {
 
881
        struct sockaddr_in  in_addr;
 
882
#if defined(IPv6) && defined(AF_INET6)
 
883
        struct sockaddr_in6 in6_addr;
 
884
#endif
 
885
        struct sockaddr *addr = NULL;
 
886
        int             family;
 
887
        int             len = 0;
 
888
        int             fd;
 
889
        char            buf[1024];
 
890
        XdmcpBuffer     buffer;
 
891
        char            *xdm;
 
892
#if defined(STREAMSCONN)
 
893
        struct  t_call  call, rcv;
 
894
#endif
 
895
 
 
896
        xdm = (char *) app_resources.xdmAddress->data;
 
897
        family = (xdm[0] << 8) + xdm[1];
 
898
        switch (family) {
 
899
        case AF_INET:
 
900
#ifdef BSD44SOCKETS
 
901
            in_addr.sin_len = sizeof(in_addr);
 
902
#endif
 
903
            in_addr.sin_family = family;
 
904
            memmove( &in_addr.sin_port, xdm + 2, 2);
 
905
            memmove( &in_addr.sin_addr, xdm + 4, 4);
 
906
            addr = (struct sockaddr *) &in_addr;
 
907
            len = sizeof (in_addr);
 
908
            break;
 
909
#if defined(IPv6) && defined(AF_INET6)
 
910
        case AF_INET6:
 
911
            bzero(&in6_addr, sizeof(in6_addr));
 
912
#ifdef SIN6_LEN
 
913
            in6_addr.sin6_len = sizeof(in6_addr);
 
914
#endif
 
915
            in6_addr.sin6_family = family;
 
916
            memmove( &in6_addr.sin6_port, xdm + 2, 2);
 
917
            memmove( &in6_addr.sin6_addr, xdm + 4, 16);
 
918
            addr = (struct sockaddr *) &in6_addr;
 
919
            len = sizeof (in6_addr);
 
920
            break;
 
921
#endif
 
922
        }
 
923
#if defined(STREAMSCONN)
 
924
        if ((fd = t_open ("/dev/tcp", O_RDWR, NULL)) == -1)
 
925
        {
 
926
            fprintf (stderr, "Cannot create response endpoint\n");
 
927
            fflush(stderr);
 
928
            exit (REMANAGE_DISPLAY);
 
929
        }
 
930
        if (t_bind (fd, NULL, NULL) == -1)
 
931
        {
 
932
            fprintf (stderr, "Cannot bind response endpoint\n");
 
933
            fflush(stderr);
 
934
            t_close (fd);
 
935
            exit (REMANAGE_DISPLAY);
 
936
        }
 
937
        call.addr.buf=(char *)addr;
 
938
        call.addr.len=len;
 
939
        call.addr.maxlen=len;
 
940
        call.opt.len=0;
 
941
        call.opt.maxlen=0;
 
942
        call.udata.len=0;
 
943
        call.udata.maxlen=0;
 
944
        if (t_connect (fd, &call, NULL) == -1)
 
945
        {
 
946
            t_error ("Cannot connect to xdm\n");
 
947
            fflush(stderr);
 
948
            t_unbind (fd);
 
949
            t_close (fd);
 
950
            exit (REMANAGE_DISPLAY);
 
951
        }
 
952
#else
 
953
        if ((fd = socket (family, SOCK_STREAM, 0)) == -1)
 
954
        {
 
955
            fprintf (stderr, "Cannot create response socket\n");
 
956
            exit (REMANAGE_DISPLAY);
 
957
        }
 
958
        if (connect (fd, addr, len) == -1)
 
959
        {
 
960
            fprintf (stderr, "Cannot connect to xdm\n");
 
961
            exit (REMANAGE_DISPLAY);
 
962
        }
 
963
#endif
 
964
        buffer.data = (BYTE *) buf;
 
965
        buffer.size = sizeof (buf);
 
966
        buffer.pointer = 0;
 
967
        buffer.count = 0;
 
968
        XdmcpWriteARRAY8 (&buffer, app_resources.clientAddress);
 
969
        XdmcpWriteCARD16 (&buffer, (CARD16) app_resources.connectionType);
 
970
        XdmcpWriteARRAY8 (&buffer, &h->hostaddr);
 
971
#if defined(STREAMSCONN)
 
972
        if( t_snd (fd, (char *)buffer.data, buffer.pointer, 0) < 0 )
 
973
        {
 
974
            fprintf (stderr, "Cannot send to xdm\n");
 
975
            fflush(stderr);
 
976
            t_unbind (fd);
 
977
            t_close (fd);
 
978
            exit (REMANAGE_DISPLAY);
 
979
        }
 
980
        sleep(5);       /* Hack because sometimes the connection gets
 
981
                           closed before the data arrives on the other end. */
 
982
        t_snddis (fd,NULL);
 
983
        t_unbind (fd);
 
984
        t_close (fd);
 
985
#else
 
986
        write (fd, (char *)buffer.data, buffer.pointer);
 
987
        close (fd);
 
988
#endif
 
989
    }
 
990
    else
 
991
    {
 
992
        int i;
 
993
 
 
994
        printf ("%u\n", h->connectionType);
 
995
        for (i = 0; i < (int)h->hostaddr.length; i++)
 
996
            printf ("%u%s", h->hostaddr.data[i],
 
997
                    i == h->hostaddr.length - 1 ? "\n" : " ");
 
998
    }
 
999
}
 
1000
 
 
1001
/*
 
1002
  next_line returns the next line in a list
 
1003
  across the list end.
 
1004
  (0, 1, 2, 3, 0, 1, 2, 3 ....)
 
1005
*/
 
1006
 
 
1007
static int 
 
1008
next_line(unsigned int current, unsigned int size, int event)
 
1009
{
 
1010
  switch(event) {
 
1011
    case Button5:
 
1012
      return (current + 1) % size;
 
1013
    case Button4:
 
1014
      return (current + size - 1) % size;
 
1015
    case XK_Down:
 
1016
      return (current + 1) % size;
 
1017
    case XK_Up:
 
1018
      return (current + size - 1) % size;
 
1019
  }  
 
1020
  return -1;
 
1021
}
 
1022
 
 
1023
/* 
 
1024
  Hostselect selects a given chooser line.
 
1025
  Returns 1 when host is willing and 0 if not
 
1026
*/
 
1027
 
 
1028
static int
 
1029
Hostselect (int line)
 
1030
{
 
1031
  XawListReturnStruct   *r;
 
1032
  HostName              *h;
 
1033
  r = XawListShowCurrent (list);
 
1034
  /* Assume the next host is willing */
 
1035
  XawListHighlight (list,line);
 
1036
  r = XawListShowCurrent (list);
 
1037
  /* copied from DoCheckWilling */
 
1038
  for (h = hostNamedb; h; h = h->next)
 
1039
  {
 
1040
    if (!strcmp (r->string, h->fullname))
 
1041
    {
 
1042
      if (!h->willing)
 
1043
        XawListUnhighlight (list);
 
1044
      else
 
1045
      {
 
1046
        /* Scroll viewport to make sure new selection is visible */
 
1047
        Arg             size[2];
 
1048
        Dimension       height, portheight;
 
1049
        Position        y;
 
1050
        int             lineheight, liney, newy = 0;
 
1051
 
 
1052
        XtSetArg (size[0], XtNheight, &height);
 
1053
        XtSetArg (size[1], XtNy, &y);
 
1054
        XtGetValues (list, size, (Cardinal) 2);
 
1055
 
 
1056
        XtSetArg (size[0], XtNheight, &portheight);
 
1057
        XtGetValues (viewport, size, (Cardinal) 1);
 
1058
 
 
1059
        lineheight = height / NameTableSize;
 
1060
        liney = lineheight * line;
 
1061
 
 
1062
        if ((y + liney) < 0) {
 
1063
            XawViewportSetCoordinates(viewport, 0, liney);
 
1064
        } else if ((y + liney + lineheight) > portheight) {
 
1065
            XawViewportSetCoordinates(viewport, 0,
 
1066
                                      (liney + lineheight) - portheight);
 
1067
        }
 
1068
        
 
1069
        return 1;
 
1070
      }
 
1071
    }
 
1072
  } 
 
1073
  return 0; 
 
1074
}
 
1075
 
 
1076
/* 
 
1077
  Selectfirst selects the first willing host
 
1078
  in the chooser list (so you can select a host without
 
1079
  presence of mouse, but with pressing space or return,
 
1080
  or XK_Down / XK_Up
 
1081
*/
 
1082
 
 
1083
static void
 
1084
Selectfirst (void)
 
1085
{
 
1086
  int line;
 
1087
  
 
1088
  for (line = 0; line < NameTableSize; line++)
 
1089
  {
 
1090
    if (Hostselect(line))
 
1091
      return;
 
1092
  }        
 
1093
  return;
 
1094
}
 
1095
 
 
1096
/*
 
1097
  Storeold stores the selected line into global int oldentry
 
1098
*/
 
1099
 
 
1100
static void
 
1101
Storeold (Widget w, XEvent *event, String *params, Cardinal *num_params)
 
1102
{
 
1103
  oldline = (XawListShowCurrent(list))->list_index;
 
1104
}
 
1105
 
 
1106
/*
 
1107
  Setold restores the global int oldentry 
 
1108
  when you try to select a host with your mouse
 
1109
  who is unwilling as follows:
 
1110
  <Btn1Down>:     Store() Set() CheckWilling() Setold() \n\
 
1111
*/
 
1112
 
 
1113
static void
 
1114
Setold (Widget w, XEvent *event, String *params, Cardinal *num_params)
 
1115
{
 
1116
 
 
1117
  if ( (XawListShowCurrent(list))->list_index == XAW_LIST_NONE && oldline != XAW_LIST_NONE)
 
1118
    XawListHighlight (list, oldline);
 
1119
}
 
1120
 
 
1121
/*
 
1122
  HostCycle tries to select the next willing host across
 
1123
  the list end and will stop at the first found willing host
 
1124
  or after trying all entries.
 
1125
*/
 
1126
 
 
1127
static void
 
1128
HostCycle(unsigned int line, unsigned int size, KeySym keysym)
 
1129
{
 
1130
  unsigned int newline = line;
 
1131
  /* Do it only once around the chooser list, either direction */
 
1132
  while ( (newline = next_line(newline,size,keysym)) != line && newline != -1)
 
1133
  {
 
1134
    if (Hostselect(newline))
 
1135
      return;
 
1136
  }
 
1137
  /* No other willing host could be found, stay at the old one*/
 
1138
  XawListHighlight (list, line);
 
1139
  return;
 
1140
}
 
1141
 
 
1142
/*
 
1143
  Switch_Key handles XK_Up and XK_Down
 
1144
  and highlights an appropriate line in the chooser list.
 
1145
*/
 
1146
 
 
1147
static void
 
1148
Switch_Key (Widget w, XEvent *event, String *params, Cardinal *num_params)
 
1149
{
 
1150
  char strbuf[128];
 
1151
  KeySym keysym = 0;
 
1152
  static XComposeStatus compose_status = {NULL, 0};
 
1153
  XawListReturnStruct   *r;
 
1154
 
 
1155
  XLookupString (&event->xkey, strbuf, sizeof (strbuf),
 
1156
                           &keysym, &compose_status);    
 
1157
 
 
1158
  if (keysym != XK_Up && keysym != XK_Down)
 
1159
    return;
 
1160
 
 
1161
  r = XawListShowCurrent (list);
 
1162
    
 
1163
  if (r->list_index == XAW_LIST_NONE)
 
1164
    Selectfirst();
 
1165
  else
 
1166
    HostCycle(r->list_index,NameTableSize,keysym);
 
1167
 
 
1168
  return;
 
1169
}
 
1170
 
 
1171
 
 
1172
 
 
1173
/*
 
1174
  Switch_Btn handles ScrollWheel Forward (Button5) and Backward
 
1175
  (Button4) and highlights an appropriate line in the chooser list.
 
1176
*/
 
1177
 
 
1178
static void
 
1179
Switch_Btn (Widget w, XEvent *event, String *params, Cardinal *num_params)
 
1180
{
 
1181
    XawListReturnStruct *r;
 
1182
    r = XawListShowCurrent (list);
 
1183
    
 
1184
    if (r->list_index == XAW_LIST_NONE)
 
1185
      Selectfirst();
 
1186
    else
 
1187
      HostCycle(r->list_index,NameTableSize,event->xbutton.button);
 
1188
 
 
1189
  return;
 
1190
}
 
1191
 
 
1192
 
 
1193
/* ARGSUSED */
 
1194
static void
 
1195
DoAccept (Widget w, XEvent *event, String *params, Cardinal *num_params)
 
1196
{
 
1197
    XawListReturnStruct *r;
 
1198
    HostName            *h;
 
1199
 
 
1200
    r = XawListShowCurrent (list);
 
1201
    if (r->list_index == XAW_LIST_NONE)
 
1202
#ifdef XKB
 
1203
        XkbStdBell(XtDisplay(toplevel),XtWindow(w),0,XkbBI_MinorError);
 
1204
#else
 
1205
        XBell (XtDisplay (toplevel), 0);
 
1206
#endif
 
1207
    else
 
1208
    {
 
1209
        for (h = hostNamedb; h; h = h->next)
 
1210
            if (!strcmp (r->string, h->fullname))
 
1211
            {
 
1212
                Choose (h);
 
1213
            }
 
1214
        exit (OBEYSESS_DISPLAY);
 
1215
    }
 
1216
}
 
1217
 
 
1218
/* ARGSUSED */
 
1219
static void
 
1220
DoCheckWilling (Widget w, XEvent *event, String *params, Cardinal *num_params)
 
1221
{
 
1222
    XawListReturnStruct *r;
 
1223
    HostName            *h;
 
1224
    
 
1225
    r = XawListShowCurrent (list);
 
1226
    if (r->list_index == XAW_LIST_NONE)
 
1227
        return;
 
1228
    for (h = hostNamedb; h; h = h->next)
 
1229
        if (!strcmp (r->string, h->fullname))
 
1230
            if (!h->willing)
 
1231
                XawListUnhighlight (list);
 
1232
}
 
1233
 
 
1234
/* ARGSUSED */
 
1235
static void
 
1236
DoCancel (Widget w, XEvent *event, String *params, Cardinal *num_params)
 
1237
{
 
1238
    exit (OBEYSESS_DISPLAY);
 
1239
}
 
1240
 
 
1241
/* ARGSUSED */
 
1242
static void
 
1243
DoPing (Widget w, XEvent *event, String *params, Cardinal *num_params)
 
1244
{
 
1245
    EmptyHostnames ();
 
1246
    pingTry = 0;
 
1247
    PingHosts ((XtPointer)NULL, (XtIntervalId *)NULL);
 
1248
}
 
1249
 
 
1250
static XtActionsRec app_actions[] = {
 
1251
    { "Accept",       DoAccept },
 
1252
    { "Cancel",       DoCancel },
 
1253
    { "CheckWilling", DoCheckWilling },
 
1254
    { "Ping",         DoPing },
 
1255
    { "KeySwitch",    Switch_Key },
 
1256
    { "BtnSwitch",    Switch_Btn },
 
1257
    { "Store",        Storeold },
 
1258
    { "Setold",       Setold },    
 
1259
};
 
1260
 
 
1261
int
 
1262
main (int argc, char **argv)
 
1263
{
 
1264
    Arg         position[3];
 
1265
    Dimension   width, height;
 
1266
    Position    x, y;
 
1267
#ifdef USE_XINERAMA
 
1268
    XineramaScreenInfo *screens;
 
1269
    int                 s_num;
 
1270
#endif
 
1271
 
 
1272
 
 
1273
    toplevel = XtInitialize (argv[0], "Chooser", options, XtNumber(options), &argc, argv);
 
1274
 
 
1275
    XtAddConverter(XtRString, XtRARRAY8, CvtStringToARRAY8, NULL, 0);
 
1276
 
 
1277
    XtGetApplicationResources (toplevel, (XtPointer) &app_resources, resources,
 
1278
                               XtNumber (resources), NULL, (Cardinal) 0);
 
1279
 
 
1280
    XtAddActions (app_actions, XtNumber (app_actions));
 
1281
    paned = XtCreateManagedWidget ("paned", panedWidgetClass, toplevel, NULL, 0);
 
1282
    label = XtCreateManagedWidget ("label", labelWidgetClass, paned, NULL, 0);
 
1283
    viewport = XtCreateManagedWidget ("viewport", viewportWidgetClass, paned, NULL, 0);
 
1284
    list = XtCreateManagedWidget ("list", listWidgetClass, viewport, NULL, 0);
 
1285
    box = XtCreateManagedWidget ("box", boxWidgetClass, paned, NULL, 0);
 
1286
    cancel = XtCreateManagedWidget ("cancel", commandWidgetClass, box, NULL, 0);
 
1287
    acceptit = XtCreateManagedWidget ("accept", commandWidgetClass, box, NULL, 0);
 
1288
    ping = XtCreateManagedWidget ("ping", commandWidgetClass, box, NULL, 0);
 
1289
 
 
1290
    /*
 
1291
     * center ourselves on the screen
 
1292
     */
 
1293
    XtSetMappedWhenManaged(toplevel, FALSE);
 
1294
    XtRealizeWidget (toplevel);
 
1295
 
 
1296
    XtSetArg (position[0], XtNwidth, &width);
 
1297
    XtSetArg (position[1], XtNheight, &height);
 
1298
    XtGetValues (toplevel, position, (Cardinal) 2);
 
1299
#ifdef USE_XINERAMA
 
1300
    if (
 
1301
        XineramaIsActive(XtDisplay(toplevel)) &&
 
1302
        (screens = XineramaQueryScreens(XtDisplay(toplevel), &s_num)) != NULL
 
1303
       )
 
1304
    {
 
1305
        x = (Position)(screens[0].x_org + (screens[0].width - width) / 2);
 
1306
        y = (Position)(screens[0].y_org + (screens[0].height - height) / 3);
 
1307
        
 
1308
        XFree(screens);
 
1309
    }
 
1310
    else
 
1311
#endif
 
1312
    {
 
1313
        x = (Position)(WidthOfScreen (XtScreen (toplevel)) - width) / 2;
 
1314
        y = (Position)(HeightOfScreen (XtScreen (toplevel)) - height) / 3;
 
1315
    }
 
1316
    XtSetArg (position[0], XtNx, x);
 
1317
    XtSetArg (position[1], XtNy, y);
 
1318
    XtSetValues (toplevel, position, (Cardinal) 2);
 
1319
 
 
1320
    /*
 
1321
     * Run
 
1322
     */
 
1323
    XtMapWidget(toplevel);
 
1324
    InitXDMCP (argv + 1);
 
1325
    XtMainLoop ();
 
1326
    exit(0);
 
1327
    /*NOTREACHED*/
 
1328
}
 
1329
 
 
1330
/* Converts the hex string s of length len into the byte array d.
 
1331
   Returns 0 if s was a legal hex string, 1 otherwise.
 
1332
   */
 
1333
static int
 
1334
FromHex (char *s, char *d, int len)
 
1335
{
 
1336
    int t;
 
1337
    int ret = len&1;            /* odd-length hex strings are illegal */
 
1338
    while (len >= 2)
 
1339
    {
 
1340
#define HexChar(c)  ('0' <= (c) && (c) <= '9' ? (c) - '0' : (c) - 'a' + 10)
 
1341
 
 
1342
        if (!ishexdigit(*s))
 
1343
            ret = 1;
 
1344
        t = HexChar (*s) << 4;
 
1345
        s++;
 
1346
        if (!ishexdigit(*s))
 
1347
            ret = 1;
 
1348
        t += HexChar (*s);
 
1349
        s++;
 
1350
        *d++ = t;
 
1351
        len -= 2;
 
1352
    }
 
1353
    return ret;
 
1354
}
 
1355
 
 
1356
/*ARGSUSED*/
 
1357
static void
 
1358
CvtStringToARRAY8 (XrmValuePtr args, Cardinal *num_args, XrmValuePtr fromVal, XrmValuePtr toVal)
 
1359
{
 
1360
    static ARRAY8Ptr    dest;
 
1361
    char        *s;
 
1362
    int         len;
 
1363
 
 
1364
    dest = (ARRAY8Ptr) XtMalloc (sizeof (ARRAY8));
 
1365
    len = fromVal->size;
 
1366
    s = (char *) fromVal->addr;
 
1367
    if (!XdmcpAllocARRAY8 (dest, len >> 1))
 
1368
        XtStringConversionWarning ((char *) fromVal->addr, XtRARRAY8);
 
1369
    else
 
1370
    {
 
1371
        FromHex (s, (char *) dest->data, len);
 
1372
    }
 
1373
    toVal->addr = (caddr_t) &dest;
 
1374
    toVal->size = sizeof (ARRAY8Ptr);
 
1375
}
 
1376