]> git.sesse.net Git - rdpsrv/blobdiff - Xserver/lib/xtrans/Xtransam.c
Removed Xserver/ directory, it does nothing useful ATM.
[rdpsrv] / Xserver / lib / xtrans / Xtransam.c
diff --git a/Xserver/lib/xtrans/Xtransam.c b/Xserver/lib/xtrans/Xtransam.c
deleted file mode 100644 (file)
index a52e181..0000000
+++ /dev/null
@@ -1,2008 +0,0 @@
-/* $XConsortium: Xtransam.c,v 1.4 94/04/17 20:23:01 mor Exp $ */
-/* $XFree86: xc/lib/xtrans/Xtransam.c,v 3.1 1996/05/10 06:55:45 dawes Exp $ */
-/*
-
-Copyright (c) 1994  X Consortium
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of the X Consortium shall
-not be used in advertising or otherwise to promote the sale, use or
-other dealings in this Software without prior written authorization
-from the X Consortium.
-
-*/
-
-/* Copyright (c) 1994 Vrije Universiteit Amsterdam, Netherlands
- *
- * All Rights Reserved
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name Vrije Universiteit not be used
- * in advertising or publicity pertaining to distribution of the software
- * without specific, written prior permission.  The Vrije Universiteit
- * makes no representations about the suitability of this software for
- * any purpose.  It is provided "as is" without express or implied warranty.
- *
- * THE VRIJE UNIVERSITEIT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
- * NO EVENT SHALL THE VRIJE UNIVERSITEIT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
- * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * This is the Amoeba implementation of the X Transport service layer
- */
-
-#define event am_event_t
-#define interval am_interval_t
-#define port am_port_t
-#include <amoeba.h>
-#include <semaphore.h>
-#include <cmdreg.h>
-#include <stdcom.h>
-#include <stderr.h>
-#include <vc.h>
-#include <circbuf.h>
-#include <exception.h>
-#include <module/signals.h>
-#include <ampolicy.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <exception.h>
-#include <fault.h>
-#include <signal.h>
-#include <ctype.h>
-#include <module/name.h>
-#include <server/x11/Xamoeba.h>
-#include <server/ip/hton.h>
-#include <server/ip/types.h>
-#include <server/ip/gen/in.h>
-#include <server/ip/gen/tcp.h>
-#include <server/ip/tcpip.h>
-#include <server/ip/tcp_io.h>
-#include <server/ip/gen/tcp_io.h>
-#include <server/ip/gen/netdb.h>
-#include <server/ip/gen/inet.h>
-#undef event
-#undef interval
-#undef port
-
-extern char *strdup();
-
-/* a new family for Amoeba RPC connections */
-#define AF_AMOEBA      33
-#define FamilyAmoeba    33
-
-#define        MAX_TCPIP_RETRY 4
-#define        CIRCBUFSIZE     4096 /* was 1024 */
-
-/*
- * Amoeba channel description:
- */
-typedef struct _XAmChanDesc {
-    int                        state;          /* current state of connection */
-    int                        type;           /* type of connection */
-    int                        status;         /* status used by server */
-    signum             signal;         /* signal to kill TCP/IP reader */
-    semaphore          *sema;          /* select semaphore */
-    struct vc          *virtcirc;      /* virtual circuit for Amoeba RPC */
-    struct circbuf     *circbuf;       /* circular buffer for TCP/IP */
-    capability         chancap;        /* TCP/IP channel capability */
-    XtransConnInfo     conninfo;       /* back pointer to the connect info */
-} XAmChanDesc;
-
-/* Amoeba channel descriptor states */
-#define        ACDS_FREE       0               /* unused */
-#define        ACDS_USED       1               /* intermediate state */
-#define        ACDS_CLOSED     2               /* just closed */
-
-/* Amoeba channel types */
-#define        ACDT_TCPIP      1               /* TCP/IP connection */
-#define        ACDT_VIRTCIRC   2               /* Amoeba virtual circuit connection */
-
-
-#ifdef XSERV_t
-#include "dix.h" /* clients[] needed by AmFindReadyClients */
-#define Error(list) ErrorF list
-#define Fatal(list) FatalError list
-#else
-#define Error(list) printf list
-#define Fatal(list) { printf list; exit(1); }
-#endif
-
-#define dbprintf(list) /* printf list */
-#define doprintf(list) printf list /**/
-
-/*
- * First: utility functions.
- */
-
-#if defined(XSERV_t) || defined(FS_t)
-
-static semaphore main_sema;
-
-/* The X-server consists of one main thread, running the non re-entrant
- * X code, and a number of auxilary threads that take care of reading
- * the input streams, and input devices. The following set of routines
- * wake up the main thread when it has something to do.
- */
-void
-InitMainThread()
-{
-    sema_init(&main_sema, 0);
-}
-
-void
-WakeUpMainThread()
-{
-    sema_up(&main_sema);
-}
-
-int
-SleepMainThread(timeout)
-am_interval_t timeout;
-{
-    dbprintf(("Sleeping main thread timeout %d\n", timeout));
-    return (sema_trydown(&main_sema, timeout) == 0) ? 0 : -1;
-}
-
-
-static int init_waiters;
-static semaphore init_sema;
-
-void
-AmInitWaitFor()
-{
-    init_waiters = 0;
-    sema_init(&init_sema, 0);
-}
-
-/*
- * Force caller thread to wait until main has finished the initialization.
- */
-void
-WaitForInitialization()
-{
-    init_waiters++;
-    dbprintf(("Waiting for initialization (%d)\n", init_waiters));
-    sema_down(&init_sema);
-}
-
-void
-WakeupInitWaiters()
-{
-    /* wakeup threads in initial sleep */
-    if (init_waiters > 0) {
-       dbprintf(("%d waiters wait for something ...\n", init_waiters));
-       while (init_waiters-- > 0) {
-           sema_up(&init_sema);
-       }
-    }
-}
-
-#endif /* XSERV_t || FS_t */
-
-
-#define        THREAD_STACK_SIZE (8*1024)
-
-/*
- * Amoeba connection information is stored in, so called,
- * channel descriptors. Channel descriptors are identified
- * by their index in the table below.
- */
-static XAmChanDesc XAmChanDescriptors[OPEN_MAX];
-static void XAmCleanUpChanDesc(); /* forward */
-
-/*
- * Cleanup connection descriptors on a signal
- */
-static void
-XAmSignalCleanUpChanDesc(sig)
-    int sig;
-{
-    XAmCleanUpChanDesc();
-    _exit(sig | 0x80);
-}
-
-/*
- * Cleanup connection descriptors
- */
-static void
-XAmCleanUpChanDesc()
-{
-    register int i;
-
-    for (i = 0; i < OPEN_MAX; i++) {
-       switch (XAmChanDescriptors[i].type) {
-       case ACDT_TCPIP:
-           /* The Amoeba TCP/IP server is capability based, i.e.
-            * it uses capabilities to identify connections.  Since a
-            * capability is only destroyed when it has aged too much
-            * or is explicitly deleted, the connection it identifies
-            * will tend to exist for some while even if the client is
-            * already gone. To force connections to close this loop
-            * destroys all open TCP/IP connection. This loop us auto-
-            * matically executed when exit() is called.
-            */
-           std_destroy(&XAmChanDescriptors[i].chancap);
-           break;
-       case ACDT_VIRTCIRC:
-           /* Close the virtual circuit asynchronously, or otherwise
-            * we may hang for a minute under some (?) conditions.
-            */
-           vc_close(XAmChanDescriptors[i].virtcirc, VC_BOTH | VC_ASYNC);
-           break;
-       }
-       XAmChanDescriptors[i].state = ACDS_FREE;
-    }
-}
-
-/*
- * Allocate a channel descriptor
- */
-static XAmChanDesc *
-XAmAllocChanDesc()
-{
-    register int i;
-
-#ifndef XSERV_t
-
-    static int initialized = 0;
-
-    /*
-     * Since the TCP/IP server is capability based its connections exists
-     * even if the owner process is long gone. To overcome this nuisance,
-     * a sweep is made over the connection descriptors when exit() is
-     * called or when an un-catched (by application program) signal is 
-     * received.
-     */
-    if (!initialized) {
-       initialized = 1;
-       atexit(XAmCleanUpChanDesc);
-       if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
-           signal(SIGHUP, XAmSignalCleanUpChanDesc);
-       if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
-           signal(SIGQUIT, XAmSignalCleanUpChanDesc);
-       if (signal(SIGINT, SIG_IGN) != SIG_IGN)
-           signal(SIGINT, XAmSignalCleanUpChanDesc);
-       if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
-           signal(SIGTERM, XAmSignalCleanUpChanDesc);
-    }
-#endif
-
-    for (i = 0; i < OPEN_MAX; i++) {
-       if (XAmChanDescriptors[i].state == ACDS_FREE) {
-           XAmChanDescriptors[i].state = ACDS_USED;
-           XAmChanDescriptors[i].conninfo = NULL;
-           return &XAmChanDescriptors[i];
-       }
-    }
-    return NULL;
-}
-
-/*
- * Convert ``file descriptor'' to channel descriptor
- */
-static XAmChanDesc *
-XAmFdToChanDesc(fd)
-    int fd;
-{
-    if (fd >= 0 && fd < OPEN_MAX) {
-       return &XAmChanDescriptors[fd];
-    } else {
-       return NULL;
-    }
-}
-
-/*
- * Convert channel descriptor to ``file descriptor''
- */
-static int
-XAmChanDescToFd(chandesc)
-    XAmChanDesc *chandesc;
-{
-    return chandesc - XAmChanDescriptors;
-}
-
-/*
- * Free channel descriptor
- */
-static void
-XAmFreeChanDesc(chandesc)
-    XAmChanDesc *chandesc;
-{
-    if (chandesc->sema) {
-       xfree(chandesc->sema);
-       chandesc->sema = NULL;
-    }
-    chandesc->state = ACDS_FREE;
-}
-
-static void XAmReaderThread();
-
-static int
-MakeAmConnection(phostname, idisplay, familyp, saddrlenp, saddrp)
-    char *phostname;
-    int idisplay;
-    int *familyp;                      /* RETURN */
-    int *saddrlenp;                    /* RETURN */
-    char **saddrp;                     /* RETURN */
-{
-    capability xservercap;
-    char xserverpath[256];
-    XAmChanDesc *chandesc;
-    errstat err;
-
-    /* Amoeba requires a server hostname */
-    if (phostname == NULL || *phostname == '\0') {
-       fprintf(stderr, "MakeAmConnection: Display name expected\n");
-       return -1;
-    }
-
-    /* allocate channel descriptor */
-    chandesc = XAmAllocChanDesc();
-    if (chandesc == NULL) {
-       fprintf(stderr, "MakeAmConnection: Out of channel capabilities\n");
-       return -1;
-    }
-
-    /*
-     * There are two possible way to make a connection on Amoeba. Either
-     * through an Amoeba RPC or a TCP/IP connection. Depending on whether
-     * the X server resides on Amoeba, Amoeba RPC's are used. Otherwise
-     * it uses a TCP/IP connection.
-     */
-    (void)sprintf(xserverpath, "%s/%s:%d", DEF_XSVRDIR, phostname, idisplay);
-    if ((err = name_lookup(xserverpath, &xservercap)) == STD_OK) {
-       am_port_t vccaps[2];
-       bufsize size;
-       errstat err;
-       header hdr;
-
-       /* Amoeba virtual circuit connection */
-       chandesc->type = ACDT_VIRTCIRC;
-
-       /* get the two connection ports from the X-server */
-       hdr.h_command = AX_CONNECT;
-       hdr.h_port = xservercap.cap_port;
-       hdr.h_priv = xservercap.cap_priv;
-       size = trans(&hdr, NILBUF, 0, &hdr, (char *)vccaps, sizeof(vccaps));
-       if (ERR_STATUS(size)) {
-           err = ERR_CONVERT(size);
-       } else {
-           err = ERR_CONVERT(hdr.h_status);
-       }
-       if (err != STD_OK || size != sizeof(vccaps)) {
-           fprintf(stderr, "Xlib: connect to Amoeba X-server failed (%s)\n",
-                   err_why(err));
-           XAmFreeChanDesc(chandesc);
-           return -1;
-       }
-
-       /* setup an Amoeba virtual circuit */
-       chandesc->virtcirc =
-           vc_create(&vccaps[1], &vccaps[0], MAXBUFSIZE, MAXBUFSIZE);
-       if (chandesc->virtcirc == (struct vc *)NULL) {
-           fprintf(stderr, "Xlib: Amoeba virtual circuit create failed\n");
-           XAmFreeChanDesc(chandesc);
-           return -1;
-       }
-
-       /* Special Amoeba family type. For Amoeba no additional access control
-        * mechanism exists;  when you have the server capability, you have
-        * the access.  Just use a fake address.
-        */
-       *familyp = AF_AMOEBA;
-       *saddrp = strdup("Amoeba");
-       *saddrlenp = strlen(*saddrp);
-    } else {
-       char tcpname[256];
-       capability tcpcap;
-       ipaddr_t ipaddr;
-       char *tcpsvr;
-       nwio_tcpcl_t tcpcl;
-       nwio_tcpconf_t tcpconf;
-       XAmChanDesc **param;
-       int result;
-
-       /* Amoeba TCP/IP connection */
-       chandesc->type = ACDT_TCPIP;
-
-       /* lookup up TCP/IP server */
-       if ((tcpsvr = getenv("TCP_SERVER")) == NULL) {
-           tcpsvr = TCP_SVR_NAME;
-       }
-       if ((err = name_lookup(tcpsvr, &tcpcap)) != STD_OK) {
-           fprintf(stderr, "Xlib: Cannot lookup %s (%s)\n",
-                   tcpsvr, err_why(err));
-           std_destroy(&chandesc->chancap);
-           XAmFreeChanDesc(chandesc);
-           return -1;
-       }
-
-       /* establish TCP/IP connection */
-       if ((err = tcpip_open(&tcpcap, &chandesc->chancap)) != STD_OK) {
-           fprintf(stderr, "Xlib: Cannot open TCP/IP server on %s (%s)\n",
-                   tcpsvr, tcpip_why(err));
-           std_destroy(&chandesc->chancap);
-           XAmFreeChanDesc(chandesc);
-           return -1;
-       }
-
-       /* lookup TCP/IP hostname */
-       if (isdigit(phostname[0])) {
-           ipaddr = inet_addr(phostname);
-       } else {
-           struct hostent *hp = gethostbyname(phostname);
-           if (hp == NULL) {
-               fprintf(stderr, "Xlib: %s unknown host\n", phostname);
-               return -1;
-           }
-           memcpy(&ipaddr, hp->h_addr, hp->h_length);
-       }
-
-       /* set remote address/port on the TCP/IP connection */
-       tcpconf.nwtc_flags = NWTC_SET_RA|NWTC_SET_RP|NWTC_LP_SEL;
-       tcpconf.nwtc_remaddr = ipaddr;
-       tcpconf.nwtc_remport = htons(6000+idisplay);
-       if ((err = tcp_ioc_setconf(&chandesc->chancap, &tcpconf)) != STD_OK) {
-           fprintf(stderr, "Xlib: Cannot configure TCP/IP server (%s)\n",
-                   tcpip_why(err));
-           std_destroy(&chandesc->chancap);
-           XAmFreeChanDesc(chandesc);
-           return -1;
-       }
-
-       /* make the actual TCP/IP connection */
-       tcpcl.nwtcl_flags = 0;
-       if ((err = tcp_ioc_connect(&chandesc->chancap, &tcpcl)) != STD_OK) {
-           fprintf(stderr, "Xlib: Cannot make TCP/IP connection (%s)\n",
-                   tcpip_why(err));
-           std_destroy(&chandesc->chancap);
-           XAmFreeChanDesc(chandesc);
-           return -1;
-       }
-
-       /* start TCP/IP reader thread */
-       chandesc->signal = sig_uniq();
-       chandesc->circbuf = cb_alloc(CIRCBUFSIZE);
-       param = (XAmChanDesc **) xalloc(sizeof(XAmChanDesc *)); /* error checking? */
-       *param = chandesc;
-       result = thread_newthread(XAmReaderThread, THREAD_STACK_SIZE,
-                                 (char *)param, sizeof(XAmChanDesc *));
-       if (result == 0) {
-           fprintf(stderr, "Xlib: Cannot start reader thread\n");
-           std_destroy(&chandesc->chancap);
-           XAmFreeChanDesc(chandesc);
-           return -1;
-       }
-       threadswitch(); /* give reader a try */
-
-       /*
-        * Family type is set to Internet so that the .Xauthority
-        * files from Unix will work under Amoeba (for Unix displays).
-        */
-       *familyp = AF_INET;
-       *saddrlenp = sizeof(ipaddr_t);
-       *saddrp = xalloc(sizeof(ipaddr_t));
-       memcpy(*saddrp, (char *)&ipaddr, sizeof(ipaddr_t)); /* error checking? */
-    }
-
-    return XAmChanDescToFd(chandesc);
-}
-
-/*
- * The TCP/IP server silently assumes a maximum buffer size of 30000 bytes.
- */
-#define        TCPIP_BUFSIZE   16384
-
-static void
-XAMCloseChannel(chandesc)
-XAmChanDesc *chandesc;
-{
-    if (chandesc->state == ACDS_USED && chandesc->type == ACDT_TCPIP) {
-       cb_close(chandesc->circbuf);
-       chandesc->state = ACDS_CLOSED;
-    }
-}
-
-
-/*
- * Shutdown TCP/IP reader thread
- */
-static void
-XAmReaderSignalCatcher(sig, us, extra)
-    signum sig;
-    thread_ustate *us;
-    _VOIDSTAR extra;
-{
-    register XAmChanDesc *chandesc = (XAmChanDesc *)extra;
-
-    XAMCloseChannel(chandesc);
-    thread_exit();
-}
-
-/*
- * TCP/IP reader thread
- */
-static void
-XAmReaderThread(argptr, argsize)
-    void *argptr;
-    int argsize;
-{
-    register XAmChanDesc *chandesc;
-
-    chandesc = *((XAmChanDesc **)argptr);
-    (void) sig_catch(chandesc->signal, XAmReaderSignalCatcher,
-                    (_VOIDSTAR) chandesc);
-
-    while (chandesc->state == ACDS_USED) {
-       char buffer[CIRCBUFSIZE];
-       bufsize size;
-
-       size = tcpip_read(&chandesc->chancap, buffer, sizeof(buffer));
-       if (ERR_STATUS(size) || size == 0) {
-           if (size == 0) {
-               static char msg[] = "Xlib: TCP/IP channel closed\n";
-
-               write(2, msg, sizeof(msg));
-           } else {
-               fprintf(stderr, "Xlib: TCP/IP read failed (%s)\n",
-                       err_why(ERR_CONVERT(size)));
-           }
-           XAMCloseChannel(chandesc);
-           break;
-       }
-
-       if (cb_puts(chandesc->circbuf, buffer, size) != 0) {
-           fprintf(stderr, "Xlib: short write to circular buffer\n");
-           XAMCloseChannel(chandesc);
-       }
-    }
-
-    thread_exit();
-}
-
-/*
- * Wait until input is available or until the timer expires.
- */
-int
-TRANS(AmSelect)(ifd, timout)
-    int ifd;
-    int timout;
-{
-    XAmChanDesc *chandesc;
-    int n;
-
-    errno = 0;
-
-    chandesc = XAmFdToChanDesc(ifd);
-    if (chandesc == NULL || chandesc->state != ACDS_USED) {
-       errno = EBADF;
-       return -1;
-    }
-
-    if (chandesc->sema == NULL) {
-       /* Allocate semaphore to sleep on when no data is
-        * available. The underlying circular buffer and
-        * virtual circuit packages manage this semaphore.
-        */
-       chandesc->sema = (semaphore *) xalloc(sizeof(semaphore));
-       if (chandesc->sema == NULL) {
-           errno = ENOMEM;
-           return -1;
-       }
-
-       sema_init(chandesc->sema, 0);
-       switch (chandesc->type) {
-       case ACDT_TCPIP:
-           cb_setsema(chandesc->circbuf, chandesc->sema);
-           break;
-       case ACDT_VIRTCIRC:
-           vc_setsema(chandesc->virtcirc, chandesc->sema);
-           break;
-       }
-    }
-
-    switch (chandesc->type) {
-    case ACDT_TCPIP:
-       if ((n = cb_full(chandesc->circbuf)) != 0) {
-           if (n < 0) errno = EPIPE;
-           return n; /* includes error as well */
-       }
-       if (sema_trydown(chandesc->sema, timout) < 0) {
-           errno = EINTR;
-           return -1;
-       } else {
-           /* we down for all the bytes in AMRead, so undo the down */
-           sema_up(chandesc->sema);
-       }
-       if ((n = cb_full(chandesc->circbuf)) < 0) {
-           errno = EPIPE;
-           return -1;
-       }
-       return n;
-
-    case ACDT_VIRTCIRC:
-       if ((n = vc_avail(chandesc->virtcirc, VC_IN)) != 0) {
-           if (n < 0) errno = EPIPE;
-           return n; /* includes error as well */
-       }
-       if (sema_trydown(chandesc->sema, timout) < 0) {
-           errno = EINTR;
-           return -1;
-       } else {
-           /* we down for all the bytes in AMRead, so undo the down */
-           sema_up(chandesc->sema);
-       }
-       if ((n = vc_avail(chandesc->virtcirc, VC_IN)) < 0) {
-           errno = EPIPE;
-           return -1;
-       }
-       return n;
-    }
-
-    errno = EINVAL;
-    return -1;
-}
-
-/*
- * This function gets the local address of the transport and stores it in the
- * XtransConnInfo structure for the connection.
- */
-
-static int
-TRANS(AMGetAddr)(ciptr)
-XtransConnInfo ciptr;
-{
-    PRMSG(1,"AMGetAddr(%x)\n", ciptr, 0,0 );
-    PRMSG(1,"AMGetAddr: TODO\n", 0, 0, 0);
-
-    return -1;
-}
-
-
-/*
- * This function gets the remote address of the socket and stores it in the
- * XtransConnInfo structure for the connection.
- */
-
-static int
-TRANS(AMGetPeerAddr)(ciptr)
-XtransConnInfo ciptr;
-{
-    struct nwio_tcpconf tcpconf;
-    errstat err;
-    XAmChanDesc *chandesc;
-
-    PRMSG(2,"AMGetPeerAddr(%x)\n", ciptr, 0,0 );
-
-    chandesc = XAmFdToChanDesc(ciptr->fd);
-    if (chandesc == NULL || chandesc->state != ACDS_USED) {
-       errno = EBADF;
-       return -1;
-    }
-
-    switch (chandesc->type) {
-    case ACDT_TCPIP:
-       /* get the remote adress from the TCP/IP server */
-       if ((err = tcp_ioc_getconf(&chandesc->chancap, &tcpconf)) != STD_OK) {
-           PRMSG (1, "AMGetPeerAddr: Cannot get remote address (%d)\n",
-                  (int) err, 0, 0);
-           return -1;
-       }
-
-#if 0 /* debug */
-        {
-           struct hostent *remote;
-           char *hostname;
-
-           remote = gethostbyaddr((char *) &tcpconf.nwtc_remaddr,
-                                  sizeof(tcpconf.nwtc_remaddr), AF_INET);
-           if ((remote == NULL) || (remote->h_name == NULL)) {
-               hostname = inet_ntoa(tcpconf.nwtc_remaddr);
-           } else {
-               hostname = remote->h_name;
-           }
-           PRMSG (1, "AMGetPeerAddr: remote addr `%s'\n",
-                  hostname, 0, 0);
-       }
-#endif
-
-       ciptr->peeraddrlen = sizeof(tcpconf.nwtc_remaddr);
-       ciptr->peeraddr = (char *) xalloc (ciptr->peeraddrlen);
-       if (ciptr->peeraddr == NULL) {
-           PRMSG (1, "AMGetPeerAddr: Can't allocate peeraddr\n",
-                  0, 0, 0);
-           return -1;
-       }
-
-       memcpy (ciptr->peeraddr, &tcpconf.nwtc_remaddr, ciptr->peeraddrlen);
-       break;
-
-    case ACDT_VIRTCIRC:
-       /* for Amoeba virtual circuits just copy the client address */
-       if ((ciptr->peeraddr = (char *) xalloc (ciptr->addrlen)) == NULL) {
-           PRMSG (1, "AMGetPeerAddr: Can't allocate peeraddr\n",
-                  0, 0, 0);
-           return -1;
-       }
-
-       ciptr->peeraddrlen = ciptr->addrlen;
-       memcpy (ciptr->peeraddr, ciptr->addr, ciptr->peeraddrlen);
-       break;
-    }
-
-    return 0;
-}
-
-
-static XtransConnInfo
-TRANS(AMOpen)(device)
-char   *device;
-{
-    PRMSG(1,"AMOpen(%s)\n", device, 0,0 );
-    PRMSG(1,"AMOpen: TODO\n", 0, 0, 0);
-
-    return NULL;
-}
-
-
-static int
-TRANS(AMAddrToNetbuf)(tlifamily, host, port, netbufp)
-int            tlifamily;
-char           *host;
-char           *port;
-struct netbuf  *netbufp;
-{
-    PRMSG(1,"AMAddrToNetbuf(%d,%s,%s)\n", tlifamily, host, port );
-    PRMSG(1,"AMAddrToNetbuf: TODO\n", 0, 0, 0);
-
-    return -1;
-}
-
-/*
- * These functions are the interface supplied in the Xtransport structure
- */
-
-#ifdef TRANS_CLIENT
-
-static XtransConnInfo
-TRANS(AMOpenCOTSClient)(thistrans, protocol, host, port)
-Xtransport     *thistrans;
-char           *protocol;
-char           *host;
-char           *port;
-{
-    XtransConnInfo  ciptr;
-    XAmChanDesc    *chandesc;
-
-    PRMSG(2,"AMOpenCOTSClient(%s,%s,%s)\n", protocol, host, port );
-    
-    ciptr = (XtransConnInfo) xcalloc (1, sizeof(struct _XtransConnInfo));
-    if (ciptr == NULL) {
-        PRMSG (1, "AMOpenCotsClient: malloc failed\n", 0, 0, 0);
-        return NULL;
-    }
-
-    ciptr->fd = MakeAmConnection (host, 0 /* TODO */, &ciptr->family,
-                                 &ciptr->addrlen, &ciptr->addr);
-    if (ciptr->fd < 0) {
-       PRMSG(1,"AMOpenCOTSClient: Unable to make connection to %s\n",
-             host, 0,0 );
-       xfree(ciptr);
-       return NULL;
-    }
-
-    /* set the back pointer */
-    chandesc = XAmFdToChanDesc(ciptr->fd);
-    chandesc->conninfo = ciptr;
-
-    TRANS(AMGetPeerAddr)(ciptr);
-
-    PRMSG(2,"AMOpenCOTSClient: made connection to %s; fd = %d, family = %d\n",
-         host, ciptr->fd, ciptr->family);
-
-    return ciptr;
-}
-
-#endif /* TRANS_CLIENT */
-
-#if defined(XSERV_t) || defined(FS_t)
-
-/* The following defines come from osdep.h;
- * they should removed from there eventually.
- */
-
-/*
- * Some fundamental constants
- */
-#define CONNECTOR_STACK 4000    /* stack for connector task */
-#define DEVREADER_STACK 4000    /* stack for device reader */
-#define CREATOR_STACK   4000    /* stack for connection creator */
-#define MAXTASKS        100     /* Maximum # clients */
-
-/*
- * OsComm status bits
- */
-#define CONN_KILLED     0x1     /* Connection being closed */
-#define REQ_PUSHBACK    0x2     /* Request pushed back */
-#define IGNORE          0x4     /* True if client ignored */
-#define CONN_INIT       0x8     /* True if still initializing */
-#define CONN_ALIVE      0x10    /* True if living */
-
-
-#define REPLY_BUFSIZE   30000
-
-capability     X;                      /* X capability */
-char           *XServerHostName;       /* X server host name */
-char           *XTcpServerName;        /* TCP/IP server name */
-
-static XtransConnInfo NewConns[MAXTASKS]; /* new client connections */
-int                  nNewConns;          /* # of new clients */
-
-int            maxClient;              /* Highest allocated client fd + 1*/
-static int     minClient = 1;          /* Lowest allocated client fd */
-
-static char *
-OsCommStatus(status)
-    int status;
-{
-    static char buf[100];
-
-    buf[0] = '\0';
-    if (status == 0)
-       sprintf(buf, "NONE");
-    if (status & CONN_INIT)
-       sprintf(buf, "%s INIT", buf);
-    if (status & CONN_ALIVE)
-       sprintf(buf, "%s ALIVE", buf);
-    if (status & CONN_KILLED)
-       sprintf(buf, "%s KILLED", buf);
-    if (status & REQ_PUSHBACK)
-       sprintf(buf, "%s PUSHBACK", buf);
-    if (status & IGNORE)
-       sprintf(buf, "%s IGNORE", buf);
-    return buf;
-}
-
-static char *
-OsCommFamily(family)
-    int family;
-{
-    if (family == FamilyAmoeba) {
-       return "AMOEBA";
-    } else {
-       return "TCP/IP";
-    }
-}
-
-
-/*
- * Return status information about the open connections
- */
-static errstat
-ConnectionStatus(hdr, buf, size)
-    header *hdr;
-    char *buf;
-    int size;
-{
-    char       *begin, *end;
-    char       *bprintf();
-    int fd;
-    XAmChanDesc *chandesc;
-
-    begin = buf;
-    end = buf + size;
-
-
-    /* all active clients */
-    begin = bprintf(begin, end, "Active clients:\n");
-    for (fd = minClient; fd < maxClient; fd++) {
-       static XAmChanDesc *chandesc;
-
-       chandesc = XAmFdToChanDesc(fd);
-       if (chandesc != NULL && chandesc->conninfo != NULL) {
-           begin = bprintf(begin, end, "%d: Family %s, State %d, Status %s\n",
-                           fd, OsCommFamily(chandesc->conninfo->family),
-                           chandesc->state, OsCommStatus(chandesc->status));
-       }
-    }
-
-    if (begin == NULL) {
-       hdr->h_size = 0;
-       return STD_SYSERR;
-    } else {
-       hdr->h_size = begin - buf;
-       return STD_OK;
-    }
-}
-
-/*
- * Wakeup main thread if necessary
- */
-static void
-UnblockMain(fd)
-int fd;
-{
-    XAmChanDesc *chandesc;
-
-    chandesc = XAmFdToChanDesc(fd);
-    if (chandesc != NULL) {
-       if ((chandesc->status & IGNORE) == 0) {
-           WakeUpMainThread();
-       }
-    } else {
-       Error(("UnblockMain: invalid fd %d\n", fd));
-    }
-}
-
-static void
-TcpIpReaderSignalCatcher(sig, us, extra)
-    signum sig;
-    thread_ustate *us;
-    _VOIDSTAR extra;
-{
-    XAmChanDesc *chandesc = (XAmChanDesc *) extra;
-
-    if (chandesc->conninfo != NULL) {
-       dbprintf(("TcpIpReaderSignalCatcher(%d), number %d\n",
-                 sig, chandesc->conninfo->fd));
-       if (chandesc->signal != sig) {
-           Error(("TCP/IP Reader: Connection %s got unexpected signal %d\n",
-                  chandesc->conninfo->fd, sig));
-       }
-    }
-
-    chandesc->signal = -1;
-    thread_exit();
-}
-
-void
-TcpIpReaderThread(argptr, argsize)
-    void *argptr;
-    int argsize;
-{
-    XAmChanDesc *chandesc;
-
-    if (argsize != sizeof(XAmChanDesc *)) {
-       Fatal(("Internal error: TcpIpReaderThread incorrectly called\n"));
-    }
-
-    chandesc = * ((XAmChanDesc **) argptr);
-    (void) sig_catch(chandesc->signal, TcpIpReaderSignalCatcher,
-                    (_VOIDSTAR) chandesc);
-
-    for (;;) {
-       char buffer[MAXBUFSIZE];
-       bufsize size;
-
-       size = tcpip_read(&chandesc->chancap, buffer, sizeof(buffer));
-
-       dbprintf(("TcpIpReaderThread() read %d bytes\n", size));
-       if (ERR_STATUS(size)) {
-           Error(("TCP/IP read failed (%s)\n", tcpip_why(ERR_CONVERT(size))));
-           chandesc->status |= CONN_KILLED;
-           chandesc->status &= ~CONN_ALIVE;
-           chandesc->signal = -1;
-           thread_exit();
-       }
-
-       if (size == 0 || cb_puts(chandesc->circbuf, buffer, size)) {
-           if (size != 0) {
-               Error(("TCP/IP short write to circular buffer for %d\n",
-                      XAmChanDescToFd(chandesc)));
-           } else {
-               Error(("TCP/IP read failed for client %d\n",
-                      XAmChanDescToFd(chandesc)));
-           }
-
-           chandesc->status |= CONN_KILLED;
-           chandesc->status &= ~CONN_ALIVE;
-           chandesc->signal = -1;
-           thread_exit();
-       }
-       UnblockMain(XAmChanDescToFd(chandesc));
-    }
-}
-
-static XAmChanDesc *
-AllocClientChannel()
-{
-    XAmChanDesc *chandesc;
-    int fd;
-
-    chandesc = XAmAllocChanDesc();
-    if (chandesc == NULL) {
-       return NULL;
-    }
-
-    fd = XAmChanDescToFd(chandesc);
-    if (fd >= maxClient) {
-       maxClient = fd + 1;
-       dbprintf(("new max Client: %d\n", fd));
-    }
-    if (fd < minClient) {
-       minClient = fd;
-    }
-
-    return chandesc;
-}
-
-static errstat
-AmRegisterRPCconn(client_ports, server_ports)
-am_port_t client_ports[2];
-am_port_t server_ports[2];
-{
-    XAmChanDesc *chandesc;
-
-    if ((chandesc = AllocClientChannel()) == NULL) {
-       return STD_NOSPACE;
-    }
-
-    chandesc->type = ACDT_VIRTCIRC;
-    chandesc->virtcirc = vc_create(&server_ports[0], &server_ports[1],
-                                  MAXBUFSIZE, MAXBUFSIZE);
-    if (chandesc->virtcirc == NULL) {
-       Error(("Connection refused: No memory for virtual circuit\n"));
-       XAmFreeChanDesc(chandesc);
-       return STD_NOSPACE;
-    }
-
-    dbprintf(("Amoeba connection registered\n"));
-
-    vc_warn(chandesc->virtcirc, VC_IN, UnblockMain, XAmChanDescToFd(chandesc));
-    
-    chandesc->status = CONN_INIT;
-
-    /* cause WaitFor to call EstablishNewConnections: */
-    nNewConns++;
-    WakeUpMainThread();
-
-    return STD_OK;
-}
-
-static XAmChanDesc *
-XAmFetchConnectingClient()
-{
-    XAmChanDesc *chandesc;
-    int fd;
-
-    for (fd = minClient; fd < maxClient; fd++) {
-       chandesc = XAmFdToChanDesc(fd);
-
-       if (chandesc->status & CONN_INIT) {
-           Error(("Client %d is connecting\n", fd));
-           chandesc->status &= ~CONN_INIT;
-           return chandesc;
-       }
-    }
-
-    return NULL;
-}
-
-static errstat
-AmRegisterTCPconn(chancap)
-capability *chancap;
-{
-    XAmChanDesc *chandesc, **param;
-
-    if ((chandesc = AllocClientChannel()) == NULL) {
-       return STD_NOSPACE;
-    }
-    
-    chandesc->type = ACDT_TCPIP;
-    chandesc->chancap = *chancap;
-
-    if ((chandesc->circbuf = cb_alloc(MAXBUFSIZE)) == NULL) {
-       Error(("TCPconn refused: No memory for circular buffer\n"));
-       XAmFreeChanDesc(chandesc);
-       return STD_NOSPACE;
-    }
-
-    chandesc->signal = sig_uniq();
-    param = (XAmChanDesc **) xalloc(sizeof(XAmChanDesc *)); /* error checking? */
-    *param = chandesc;
-    if (thread_newthread(TcpIpReaderThread, MAXBUFSIZE + CONNECTOR_STACK,
-                        (char *)param, sizeof(XAmChanDesc *)) == 0)
-    {
-       Error(("TCPconn refused: Cannot start reader thread\n"));
-       cb_close(chandesc->circbuf);
-       cb_free(chandesc->circbuf);
-       XAmFreeChanDesc(chandesc);
-       return STD_NOSPACE;
-    }
-
-    dbprintf(("TCP connection registered\n"));
-
-    chandesc->status = CONN_INIT;
-
-    /* cause WaitFor to call EstablishNewConnections: */
-    nNewConns++;
-    WakeUpMainThread();
-
-    return STD_OK;
-}
-
-
-/*
- * Establishing a new connection is done in two phases. This thread does the
- * first part. It filters out bad connect requests. A new rendevous port is
- * sent to the client and the main loop is informed if there is a legal
- * request. The sleep synchronizes with the main loop so that the paperwork
- * is finished for the current connect request before the thread is ready to
- * accept another connect.
- */
-static void
-AmConnectorThread()
-{
-    header     req, rep;
-    am_port_t  client_ports[2];
-    am_port_t  server_ports[2];
-    short      s;
-    char       *repb;
-    extern     CreateNewClient();
-
-    WaitForInitialization();
-    dbprintf(("AmConnectorThread() running ...\n"));
-    if ((repb = (char *)xalloc(REPLY_BUFSIZE)) == NULL) {
-       Fatal(("Amoeba connector thread: malloc failed"));
-    }
-    for (;;) {
-       do {
-           req.h_port = X.cap_port;
-           s = getreq(&req, NILBUF, 0);
-       } while (ERR_CONVERT(s) == RPC_ABORTED);
-       if (ERR_STATUS(s))
-           Fatal(("Amoeba connector thread: getreq failed"));
-
-       /* TODO: check privilege fields here */
-
-       dbprintf(("AmConnectorThread() accepting a request\n"));
-
-       switch (req.h_command) {
-
-       case STD_INFO:
-           rep.h_status = STD_OK;
-           sprintf(repb, "X11R6 server on %s", XServerHostName);
-           rep.h_size = strlen(repb);
-           putrep(&rep, repb, rep.h_size);
-           break;
-
-       case STD_STATUS:
-           rep.h_status = ConnectionStatus(&rep, repb, REPLY_BUFSIZE);
-           putrep(&rep, repb, rep.h_size);
-           break;
-
-#ifdef XSERV_t
-       case AX_SHUTDOWN:
-           rep.h_status = STD_OK;
-           putrep(&rep, NILBUF, 0);
-           GiveUp(SIGTERM);
-           break;
-
-       case AX_REINIT:
-           rep.h_status = STD_OK;
-           putrep(&rep, NILBUF, 0);
-           AutoResetServer(SIGINT);
-           break;
-#endif
-
-       case AX_CONNECT:
-           uniqport(&client_ports[0]);
-           uniqport(&server_ports[1]);
-           priv2pub(&client_ports[0], &server_ports[0]);
-           priv2pub(&server_ports[1], &client_ports[1]);
-
-           rep.h_status = AmRegisterRPCconn(client_ports, server_ports);
-           if (rep.h_status == STD_OK) {
-               putrep(&rep, (bufptr)client_ports, 2*sizeof(am_port_t));
-           } else {
-               putrep(&rep, NILBUF, 0);
-           }
-           break;
-
-       default:
-           rep.h_status = STD_COMBAD;
-           putrep(&rep, NILBUF, 0);
-           break;
-       }
-    }
-}
-
-#ifdef XSERV_t
-
-/*
- * To prevent the X-server from generating lots of error messages,
- * in case the server is gone or when its full.
- */
-#define        LOOP_OPEN       1
-#define        LOOP_SETCONF    2
-#define        LOOP_LISTEN     4
-
-extern char *display;          /* The display number */
-
-/*
- * The TCP/IP connector thread listens to a well known port (6000 +
- * display number) for connection request. When such a request arrives
- * it allocates a communication structure and a reader thread. This
- * thread prevents the main loop from blocking when there's no data.
- */
-static void
-AmTCPConnectorThread()
-{
-    capability         svrcap, chancap;
-    nwio_tcpconf_t     tcpconf;
-    nwio_tcpcl_t       tcpconnopt;
-    char               name[BUFSIZ];
-    errstat            err;
-    int                        result;
-    int                        looping = 0;
-
-    strncpy(name, XTcpServerName, BUFSIZ);
-    if ((err = name_lookup(name, &svrcap)) != STD_OK) {
-       sprintf(name, "%s/%s", TCP_SVR_NAME, XTcpServerName);
-       if ((err = name_lookup(name, &svrcap)) != STD_OK)
-           Fatal(("Lookup %s failed: %s\n", XTcpServerName, err_why(err)));
-    }
-
-    WaitForInitialization();
-    dbprintf(("AmTCPConnectorThread() running ...\n"));
-
-    for (;;) {
-       /*
-        * Listen to TCP/IP port X_TCP_PORT + display for connections.
-        * Some interesting actions have to be taken to keep this connection
-        * alive and kicking :-)
-        */
-       if ((err = tcpip_open(&svrcap, &chancap)) != STD_OK) {
-           /* the server probably disappeared, just wait for it to return */
-           if (looping & LOOP_OPEN) {
-               Error(("TCP/IP open failed: %s\n", tcpip_why(err)));
-               looping |= LOOP_OPEN;
-           }
-           sleep(60);
-           (void) name_lookup(name, &svrcap);
-           continue;
-       }
-       looping &= ~LOOP_OPEN;
-
-       tcpconf.nwtc_locport = htons(X_TCP_PORT + atoi(display));
-       tcpconf.nwtc_flags = NWTC_EXCL | NWTC_LP_SET | NWTC_UNSET_RA | 
-                                                               NWTC_UNSET_RP;
-       if ((err = tcp_ioc_setconf(&chancap, &tcpconf)) != STD_OK) {
-           /* couldn't configure, probably server space problem */
-           if (looping & LOOP_SETCONF) {
-               Error(("TCP/IP setconf failed: %s\n", tcpip_why(err)));
-               looping |= LOOP_SETCONF;
-           }
-           std_destroy(&chancap);
-           sleep(60);
-           continue;
-       }
-       looping &= ~LOOP_SETCONF;
-
-       tcpconnopt.nwtcl_flags = 0;
-       if ((err = tcp_ioc_listen(&chancap, &tcpconnopt)) != STD_OK) {
-           /* couldn't listen, definitely a server memory problem */
-           if (looping & LOOP_LISTEN) {
-               Error(("TCP/IP listen failed: %s\n", tcpip_why(err)));
-               looping |= LOOP_LISTEN;
-           }
-           std_destroy(&chancap);
-           sleep(60);
-           continue;
-       }
-       looping &= ~LOOP_LISTEN;
-
-       if ((err = tcpip_keepalive_cap(&chancap)) != STD_OK) {
-           Error(("TCP/IP keep alive failed: %s\n", tcpip_why(err)));
-           std_destroy(&chancap);
-           continue;
-       }
-
-       err = AmRegisterTCPconn(&chancap);
-       if (err != STD_OK) {
-           Error(("AmRegisterTCPconn failed (%s)\n", err_why(err)));
-           std_destroy(&chancap);
-       }
-    }
-}
-
-static void
-AmStartXserverThreads(chandesc)
-XAmChanDesc *chandesc;
-{
-    char               host[100];
-    errstat            err;
-    capability         pubX;
-    static int         threadsStarted = 0;
-
-    /*
-     * Each time the server is reset this routine is called to
-     * setup the new well known sockets. For Amoeba we'll just
-     * keep using the old threads that are already running.
-     */
-    if (!threadsStarted) {
-       threadsStarted = 1;
-
-       /*
-        * Create a new capability for this X server
-        */
-       if (XServerHostName == NULL)
-           XServerHostName = getenv("XHOST");
-       if (XServerHostName == NULL) {
-           Fatal(("XHOST not set, or server host name not given\n"));
-       }
-       sprintf(host, "%s/%s:%s", DEF_XSVRDIR, XServerHostName, display);
-
-       uniqport(&X.cap_port);
-       priv2pub(&X.cap_port, &pubX.cap_port);
-       (void) name_delete(host);
-       if ((err = name_append(host, &pubX)) != 0) {
-           Error(("Cannot create capability %s: %s\n", host, err_why(err)));
-           exit(1);
-       }
-
-       /* Allow WaitFor module to initialize */
-       AmInitWaitFor();
-
-       /* Also, initialize main thread locking */
-       InitMainThread();
-
-       /* Initialize and start IOP reader thread */
-       InitializeIOPServerReader();
-
-       /* Start native Amoeba service threads */
-       if (thread_newthread(AmConnectorThread, CONNECTOR_STACK, 0, 0) <= 0) {
-           Fatal(("Cannot start Amoeba connector thread\n"));
-       }
-       if (thread_newthread(AmConnectorThread, CONNECTOR_STACK, 0, 0) <= 0) {
-           Fatal(("Cannot start Amoeba connector thread\n"));
-       }
-       chandesc->type = ACDT_VIRTCIRC;
-       chandesc->status = CONN_ALIVE;
-
-       /*
-        * Start TCP/IP service threads
-        */
-       if (XTcpServerName) {
-           if (thread_newthread(AmTCPConnectorThread,
-                                CONNECTOR_STACK, 0, 0) <= 0)
-               Fatal(("Cannot start TCP connector thread\n"));
-           if (thread_newthread(AmTCPConnectorThread,
-                                CONNECTOR_STACK, 0, 0) <= 0)
-               Fatal(("Cannot start TCP connector thread\n"));
-       }
-    }
-}
-
-int
-AmFindReadyClients(pClientsReady, mask)
-int *pClientsReady;
-long *mask;
-{
-    /* Check for clients needing attention.  They may have input,
-     * or they might be dying.  Ignore the clients not present in
-     * the file descriptor bit vector `mask'.  This is used for
-     * implementing server grabs.
-     * Returns the number of clients having data for us.
-     */
-    extern int ConnectionTranslation[];
-    XAmChanDesc *chandesc;
-    int fd;
-    int nready;
-
-    /* Since we're scheduled non-preemptively by default, allow the
-     * listener threads to run first, if needed:
-     */
-    threadswitch();
-
-    nready = 0;
-    for (fd = minClient; fd < maxClient; fd++) {
-       int which;
-       int n;
-
-       if (fd > 0 && (fd % 32) == 0) {
-           /* switch to next fd mask */
-           mask++;
-       }
-
-       if ((*mask & (1L << fd)) == 0) {
-           dbprintf(("skip %d\n", fd));
-           continue;
-       }
-
-       chandesc = XAmFdToChanDesc(fd);
-       if (chandesc->state != ACDS_USED) {
-           dbprintf(("AmFindReady: fd %d not in use\n", fd));
-           continue;
-       }
-
-       which = ConnectionTranslation[fd];
-       dbprintf(("checking client %d (fd %d) of %d\n",
-                 fd, which, maxClient));
-
-       if (chandesc->status & CONN_KILLED) {
-           dbprintf(("conn killed; close client with fd %d\n", fd));
-           CloseDownClient(clients[which]);
-           chandesc->status &= ~(CONN_KILLED | CONN_ALIVE);
-           continue;
-       }
-
-       if ((chandesc->status & CONN_ALIVE) == 0) {
-           dbprintf(("conn with %d is not alive\n", fd));
-           continue;
-       }
-
-       /* see if there is data available */
-       switch (chandesc->type) {
-       case ACDT_TCPIP:
-           n = cb_full(chandesc->circbuf);
-           break;
-       case ACDT_VIRTCIRC:
-           n = vc_avail(chandesc->virtcirc, VC_IN);
-           break;
-       default:
-           n = -1;
-       }
-
-       if (n < 0) {
-           dbprintf(("avail %d; close client %d\n", n, which));
-           CloseDownClient(clients[which]);
-           continue;
-       } else {
-           if (n > 0) {
-               *pClientsReady++ = which;
-               nready++;
-               dbprintf(("client %d has %d bytes available\n", which, n));
-           } else {
-               dbprintf(("client %d has no data available\n", which, n));
-           }
-       }
-
-       /* Clients that already have (possibly inserted) data are found
-        * with help from io.c (the ClientsWithData bit array).
-        */
-    }
-
-    return nready;
-}
-
-#endif /* XSERV_t */
-
-#endif /* XSERV_t || FS_t */
-
-static
-TRANS(AmSetAddr)(ciptr, chandesc)
-    XtransConnInfo  ciptr;
-    XAmChanDesc    *chandesc;
-{
-    switch (chandesc->type) {
-    case ACDT_TCPIP:
-       /* should really ask the TCP/IP server */
-       ciptr->family = AF_INET;
-       ciptr->addr = strdup("XXXXTODO");
-       ciptr->addrlen = strlen("XXXXTODO");
-       break;
-    case ACDT_VIRTCIRC:
-       /* For Amoeba connections the adress is not really used,
-        * so just fake something
-        */
-       ciptr->family = AF_AMOEBA;
-       ciptr->addr = strdup("Amoeba");
-       ciptr->addrlen = strlen(ciptr->addr);
-       break;
-    }
-}
-
-#ifdef TRANS_SERVER
-
-static XtransConnInfo
-TRANS(AMOpenCOTSServer)(thistrans, protocol, given_host, port)
-Xtransport     *thistrans;
-char           *protocol;
-char           *given_host;
-char           *port;
-{
-    XAmChanDesc    *chandesc;
-    XtransConnInfo  ciptr;
-
-    PRMSG(2,"AMOpenCOTSServer(%s,%s,%s)\n", protocol, given_host, port);
-
-    ciptr = (XtransConnInfo) xcalloc (1, sizeof(struct _XtransConnInfo));
-    if (ciptr == NULL) {
-        PRMSG (1, "AMOpenCotsClient: malloc failed\n", 0, 0, 0);
-        return NULL;
-    }
-
-    chandesc = XAmAllocChanDesc();
-    if (chandesc == NULL) {
-       return NULL;
-    }
-
-#ifdef XSERV_t
-    AmStartXserverThreads(chandesc);
-#endif
-
-    chandesc->conninfo = ciptr;
-    ciptr->fd = XAmChanDescToFd(chandesc);
-
-    TRANS(AmSetAddr)(ciptr, chandesc);
-    TRANS(AMGetPeerAddr)(ciptr);
-
-    return ciptr;
-}
-
-#endif /* TRANS_SERVER */
-
-
-#ifdef TRANS_CLIENT
-
-static XtransConnInfo
-TRANS(AMOpenCLTSClient)(thistrans, protocol, host, port)
-Xtransport     *thistrans;
-char           *protocol;
-char           *host;
-char           *port;
-{
-    XtransConnInfo     ciptr;
-    int                i;
-    
-    PRMSG(1,"AMOpenCLTSClient(%d,%s,%s)\n", protocol, host, port );
-    /* TODO */
-    return NULL;
-}                      
-
-#endif /* TRANS_CLIENT */
-
-
-#ifdef TRANS_SERVER
-
-static XtransConnInfo
-TRANS(AMOpenCLTSServer)(thistrans, protocol, host, port)
-Xtransport     *thistrans;
-char           *protocol;
-char           *host;
-char           *port;
-{
-    XtransConnInfo     ciptr;
-    int                i;
-    
-    PRMSG(1,"AMOpenCLTSServer(%d,%s,%s)\n", protocol, host, port );
-    /* TODO */
-    return NULL;
-}                      
-
-static int
-TRANS(AMResetListener)(ciptr)
-XtransConnInfo ciptr;
-{
-    PRMSG(2,"AMResetListener()\n", 0, 0, 0 );
-
-    /* nothing to do? */
-    return 0;
-}
-
-#endif /* TRANS_SERVER */
-
-static
-TRANS(AMSetOption)(ciptr, option, arg)
-XtransConnInfo ciptr;
-int            option;
-int            arg;
-{
-    PRMSG(1,"AMSetOption(%d,%d,%d)\n", ciptr->fd, option, arg );
-    /* TODO */
-    return -1;
-}
-
-
-#ifdef TRANS_SERVER
-
-static
-TRANS(AMCreateListener)(ciptr, req)
-XtransConnInfo ciptr;
-char          *req;
-{
-    PRMSG(2,"AMCreateListener(%x->%d,%x)\n", ciptr, ciptr->fd, req );
-
-    /* Listener threads are already created at this point */
-    return 0;
-}
-
-
-static XtransConnInfo
-TRANS(AMAccept)(ciptr)
-XtransConnInfo ciptr;
-{
-    XAmChanDesc    *chandesc;
-    XtransConnInfo  newciptr;
-
-    PRMSG(2,"AMAccept(%x->%d)\n", ciptr, ciptr->fd, 0 );
-
-#if defined(XSERV_t) || defined(FS_t)
-    chandesc = XAmFetchConnectingClient();
-    if (chandesc == NULL) {
-        PRMSG (1, "AMAccept: no client waiting?\n", 0, 0, 0);
-        return NULL;
-    }
-    nNewConns--;
-
-    newciptr = (XtransConnInfo) xcalloc (1, sizeof(struct _XtransConnInfo));
-    if (newciptr == NULL)
-    {
-        PRMSG (1, "AMAccept: malloc failed\n", 0, 0, 0);
-        return NULL;
-    }
-
-    newciptr->fd = XAmChanDescToFd(chandesc);
-    chandesc->conninfo = newciptr;
-    chandesc->status |= CONN_ALIVE;
-
-    PRMSG(2,"AMAccept: OK: (%x->%d)\n", newciptr, newciptr->fd, 0 );
-
-    TRANS(AmSetAddr)(newciptr, chandesc);
-    TRANS(AMGetPeerAddr)(newciptr);
-    
-    return newciptr;
-#else
-    return NULL;
-#endif
-}
-
-#endif /* TRANS_SERVER */
-
-
-#ifdef TRANS_CLIENT
-
-static
-TRANS(AMConnect)(ciptr, host, port)
-XtransConnInfo ciptr;
-char           *host;
-char           *port;
-{
-    /* If this function is called, we are already connected */
-    PRMSG(2, "AMConnect(%d,%s)\n", ciptr->fd, host, 0);
-    return 0;
-}
-
-#endif /* TRANS_CLIENT */
-
-
-int
-TRANS(AmFdBytesReadable)(fd, count)
-int fd;
-BytesReadable_t        *count;
-{
-    register XAmChanDesc *chandesc;
-
-    PRMSG(2, "AmFdBytesReadable(%d,%x): ", fd, count, 0 );
-
-#ifndef XSERV_t
-    /* give reader threads a chance: */
-    threadswitch();
-#endif
-
-    errno = 0;
-    chandesc = XAmFdToChanDesc(fd);
-    if (chandesc == NULL || chandesc->state != ACDS_USED) {
-       errno = EBADF;
-       *count = 0;
-       return -1;
-    }
-
-    switch (chandesc->type) {
-    case ACDT_TCPIP:
-       *count = cb_full(chandesc->circbuf);
-       break;
-    case ACDT_VIRTCIRC:
-       *count = vc_avail(chandesc->virtcirc, VC_IN);
-       break;
-    }
-
-    if (*count < 0) {
-       errno = (chandesc->state == ACDS_CLOSED) ? EINTR : EPIPE;
-       *count = 0;
-       return -1;
-    }
-
-    PRMSG(2, "AMFdBytesReadable: %d\n", *count, 0, 0 );
-
-    return 0;
-}
-
-static
-TRANS(AMBytesReadable)(ciptr, count)
-XtransConnInfo ciptr;
-BytesReadable_t        *count;
-{
-    return TRANS(AmFdBytesReadable)(ciptr->fd, count);
-}
-
-
-static
-TRANS(AMRead)(ciptr, buf, count)
-XtransConnInfo ciptr;
-char           *buf;
-int            count;
-{
-    int fdi;
-    register XAmChanDesc *chandesc;
-    register int rv;
-    BytesReadable_t avail;
-
-    fdi = ciptr->fd;
-    PRMSG(2, "AMRead(%d,%x,%d)\n", ciptr->fd, buf, count );
-
-    errno = 0;
-    chandesc = XAmFdToChanDesc(fdi);
-    if (chandesc == NULL || chandesc->state != ACDS_USED) {
-       errno = EBADF;
-       return -1;
-    }
-
-    /* do a non-blocking read (maybe only conditionally?) */
-    if ((TRANS(AMBytesReadable)(ciptr, &avail)) == 0) {
-       if (avail <= 0) {
-           PRMSG(2, "AMRead: nothing available yet\n", 0, 0, 0);
-           errno = EAGAIN;
-           return 0;
-       } else if (count > avail) {
-           PRMSG(2, "AMRead(%d): only %d of %d available\n",
-                 ciptr->fd, avail, count);
-           count = avail; /* just read amount available */
-       }
-    } else {
-       PRMSG(1, "AMRead: ...BytesReadable failed\n", 0, 0, 0);
-       return -1;
-    }
-
-    switch (chandesc->type) {
-    case ACDT_TCPIP:
-       rv = cb_gets(chandesc->circbuf, buf, count, count);
-       if (rv != count) {
-           if (rv == 0) {
-               fprintf(stderr, "Xlib: Cannot read circbuf\n");
-               errno = EPIPE;
-               rv = -1;
-           } else {
-               fprintf(stderr, "Xlib: Cannot read circbuf (%d)\n", rv);
-           }
-       }
-       break;
-
-    case ACDT_VIRTCIRC:
-       rv = vc_readall(chandesc->virtcirc, buf, count);
-       if (rv < 0) {
-           fprintf(stderr, "Xlib: Cannot read virtual circuit\n");
-           errno = EPIPE;
-           rv = -1;
-       }
-       break;
-    }
-
-    /* The circular buffer writer will only UP the semaphore when
-     * characters are available; we have to down it ourselfs.
-     */
-    if (chandesc->sema && rv > 0)
-       sema_mdown(chandesc->sema, rv);
-
-    PRMSG(2, "AMRead: %d bytes\n", rv, 0, 0);
-
-    return rv;
-}
-
-
-static
-TRANS(AMWrite)(ciptr, buf, count)
-XtransConnInfo ciptr;
-char           *buf;
-int            count;
-{
-    register XAmChanDesc *chandesc;
-    register int written;
-    
-    PRMSG(2, "AMWrite(%d,%x,%d)\n", ciptr->fd, buf, count );
-
-    errno = 0;
-    written = 0;
-
-    chandesc = XAmFdToChanDesc(ciptr->fd);
-    if (chandesc == NULL || chandesc->state != ACDS_USED) {
-       errno = EBADF;
-       return -1;
-    }
-
-    switch (chandesc->type) {
-    case ACDT_TCPIP:
-       while (count > 0) {
-           bufsize bsize;
-           int wrcnt;
-
-           wrcnt = count > TCPIP_BUFSIZE ? TCPIP_BUFSIZE : count;
-           bsize = tcpip_write(&chandesc->chancap, buf, wrcnt);
-           if (ERR_STATUS(bsize)) {
-               fprintf(stderr, "Xlib: TCP/IP write failed (%s)\n",
-                       tcpip_why(ERR_CONVERT(bsize)));
-               errno = EPIPE;
-               return -1;
-           }
-           if (bsize != wrcnt) {
-               fprintf(stderr,
-                       "Xlib: TCP/IP write failed (expected %d, wrote %d)\n",
-                       (int)bsize, wrcnt);
-               errno = EPIPE;
-               return -1;
-           }
-           buf += bsize;
-           count -= (int) bsize;
-           written += (int) bsize;
-       }
-       break;
-
-    case ACDT_VIRTCIRC:
-       if ((written = vc_write(chandesc->virtcirc, buf, count)) < 0) {
-           fprintf(stderr, "Xlib: virtual circuit write failed\n");
-           errno = EPIPE;
-           return -1;
-       }
-       break;
-    }
-
-    return written;
-}
-
-
-static
-TRANS(AMReadv)(ciptr, iov, n)
-XtransConnInfo ciptr;
-struct iovec   *iov;
-int            n;
-{
-    int i;
-    int count = 0, thiscount;
-
-    PRMSG(2, "AMReadv(%d,%x,%d)\n", ciptr->fd, ciptr, n );
-
-    for (i = 0; i < n; i++, iov++) {
-       if (iov->iov_len) {
-           thiscount = TRANS(AMRead)(ciptr, iov->iov_base, iov->iov_len);
-           if (thiscount < 0) return thiscount;
-           count += thiscount;
-           if (thiscount < iov->iov_len) break;
-       }
-    }
-
-    return count;
-}
-
-
-static
-TRANS(AMWritev)(ciptr, iov, n)
-XtransConnInfo ciptr;
-struct iovec   *iov;
-int            n;
-{
-    int i;
-    int count = 0, thiscount;
-
-    PRMSG(2, "AMWritev(%d,%x,%d)\n", ciptr->fd, iov, n );
-
-    for (i = 0; i < n; i++, iov++) {
-       if (iov->iov_len) {
-           thiscount = TRANS(AMWrite)(ciptr, iov->iov_base, iov->iov_len);
-           if (thiscount < 0)
-               return thiscount;
-           count += thiscount;
-           if (thiscount < iov->iov_len) break;
-       }
-    }
-
-    return count;
-}
-
-
-static
-TRANS(AMDisconnect)(ciptr)
-XtransConnInfo ciptr;
-{
-    register XAmChanDesc *chandesc;
-
-    PRMSG(2, "AMDisconnect(%x->%d)\n", ciptr, ciptr->fd, 0 );
-
-    chandesc = XAmFdToChanDesc(ciptr->fd);
-    if (chandesc != NULL) {
-       switch (chandesc->type) {
-       case ACDT_TCPIP:
-           if (chandesc->signal != -1) {
-               sig_raise(chandesc->signal);
-               chandesc->signal = -1;
-           }
-           std_destroy(&chandesc->chancap);
-           break;
-
-       case ACDT_VIRTCIRC:
-           vc_close(chandesc->virtcirc, VC_BOTH | VC_ASYNC);
-           break;
-       }
-#ifdef XSERV_t
-       if (ciptr->fd == maxClient - 1) {
-           maxClient--;
-           /* we could look if maxClient can be reduced even more */
-       }
-#endif
-       XAmFreeChanDesc(chandesc);
-    }
-
-    return 0;
-}
-
-
-static
-TRANS(AMClose)(ciptr)
-XtransConnInfo ciptr;
-{
-    PRMSG(2, "AMClose(%x->%d)\n", ciptr, ciptr->fd, 0 );
-
-    return TRANS(AMDisconnect)(ciptr);
-}
-
-
-Xtransport     TRANS(AmConnFuncs) = {
-       /* Combined AMOEBA RPC/TCP Interface; maybe we should split this  */
-       "amcon",
-       0,
-#ifdef TRANS_CLIENT
-       TRANS(AMOpenCOTSClient),
-#endif /* TRANS_CLIENT */
-#ifdef TRANS_SERVER
-       TRANS(AMOpenCOTSServer),
-#endif /* TRANS_SERVER */
-#ifdef TRANS_CLIENT
-       TRANS(AMOpenCLTSClient),
-#endif /* TRANS_CLIENT */
-#ifdef TRANS_SERVER
-       TRANS(AMOpenCLTSServer),
-#endif /* TRANS_SERVER */
-       TRANS(AMSetOption),
-#ifdef TRANS_SERVER
-       TRANS(AMCreateListener),
-       TRANS(AMResetListener),
-       TRANS(AMAccept),
-#endif /* TRANS_SERVER */
-#ifdef TRANS_CLIENT
-       TRANS(AMConnect),
-#endif /* TRANS_CLIENT */
-       TRANS(AMBytesReadable),
-       TRANS(AMRead),
-       TRANS(AMWrite),
-       TRANS(AMReadv),
-       TRANS(AMWritev),
-       TRANS(AMDisconnect),
-       TRANS(AMClose),
-};