source: trunk/athena/etc/xdm/xdm/chooser.c @ 6052

Revision 6052, 19.9 KB checked in by lwvanels, 33 years ago (diff)
Initial revision
Line 
1/*
2 * $XConsortium: chooser.c,v 1.10 91/08/25 10:49:47 keith Exp $
3 *
4 * Copyright 1990 Massachusetts Institute of Technology
5 *
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of M.I.T. not be used in advertising or
11 * publicity pertaining to distribution of the software without specific,
12 * written prior permission.  M.I.T. makes no representations about the
13 * suitability of this software for any purpose.  It is provided "as is"
14 * without express or implied warranty.
15 *
16 * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
18 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 *
23 * Author:  Keith Packard, MIT X Consortium
24 */
25
26/*
27 * Chooser - display a menu of names and let the user select one
28 */
29
30/*
31 * Layout:
32 *
33 *  +--------------------------------------------------+
34 *  |             +------------------+                 |
35 *  |             |      Label       |                 |
36 *  |             +------------------+                 |
37 *  |    +-+--------------+                            |
38 *  |    |^| name-1       |                            |
39 *  |    ||| name-2       |                            |
40 *  |    |v| name-3       |                            |
41 *  |    | | name-4       |                            |
42 *  |    | | name-5       |                            |
43 *  |    | | name-6       |                            |
44 *  |    +----------------+                            |
45 *  |    cancel  accept  ping                          |
46 *  +--------------------------------------------------+
47 */
48
49#include    <X11/Intrinsic.h>
50#include    <X11/StringDefs.h>
51#include    <X11/Xatom.h>
52
53#include    <X11/Xaw/Paned.h>
54#include    <X11/Xaw/Label.h>
55#include    <X11/Xaw/Viewport.h>
56#include    <X11/Xaw/List.h>
57#include    <X11/Xaw/Box.h>
58#include    <X11/Xaw/Command.h>
59
60#include    "dm.h"
61
62#include    <X11/Xdmcp.h>
63
64#include    <sys/types.h>
65#include    <stdio.h>
66#include    <ctype.h>
67
68#ifdef SVR4
69#include    <sys/sockio.h>
70#endif
71#include    <sys/socket.h>
72#include    <netinet/in.h>
73#include    <sys/ioctl.h>
74
75#define BROADCAST_HOSTNAME  "BROADCAST"
76
77#ifdef hpux
78# include <sys/utsname.h>
79# ifdef HAS_IFREQ
80#  include <net/if.h>
81# endif
82#else
83#ifdef __convex__
84# include <sync/queue.h>
85# include <sync/sema.h>
86#endif
87# include <net/if.h>
88#endif /* hpux */
89
90#include    <netdb.h>
91
92Widget      toplevel, label, viewport, paned, list, box, cancel, acceptit, ping;
93
94static void     CvtStringToARRAY8();
95
96static struct _app_resources {
97    ARRAY8Ptr   xdmAddress;
98    ARRAY8Ptr   clientAddress;
99    int         connectionType;
100} app_resources;
101
102#define offset(field) XtOffsetOf(struct _app_resources, field)
103
104#define XtRARRAY8   "ARRAY8"
105
106static XtResource  resources[] = {
107    {"xdmAddress",      "XdmAddress",  XtRARRAY8,       sizeof (ARRAY8Ptr),
108        offset (xdmAddress),        XtRString,  NULL },
109    {"clientAddress",   "ClientAddress",  XtRARRAY8,    sizeof (ARRAY8Ptr),
110        offset (clientAddress),     XtRString,  NULL },
111    {"connectionType",  "ConnectionType",   XtRInt,     sizeof (int),
112        offset (connectionType),    XtRImmediate,       (XtPointer) 0 }
113};
114#undef offset
115
116static XrmOptionDescRec options[] = {
117    "-xdmaddress",      "*xdmAddress",      XrmoptionSepArg,    NULL,
118    "-clientaddress",   "*clientAddress",   XrmoptionSepArg,    NULL,
119    "-connectionType",  "*connectionType",  XrmoptionSepArg,    NULL,
120};
121
122typedef struct _hostAddr {
123    struct _hostAddr    *next;
124    struct sockaddr     *addr;
125    int                 addrlen;
126    xdmOpCode           type;
127} HostAddr;
128
129static HostAddr    *hostAddrdb;
130
131typedef struct _hostName {
132    struct _hostName    *next;
133    char                *fullname;
134    int                 willing;
135    ARRAY8              hostname, status;
136    CARD16              connectionType;
137    ARRAY8              hostaddr;
138} HostName;
139
140static HostName    *hostNamedb;
141
142static int  socketFD;
143
144static int  pingTry;
145
146#define PING_INTERVAL   2000
147#define TRIES           3
148
149static XdmcpBuffer      directBuffer, broadcastBuffer;
150static XdmcpBuffer      buffer;
151
152/* ARGSUSED */
153static void
154PingHosts (closure, id)
155    XtPointer closure;
156    XtIntervalId *id;
157{
158    HostAddr    *hosts;
159
160    for (hosts = hostAddrdb; hosts; hosts = hosts->next)
161    {
162        if (hosts->type == QUERY)
163            XdmcpFlush (socketFD, &directBuffer, hosts->addr, hosts->addrlen);
164        else
165            XdmcpFlush (socketFD, &broadcastBuffer, hosts->addr, hosts->addrlen);
166    }
167    if (++pingTry < TRIES)
168        XtAddTimeOut (PING_INTERVAL, PingHosts, (XtPointer) 0);
169}
170
171char    **NameTable;
172int     NameTableSize;
173
174static int
175HostnameCompare (a, b)
176#if __STDC__
177    const void *a, *b;
178#else
179    char *a, *b;
180#endif
181{
182    return strcmp (*(char **)a, *(char **)b);
183}
184
185static void
186RebuildTable (size)
187{
188    char        **newTable = 0;
189    HostName    *names;
190    int         i;
191
192    if (size)
193    {
194        newTable = (char **) malloc (size * sizeof (char *));
195        if (!newTable)
196            return;
197        for (names = hostNamedb, i = 0; names; names = names->next, i++)
198            newTable[i] = names->fullname;
199        qsort (newTable, size, sizeof (char *), HostnameCompare);
200    }
201    XawListChange (list, newTable, size, 0, TRUE);
202    if (NameTable)
203        free ((char *) NameTable);
204    NameTable = newTable;
205    NameTableSize = size;
206}
207
208static int
209AddHostname (hostname, status, addr, willing)
210    ARRAY8Ptr       hostname, status;
211    struct sockaddr *addr;
212    int             willing;
213{
214    HostName    *new, **names, *name;
215    ARRAY8      hostAddr;
216    CARD16      connectionType;
217    int         fulllen;
218
219    switch (addr->sa_family)
220    {
221    case AF_INET:
222        hostAddr.data = (CARD8 *) &((struct sockaddr_in *) addr)->sin_addr;
223        hostAddr.length = 4;
224        connectionType = FamilyInternet;
225        break;
226    default:
227        hostAddr.data = (CARD8 *) "";
228        hostAddr.length = 0;
229        connectionType = FamilyLocal;
230        break;
231    }
232    for (names = &hostNamedb; *names; names = & (*names)->next)
233    {
234        name = *names;
235        if (connectionType == name->connectionType &&
236            XdmcpARRAY8Equal (&hostAddr, &name->hostaddr))
237        {
238            if (XdmcpARRAY8Equal (status, &name->status))
239            {
240                return 0;
241            }
242            break;
243        }
244    }
245    if (!*names)
246    {
247        new = (HostName *) malloc (sizeof (HostName));
248        if (!new)
249            return 0;
250        if (hostname->length)
251        {
252            switch (addr->sa_family)
253            {
254            case AF_INET:
255                {
256                    struct hostent  *hostent;
257                    char            *host;
258       
259                    hostent = gethostbyaddr (hostAddr.data, hostAddr.length, AF_INET);
260                    if (hostent)
261                    {
262                        XdmcpDisposeARRAY8 (hostname);
263                        host = hostent->h_name;
264                        XdmcpAllocARRAY8 (hostname, strlen (host));
265                        bcopy (host, hostname->data, hostname->length);
266                    }
267                }
268            }
269        }
270        if (!XdmcpAllocARRAY8 (&new->hostaddr, hostAddr.length))
271        {
272            free ((char *) new->fullname);
273            free ((char *) new);
274            return 0;
275        }
276        bcopy (hostAddr.data, new->hostaddr.data, hostAddr.length);
277        new->connectionType = connectionType;
278        new->hostname = *hostname;
279
280        *names = new;
281        new->next = 0;
282        NameTableSize++;
283    }
284    else
285    {
286        new = *names;
287        free (new->fullname);
288        XdmcpDisposeARRAY8 (&new->status);
289        XdmcpDisposeARRAY8 (hostname);
290    }
291    new->willing = willing;
292    new->status = *status;
293
294    hostname = &new->hostname;
295    fulllen = hostname->length;
296    if (fulllen < 30)
297        fulllen = 30;
298    new->fullname = malloc (fulllen + status->length + 10);
299    if (!new->fullname)
300    {
301        new->fullname = "Unknown";
302    }
303    else
304    {
305        sprintf (new->fullname, "%-30.*s %*.*s",
306                 hostname->length, hostname->data,
307                 status->length, status->length, status->data);
308    }
309    RebuildTable (NameTableSize);
310    return 1;
311}
312
313static
314DisposeHostname (host)
315    HostName    *host;
316{
317    XdmcpDisposeARRAY8 (&host->hostname);
318    XdmcpDisposeARRAY8 (&host->hostaddr);
319    XdmcpDisposeARRAY8 (&host->status);
320    free ((char *) host->fullname);
321    free ((char *) host);
322}
323
324static
325RemoveHostname (host)
326    HostName    *host;
327{
328    HostName    **prev, *hosts;
329
330    prev = &hostNamedb;;
331    for (hosts = hostNamedb; hosts; hosts = hosts->next)
332    {
333        if (hosts == host)
334            break;
335        prev = &hosts->next;
336    }
337    if (!hosts)
338        return;
339    *prev = host->next;
340    DisposeHostname (host);
341    NameTableSize--;
342    RebuildTable (NameTableSize);
343}
344
345static
346EmptyHostnames ()
347{
348    HostName    *hosts, *next;
349
350    for (hosts = hostNamedb; hosts; hosts = next)
351    {
352        next = hosts->next;
353        DisposeHostname (hosts);
354    }
355    NameTableSize = 0;
356    hostNamedb = 0;
357    RebuildTable (NameTableSize);
358}
359
360/* ARGSUSED */
361static void
362ReceivePacket (closure, source, id)
363    XtPointer   closure;
364    int         *source;
365    XtInputId   *id;
366{
367    XdmcpHeader     header;
368    ARRAY8          authenticationName;
369    ARRAY8          hostname;
370    ARRAY8          status;
371    int             saveHostname = 0;
372    struct sockaddr addr;
373    int             addrlen;
374
375    addrlen = sizeof (addr);
376    if (!XdmcpFill (socketFD, &buffer, &addr, &addrlen))
377        return;
378    if (!XdmcpReadHeader (&buffer, &header))
379        return;
380    if (header.version != XDM_PROTOCOL_VERSION)
381        return;
382    hostname.data = 0;
383    status.data = 0;
384    authenticationName.data = 0;
385    switch (header.opcode) {
386    case WILLING:
387        if (XdmcpReadARRAY8 (&buffer, &authenticationName) &&
388            XdmcpReadARRAY8 (&buffer, &hostname) &&
389            XdmcpReadARRAY8 (&buffer, &status))
390        {
391            if (header.length == 6 + authenticationName.length +
392                hostname.length + status.length)
393            {
394                if (AddHostname (&hostname, &status, &addr, header.opcode == (int) WILLING))
395                    saveHostname = 1;
396            }
397        }
398        XdmcpDisposeARRAY8 (&authenticationName);
399        break;
400    case UNWILLING:
401        if (XdmcpReadARRAY8 (&buffer, &hostname) &&
402            XdmcpReadARRAY8 (&buffer, &status))
403        {
404            if (header.length == 4 + hostname.length + status.length)
405            {
406                if (AddHostname (&hostname, &status, &addr, header.opcode == (int) WILLING))
407                    saveHostname = 1;
408
409            }
410        }
411        break;
412    default:
413        break;
414    }
415    if (!saveHostname)
416    {
417        XdmcpDisposeARRAY8 (&hostname);
418        XdmcpDisposeARRAY8 (&status);
419    }
420}
421
422RegisterHostaddr (addr, len, type)
423    struct sockaddr *addr;
424    int             len;
425    xdmOpCode       type;
426{
427    HostAddr            *host, **prev;
428
429    host = (HostAddr *) malloc (sizeof (HostAddr));
430    if (!host)
431        return;
432    host->addr = (struct sockaddr *) malloc (len);
433    if (!host->addr)
434    {
435        free ((char *) host);
436        return;
437    }
438    bcopy ((char *) addr, (char *) host->addr, len);
439    host->addrlen = len;
440    host->type = type;
441    for (prev = &hostAddrdb; *prev; prev = &(*prev)->next)
442        ;
443    *prev = host;
444    host->next = NULL;
445}
446
447/*
448 * Register the address for this host.
449 * Called with each of the names on the command line.
450 * The special name "BROADCAST" looks up all the broadcast
451 *  addresses on the local host.
452 */
453
454RegisterHostname (name)
455    char    *name;
456{
457    struct hostent      *hostent;
458    struct sockaddr_in  in_addr;
459    struct ifconf       ifc;
460    register struct ifreq *ifr;
461    struct sockaddr     broad_addr;
462    char                buf[2048];
463    int                 n;
464
465    if (!strcmp (name, BROADCAST_HOSTNAME))
466    {
467        ifc.ifc_len = sizeof (buf);
468        ifc.ifc_buf = buf;
469        if (ioctl (socketFD, (int) SIOCGIFCONF, (char *) &ifc) < 0)
470            return;
471        for (ifr = ifc.ifc_req, n = ifc.ifc_len / sizeof (struct ifreq); --n >= 0;
472            ifr++)
473        {
474            if (ifr->ifr_addr.sa_family != AF_INET)
475                continue;
476
477            broad_addr = ifr->ifr_addr;
478            ((struct sockaddr_in *) &broad_addr)->sin_addr.s_addr =
479                htonl (INADDR_BROADCAST);
480#ifdef SIOCGIFBRDADDR
481            {
482                struct ifreq    broad_req;
483   
484                broad_req = *ifr;
485                if (ioctl (socketFD, SIOCGIFFLAGS, (char *) &broad_req) != -1 &&
486                    (broad_req.ifr_flags & IFF_BROADCAST) &&
487                    (broad_req.ifr_flags & IFF_UP)
488                    )
489                {
490                    broad_req = *ifr;
491                    if (ioctl (socketFD, SIOCGIFBRDADDR, &broad_req) != -1)
492                        broad_addr = broad_req.ifr_addr;
493                    else
494                        continue;
495                }
496                else
497                    continue;
498            }
499#endif
500            in_addr = *((struct sockaddr_in *) &broad_addr);
501            in_addr.sin_port = htons (XDM_UDP_PORT);
502            RegisterHostaddr ((struct sockaddr *)&in_addr, sizeof (in_addr),
503                              BROADCAST_QUERY);
504        }
505    }
506    else
507    {
508#ifndef ishexdigit
509#define ishexdigit(c)   (isdigit(c) || 'a' <= (c) && (c) <= 'f')
510#endif
511
512        if (isascii (name[0]) && ishexdigit (name[0]))
513        {
514            if (!index (name, '.'))
515                FromHex (name, &in_addr.sin_addr.s_addr, strlen (name));
516            else
517                in_addr.sin_addr.s_addr = inet_addr (name);
518            if (in_addr.sin_addr.s_addr == -1)
519                return;
520            in_addr.sin_family = AF_INET;
521        }
522        else
523        {
524            hostent = gethostbyname (name);
525            if (!hostent)
526                return;
527            if (hostent->h_addrtype != AF_INET || hostent->h_length != 4)
528                return;
529            in_addr.sin_family = hostent->h_addrtype;
530            bcopy (hostent->h_addr, &in_addr.sin_addr, 4);
531        }
532        in_addr.sin_port = htons (XDM_UDP_PORT);
533        RegisterHostaddr ((struct sockaddr *)&in_addr, sizeof (in_addr),
534                          QUERY);
535    }
536}
537
538static ARRAYofARRAY8    AuthenticationNames;
539
540RegisterAuthenticationName (name, namelen)
541    char    *name;
542    int     namelen;
543{
544    ARRAY8Ptr   authName;
545    if (!XdmcpReallocARRAYofARRAY8 (&AuthenticationNames,
546                                    AuthenticationNames.length + 1))
547        return;
548    authName = &AuthenticationNames.data[AuthenticationNames.length-1];
549    if (!XdmcpAllocARRAY8 (authName, namelen))
550        return;
551    bcopy (name, authName->data, namelen);
552}
553
554InitXDMCP (argv)
555    char    **argv;
556{
557    int soopts = 1;
558    XdmcpHeader header;
559    int i;
560    int optlen;
561
562    header.version = XDM_PROTOCOL_VERSION;
563    header.opcode = (CARD16) BROADCAST_QUERY;
564    header.length = 1;
565    for (i = 0; i < (int)AuthenticationNames.length; i++)
566        header.length += 2 + AuthenticationNames.data[i].length;
567    XdmcpWriteHeader (&broadcastBuffer, &header);
568    XdmcpWriteARRAYofARRAY8 (&broadcastBuffer, &AuthenticationNames);
569
570    header.version = XDM_PROTOCOL_VERSION;
571    header.opcode = (CARD16) QUERY;
572    header.length = 1;
573    for (i = 0; i < (int)AuthenticationNames.length; i++)
574        header.length += 2 + AuthenticationNames.data[i].length;
575    XdmcpWriteHeader (&directBuffer, &header);
576    XdmcpWriteARRAYofARRAY8 (&directBuffer, &AuthenticationNames);
577    if ((socketFD = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
578        return 0;
579#ifdef SO_BROADCAST
580    soopts = 1;
581    if (setsockopt (socketFD, SOL_SOCKET, SO_BROADCAST, &soopts, sizeof (soopts)) < 0)
582        perror ("setsockopt");
583#endif
584   
585    XtAddInput (socketFD, (XtPointer) XtInputReadMask, ReceivePacket,
586                (XtPointer) 0);
587    while (*argv)
588    {
589        RegisterHostname (*argv);
590        ++argv;
591    }
592    pingTry = 0;
593    PingHosts ((XtPointer)NULL, (XtIntervalId *)NULL);
594    return 1;
595}
596
597Boolean
598Choose (h)
599    HostName    *h;
600{
601    if (app_resources.xdmAddress)
602    {
603        struct sockaddr_in  in_addr;
604        struct sockaddr *addr;
605        int             family;
606        int             len;
607        int             fd;
608        char            buf[1024];
609        XdmcpBuffer     buffer;
610        char            *xdm;
611
612        xdm = (char *) app_resources.xdmAddress->data;
613        family = (xdm[0] << 8) + xdm[1];
614        switch (family) {
615        case AF_INET:
616            in_addr.sin_family = family;
617            bcopy (xdm + 2, &in_addr.sin_port, 2);
618            bcopy (xdm + 4, &in_addr.sin_addr.s_addr, 4);
619            addr = (struct sockaddr *) &in_addr;
620            len = sizeof (in_addr);
621            break;
622        }
623        if ((fd = socket (family, SOCK_STREAM, 0)) == -1)
624        {
625            fprintf (stderr, "Cannot create response socket\n");
626            exit (REMANAGE_DISPLAY);
627        }
628        if (connect (fd, addr, len) == -1)
629        {
630            fprintf (stderr, "Cannot connect to xdm\n");
631            exit (REMANAGE_DISPLAY);
632        }
633        buffer.data = (BYTE *) buf;
634        buffer.size = sizeof (buf);
635        buffer.pointer = 0;
636        buffer.count = 0;
637        XdmcpWriteARRAY8 (&buffer, app_resources.clientAddress);
638        XdmcpWriteCARD16 (&buffer, (CARD16) app_resources.connectionType);
639        XdmcpWriteARRAY8 (&buffer, &h->hostaddr);
640        write (fd, buffer.data, buffer.pointer);
641        close (fd);
642    }
643    else
644    {
645        int i;
646
647        printf ("%u\n", h->connectionType);
648        for (i = 0; i < (int)h->hostaddr.length; i++)
649            printf ("%u%s", h->hostaddr.data[i],
650                    i == h->hostaddr.length - 1 ? "\n" : " ");
651    }
652}
653
654/* ARGSUSED */
655static void
656DoAccept (w, event, params, num_params)
657    Widget w;
658    XEvent *event;
659    String *params;
660    Cardinal *num_params;
661{
662    XawListReturnStruct *r;
663    HostName            *h;
664
665    r = XawListShowCurrent (list);
666    if (r->list_index == XAW_LIST_NONE)
667        XBell (XtDisplay (toplevel), 0);
668    else
669    {
670        for (h = hostNamedb; h; h = h->next)
671            if (!strcmp (r->string, h->fullname))
672            {
673                Choose (h);
674            }
675        exit (OBEYSESS_DISPLAY);
676    }
677}
678
679/* ARGSUSED */
680static void
681DoCheckWilling (w, event, params, num_params)
682    Widget w;
683    XEvent *event;
684    String *params;
685    Cardinal *num_params;
686{
687    XawListReturnStruct *r;
688    HostName            *h;
689   
690    r = XawListShowCurrent (list);
691    if (r->list_index == XAW_LIST_NONE)
692        return;
693    for (h = hostNamedb; h; h = h->next)
694        if (!strcmp (r->string, h->fullname))
695            if (!h->willing)
696                XawListUnhighlight (list);
697}
698
699/* ARGSUSED */
700static void
701DoCancel (w, event, params, num_params)
702    Widget w;
703    XEvent *event;
704    String *params;
705    Cardinal *num_params;
706{
707    exit (OBEYSESS_DISPLAY);
708}
709
710/* ARGSUSED */
711static void
712DoPing (w, event, params, num_params)
713    Widget w;
714    XEvent *event;
715    String *params;
716    Cardinal *num_params;
717{
718    EmptyHostnames ();
719    pingTry = 0;
720    PingHosts ((XtPointer)NULL, (XtIntervalId *)NULL);
721}
722
723static XtActionsRec app_actions[] = {
724    "Accept",       DoAccept,
725    "Cancel",       DoCancel,
726    "CheckWilling", DoCheckWilling,
727    "Ping",         DoPing,
728};
729
730main (argc, argv)
731    char    **argv;
732{
733    Arg         position[3];
734    Dimension   width, height;
735    Position    x, y;
736
737    toplevel = XtInitialize (argv[0], "Chooser", options, XtNumber(options), &argc, argv);
738
739    XtAddConverter(XtRString, XtRARRAY8, CvtStringToARRAY8, NULL, 0);
740
741    XtGetApplicationResources (toplevel, (XtPointer) &app_resources, resources,
742                               XtNumber (resources), NULL, (Cardinal) 0);
743
744    XtAddActions (app_actions, XtNumber (app_actions));
745    paned = XtCreateManagedWidget ("paned", panedWidgetClass, toplevel, NULL, 0);
746    label = XtCreateManagedWidget ("label", labelWidgetClass, paned, NULL, 0);
747    viewport = XtCreateManagedWidget ("viewport", viewportWidgetClass, paned, NULL, 0);
748    list = XtCreateManagedWidget ("list", listWidgetClass, viewport, NULL, 0);
749    box = XtCreateManagedWidget ("box", boxWidgetClass, paned, NULL, 0);
750    cancel = XtCreateManagedWidget ("cancel", commandWidgetClass, box, NULL, 0);
751    acceptit = XtCreateManagedWidget ("accept", commandWidgetClass, box, NULL, 0);
752    ping = XtCreateManagedWidget ("ping", commandWidgetClass, box, NULL, 0);
753
754    /*
755     * center ourselves on the screen
756     */
757    XtSetMappedWhenManaged(toplevel, FALSE);
758    XtRealizeWidget (toplevel);
759
760    XtSetArg (position[0], XtNwidth, &width);
761    XtSetArg (position[1], XtNheight, &height);
762    XtGetValues (toplevel, position, (Cardinal) 2);
763    x = (Position)(WidthOfScreen (XtScreen (toplevel)) - width) / 2;
764    y = (Position)(HeightOfScreen (XtScreen (toplevel)) - height) / 3;
765    XtSetArg (position[0], XtNx, x);
766    XtSetArg (position[1], XtNy, y);
767    XtSetValues (toplevel, position, (Cardinal) 2);
768
769    /*
770     * Run
771     */
772    XtMapWidget(toplevel);
773    InitXDMCP (argv + 1);
774    XtMainLoop ();
775    exit(0);
776    /*NOTREACHED*/
777}
778
779FromHex (s, d, len)
780    char    *s, *d;
781    int     len;
782{
783    int t;
784    while (len >= 2)
785    {
786#define HexChar(c)  ('0' <= (c) && (c) <= '9' ? (c) - '0' : (c) - 'a' + 10)
787        t = HexChar (*s) << 4;
788        s++;
789        t += HexChar (*s);
790        s++;
791        *d++ = t;
792        len -= 2;
793    }
794}
795
796/*ARGSUSED*/
797static void
798CvtStringToARRAY8 (args, num_args, fromVal, toVal)
799    XrmValuePtr args;
800    Cardinal    *num_args;
801    XrmValuePtr fromVal;
802    XrmValuePtr toVal;
803{
804    static ARRAY8Ptr    dest;
805    char        *s;
806    int         len;
807
808    dest = (ARRAY8Ptr) XtMalloc (sizeof (ARRAY8));
809    len = fromVal->size;
810    s = (char *) fromVal->addr;
811    if (!XdmcpAllocARRAY8 (dest, len >> 1))
812        XtStringConversionWarning ((char *) fromVal->addr, XtRARRAY8);
813    else
814    {
815        FromHex (s, (char *) dest->data, len);
816    }
817    toVal->addr = (caddr_t) &dest;
818    toVal->size = sizeof (ARRAY8Ptr);
819}
Note: See TracBrowser for help on using the repository browser.