Source Code (Use browser search to find items of interest.)

Class Index

kdm'CXdmcp (./kdebase/kdm/CXdmcp.h:100)

class CXdmcp : public QObject {
Q_OBJECT
 public:

  typedef struct _hostName {
    struct _hostName	*next;
    char		*fullname;
    int			willing;
    ARRAY8		hostname, status;
    CARD16		connectionType;
    ARRAY8		hostaddr;
  } HostName;

	/* Constructor with command line arguments.
   */
  CXdmcp( int argc, char **argv );
	~CXdmcp();

	/* Add hostname to ping.
	 * "BROADCAST" is special.
	 */
  void registerHostname (const char *name);

	/* Empty Hostname list.
	 */
  void emptyHostnames (void);

	/* Select Host.
	 */
  void chooseHost (const char *h);

	/* Ping all specified hosts.
	 */
  void pingHosts();

signals:

	/* No more hosts to display.
	 */
  void deleteAllHosts();

  /* Remove host from list.
	 */
  void deleteHost(char *name);

	/* Add host to list.
	 */
  void addHost(CXdmcp::HostName *newname);

	/* Change hosts name in list.
	 */
  void changeHost(char *oldname, CXdmcp::HostName *newname);

public slots:
	/* To call when socket is ready.
   */
  void slotReceivePacket (int);

private slots:
  void doPingHosts();

private:
  QSocketNotifier *sn;

	ARRAYofARRAY8	AuthenticationNames;
  int  socketFD;
  QTimer *t;
  int pingTry;

  int ifioctl (int fd, int cmd, char *arg);
  void rebuildTable (int size);
  int addHostname (ARRAY8Ptr hostname, ARRAY8Ptr status,
		   struct sockaddr *addr, int willing);

  void disposeHostname (HostName *host);
  void removeHostname (HostName *host);
  void registerHostaddr (struct sockaddr *addr, int len, xdmOpCode type);
  int  initXDMCP (char **argv);

#ifdef MINIX
   char read_buffer[XDM_MAX_MSGLEN+sizeof(udp_io_hdr_t)];
   int read_inprogress;
   int read_size;
   void read_cb(nbio_ref_t ref, int res, int err);
#endif

   int fromHex (char *s, char *d, int len);


  struct _app_resources app_resources;


  typedef struct _hostAddr {
    struct _hostAddr	*next;
    struct sockaddr	*addr;
    int			addrlen;
    xdmOpCode		type;
  } HostAddr;

   HostAddr    *hostAddrdb;
   HostName    *hostNamedb;

   XdmcpBuffer	directBuffer, broadcastBuffer;
   XdmcpBuffer	buffer;
};

kdm'CXdmcp::ifioctl() (./kdebase/kdm/CXdmcp.cpp:180)

CXdmcp::ifioctl (int fd, int cmd, char *arg)
{
  struct strioctl ioc;
  int ret;

  bzero((char *) &ioc, sizeof(ioc));
  ioc.ic_cmd = cmd;
  ioc.ic_timout = 0;
  if (cmd == SIOCGIFCONF)
    {
      ioc.ic_len = ((struct ifconf *) arg)->ifc_len;
      ioc.ic_dp = ((struct ifconf *) arg)->ifc_buf;
#ifdef ISC
      /* SIOCGIFCONF is somewhat brain damaged on ISC. The argument
       * buffer must contain the ifconf structure as header. Ifc_req
       * is also not a pointer but a one element array of ifreq
       * structures. On return this array is extended by enough
       * ifreq fields to hold all interfaces. The return buffer length
       * is placed in the buffer header.
       */
      ((struct ifconf *) ioc.ic_dp)->ifc_len =
	ioc.ic_len - sizeof(struct ifconf);
#endif
    }
  else
    {
      ioc.ic_len = sizeof(struct ifreq);
      ioc.ic_dp = arg;
    }
  ret = ioctl(fd, I_STR, (char *) &ioc);
  if (ret >= 0 && cmd == SIOCGIFCONF)
#ifdef SVR4
    ((struct ifconf *) arg)->ifc_len = ioc.ic_len;
#endif
#ifdef ISC
  {
    ((struct ifconf *) arg)->ifc_len =
      ((struct ifconf *)ioc.ic_dp)->ifc_len;
    ((struct ifconf *) arg)->ifc_buf = 
      (caddr_t)((struct ifconf *)ioc.ic_dp)->ifc_req;
  }
#endif
  return(ret);
}

kdm'CXdmcp::pingHosts() (./kdebase/kdm/CXdmcp.cpp:230)

CXdmcp::pingHosts()
{
  pingTry = 0;
  doPingHosts();
}

void

kdm'CXdmcp::doPingHosts() (./kdebase/kdm/CXdmcp.cpp:237)

CXdmcp::doPingHosts()
{
  HostAddr	*hosts;
  for (hosts = hostAddrdb; hosts; hosts = hosts->next)
  {
  	if (hosts->type == QUERY)
#ifdef XIMStringConversionRetrival
			XdmcpFlush (socketFD, &directBuffer, hosts->addr, hosts->addrlen);
#else
			XdmcpFlush (socketFD, &directBuffer, (char*)hosts->addr, hosts->addrlen);
#endif	
    else
#ifdef XIMStringConversionRetrival
			XdmcpFlush (socketFD, &broadcastBuffer, hosts->addr, hosts->addrlen);
#else
			XdmcpFlush (socketFD, &broadcastBuffer, (char*)hosts->addr, hosts->addrlen);
#endif	
    }
	  if (++pingTry < TRIES)
  	  t->start( PING_INTERVAL, true);
}

int

kdm'CXdmcp::addHostname() (./kdebase/kdm/CXdmcp.cpp:260)

CXdmcp::addHostname (ARRAY8Ptr hostname, ARRAY8Ptr status, 
		    struct sockaddr *addr, int willing)
{
  HostName	*newname, **names, *name;
  ARRAY8	hostAddr;
  CARD16	connectionType;
  int		fulllen;
    
  char *oldname = 0;

  switch (addr->sa_family)
    {
    case AF_INET:
      hostAddr.data = (CARD8 *) &((struct sockaddr_in *) addr)->sin_addr;
      hostAddr.length = 4;
      connectionType = FamilyInternet;
      break;
    default:
      hostAddr.data = (CARD8 *) "";
      hostAddr.length = 0;
      connectionType = FamilyLocal;
      break;
    }
  for (names = &hostNamedb; *names; names = & (*names)->next)
    {
      name = *names;
      if (connectionType == name->connectionType &&
	  XdmcpARRAY8Equal (&hostAddr, &name->hostaddr))
	{
	  if (XdmcpARRAY8Equal (status, &name->status))
	    {
	      return 0;
	    }
	  break;
	}
    }
  if (!*names)
    {
      newname = (HostName *) malloc (sizeof (HostName));
      if (!newname)
	return 0;
      if (hostname->length)
	{
	  switch (addr->sa_family)
	    {
	    case AF_INET:
	      {
		struct hostent  *hostent;
		char	    *host;
    	
		hostent = gethostbyaddr ((char *)hostAddr.data, hostAddr.length, AF_INET);
		if (hostent)
		  {
		    XdmcpDisposeARRAY8 (hostname);
		    host = hostent->h_name;
		    XdmcpAllocARRAY8 (hostname, strlen (host));
		    memmove( hostname->data, host, hostname->length);
		  }
	      }
	    }
	}
      if (!XdmcpAllocARRAY8 (&newname->hostaddr, hostAddr.length))
    	{
	  free ((char *) newname->fullname);
	  free ((char *) newname);
	  return 0;
    	}
      memmove( newname->hostaddr.data, hostAddr.data, hostAddr.length);
      newname->connectionType = connectionType;
      newname->hostname = *hostname;

      *names = newname;
      newname->next = 0;

      /******************************
       * Add Host
      ******************************/
    }
  else
    {
      /******************************
       * change Host
       ******************************/
      newname = *names;
      oldname = newname->fullname;
      XdmcpDisposeARRAY8 (&newname->status);
      XdmcpDisposeARRAY8 (hostname);
    }


  newname->willing = willing;
  newname->status = *status;

  hostname = &newname->hostname;
  fulllen = hostname->length;
  if (fulllen < 30)
    fulllen = 30;
  newname->fullname = (char *)malloc (fulllen + status->length + 10);

  if (!newname->fullname)
  {
  	newname->fullname = const_cast<char*>("Unknown");
  }
  else
  {
/*
	  sprintf (newname->fullname, "%-30.*s %*.*s",
	  hostname->length, hostname->data,
	  status->length, status->length, status->data);
*/
	  sprintf (newname->fullname, "%*.*s", hostname->length, hostname->length, hostname->data);
  }

  if(oldname) {
    emit changeHost(oldname, newname);
    free (oldname);
  } else {
	  emit addHost(newname);
  }

  return 1;
}

void

kdm'CXdmcp::disposeHostname() (./kdebase/kdm/CXdmcp.cpp:384)

CXdmcp::disposeHostname (HostName *host)
{
  XdmcpDisposeARRAY8 (&host->hostname);
  XdmcpDisposeARRAY8 (&host->hostaddr);
  XdmcpDisposeARRAY8 (&host->status);
  free ((char *) host->fullname);
  free ((char *) host);
}

void

kdm'CXdmcp::removeHostname() (./kdebase/kdm/CXdmcp.cpp:394)

CXdmcp::removeHostname (HostName *host)
{
  HostName	**prev, *hosts;

  prev = &hostNamedb;;
  for (hosts = hostNamedb; hosts; hosts = hosts->next)
    {
      if (hosts == host)
	break;
      prev = &hosts->next;
    }
  if (!hosts)
    return;
  *prev = host->next;

  disposeHostname (host);

  emit deleteHost(host->fullname);

}

void

kdm'CXdmcp::emptyHostnames() (./kdebase/kdm/CXdmcp.cpp:416)

CXdmcp::emptyHostnames (void)
{
  HostName	*hosts, *next;

  for (hosts = hostNamedb; hosts; hosts = next)
  {
		next = hosts->next;
    disposeHostname (hosts);
  }

  emit deleteAllHosts();

  hostNamedb = 0;
}

void

kdm'CXdmcp::slotReceivePacket() (./kdebase/kdm/CXdmcp.cpp:432)

CXdmcp::slotReceivePacket (int socketFD)
{
  XdmcpHeader	    header;
  ARRAY8	    authenticationName;
  ARRAY8	    hostname;
  ARRAY8	    status;
  int		    saveHostname = 0;
  struct sockaddr addr;
  int		    addrlen;
#ifdef MINIX
  int r;
#endif

#ifdef MINIX
  if (read_inprogress) abort();
  if (read_size == 0)
    {
      r= read(socketFD, read_buffer, sizeof(read_buffer));
      if (r == -1 && errno == EINPROGRESS)
    	{
	  read_inprogress= 1;
	  nbio_inprogress(socketFD, ASIO_READ, 1 /* read */,
			  0 /* write */, 0 /* exception */);
    	}
      else if (r <= 0)
    	{
	  fprintf(stderr, "chooser: read error: %s\n", r == 0 ?
		  "EOF" : strerror(errno));
	  return;
	}
    }
#endif

  addrlen = sizeof (addr);
#ifdef MINIX
  if (!MNX_XdmcpFill (socketFD, &buffer, &addr, &addrlen,
		      read_buffer, read_size))
    {
      return;
    }
  read_size= 0;
#else
  if (!XdmcpFill (socketFD, &buffer, (XdmcpNetaddr) &addr, &addrlen))
    return;
#endif
  if (!XdmcpReadHeader (&buffer, &header))
    return;
  if (header.version != XDM_PROTOCOL_VERSION)
    return;
  hostname.data = 0;
  status.data = 0;
  authenticationName.data = 0;
  switch (header.opcode) {
  case WILLING:
    if (XdmcpReadARRAY8 (&buffer, &authenticationName) &&
	XdmcpReadARRAY8 (&buffer, &hostname) &&
	XdmcpReadARRAY8 (&buffer, &status))
      {
	if (header.length == 6 + authenticationName.length +
	    hostname.length + status.length)
	  {
	    if (addHostname (&hostname, &status, &addr, header.opcode == (int) WILLING))
	      saveHostname = 1;
	  }
      }
    XdmcpDisposeARRAY8 (&authenticationName);
    break;
  case UNWILLING:
    if (XdmcpReadARRAY8 (&buffer, &hostname) &&
	XdmcpReadARRAY8 (&buffer, &status))
      {
	if (header.length == 4 + hostname.length + status.length)
	  {
	    if (addHostname (&hostname, &status, &addr, header.opcode == (int) WILLING))
	      saveHostname = 1;

	  }
      }
    break;
  default:
    break;
  }
  if (!saveHostname)
    {
      XdmcpDisposeARRAY8 (&hostname);
      XdmcpDisposeARRAY8 (&status);
    }
}

void

kdm'CXdmcp::registerHostaddr() (./kdebase/kdm/CXdmcp.cpp:522)

CXdmcp::registerHostaddr (struct sockaddr *addr, int len, xdmOpCode type)
{
  HostAddr		*host, **prev;

  host = (HostAddr *) malloc (sizeof (HostAddr));
  if (!host)
    return;
  host->addr = (struct sockaddr *) malloc (len);
  if (!host->addr)
    {
      free ((char *) host);
      return;
    }
  memmove( (char *) host->addr, (char *) addr, len);
  host->addrlen = len;
  host->type = type;
  for (prev = &hostAddrdb; *prev; prev = &(*prev)->next)
    ;
  *prev = host;
  host->next = NULL;
}

/*
 * Register the address for this host.
 * Called with each of the names on the command line.
 * The special name "BROADCAST" looks up all the broadcast
 *  addresses on the local host.
 */

#if !defined(MINIX) && !defined(__GNU__)

/* Handle variable length ifreq in BNR2 and later */

kdm'CXdmcp::registerHostname() (./kdebase/kdm/CXdmcp.cpp:563)

CXdmcp::registerHostname (const char *name)
{
  struct hostent	*hostent;
  struct sockaddr_in	in_addr;
  struct ifconf	ifc;
  register struct ifreq *ifr;
  struct sockaddr	broad_addr;
  char		buf[2048], *cp, *cplim;

  if (!strcmp (name, BROADCAST_HOSTNAME)) {
#ifdef WINTCP /* NCR with Wollongong TCP */
    int                 ipfd;
    struct ifconf       *ifcp;
    struct strioctl     ioc;
    int			n;
    
    ifcp = (struct ifconf *)buf;
    ifcp->ifc_buf = buf+4;
    ifcp->ifc_len = sizeof (buf) - 4;
    
    if ((ipfd=open( "/dev/ip", O_RDONLY )) < 0 ) {
      t_error( "RegisterHostname() t_open(/dev/ip) failed" );
      return;
    }
    
    ioc.ic_cmd = IPIOC_GETIFCONF;
    ioc.ic_timout = 60;
    ioc.ic_len = sizeof( buf );
    ioc.ic_dp = (char *)ifcp;
    
    if (ioctl (ipfd, (int) I_STR, (char *) &ioc) < 0)	{
      perror( "RegisterHostname() ioctl(I_STR(IPIOC_GETIFCONF)) failed" );
      close( ipfd );
      return;
    }
    
    for (ifr = ifcp->ifc_req, n = ifcp->ifc_len / sizeof (struct ifreq);
	 --n >= 0;
	 ifr++)
#else /* WINTCP */
      ifc.ifc_len = sizeof (buf);
    ifc.ifc_buf = buf;
    if (ifioctl (socketFD, (int) SIOCGIFCONF, (char *) &ifc) < 0)
      return;
    

kdm'CXdmcp::registerHostname() (./kdebase/kdm/CXdmcp.cpp:705)

CXdmcp::registerHostname (const char *name)
{
	struct hostent	*hostent;
  struct sockaddr_in	in_addr;

  if (!strcmp (name, BROADCAST_HOSTNAME))
	{
		in_addr.sin_addr.s_addr= htonl(0xFFFFFFFF);
	  in_addr.sin_port = htons (XDM_UDP_PORT);
	  RegisterHostaddr ((struct sockaddr *)&in_addr, sizeof (in_addr),
			    BROADCAST_QUERY);
	}
  else
	{
	  /* address as hex string, e.g., "12180022" (depreciated) */
	  if (strlen(name) == 8 &&
	      FromHex(name, (char *)&in_addr.sin_addr, strlen(name)) == 0)
	  {
	      in_addr.sin_family = AF_INET;
	  }
	  /* Per RFC 1123, check first for IP address in dotted-decimal form */
	  else if ((in_addr.sin_addr.s_addr = inet_addr(name)) != -1)
	  	in_addr.sin_family = AF_INET;
	  else
	  {
	      hostent = gethostbyname (name);
	      if (!hostent)
					return;
	      if (hostent->h_addrtype != AF_INET || hostent->h_length != 4)
		    	return;
	      in_addr.sin_family = hostent->h_addrtype;
	      memmove( &in_addr.sin_addr, hostent->h_addr, 4);
	  }
	  in_addr.sin_port = htons (XDM_UDP_PORT);
	  RegisterHostaddr ((struct sockaddr *)&in_addr, sizeof (in_addr),
			    QUERY);
	}
}
#endif /* !MINIX */

#if 0
static void
RegisterAuthenticationName (char *name, int namelen)
    {
      ARRAY8Ptr	authName;
      if (!XdmcpReallocARRAYofARRAY8 (&AuthenticationNames,
				      AuthenticationNames.length + 1))
	return;
      authName = &AuthenticationNames.data[AuthenticationNames.length-1];
      if (!XdmcpAllocARRAY8 (authName, namelen))
	return;
      memmove( authName->data, name, namelen);
    }
#endif

int

kdm'CXdmcp::initXDMCP() (./kdebase/kdm/CXdmcp.cpp:761)

CXdmcp::initXDMCP (char **argv)
{
	int	soopts = 1;
  XdmcpHeader	header;
  int	i;
#ifdef MINIX
  char *udp_device;
  nwio_udpopt_t udpopt;
  int flags;
  nbio_ref_t ref;
#endif

  header.version = XDM_PROTOCOL_VERSION;
  header.opcode = (CARD16) BROADCAST_QUERY;
  header.length = 1;
  for (i = 0; i < (int)AuthenticationNames.length; i++)
		header.length += 2 + AuthenticationNames.data[i].length;
  XdmcpWriteHeader (&broadcastBuffer, &header);
  XdmcpWriteARRAYofARRAY8 (&broadcastBuffer, &AuthenticationNames);

  header.version = XDM_PROTOCOL_VERSION;
  header.opcode = (CARD16) QUERY;
  header.length = 1;
  for (i = 0; i < (int)AuthenticationNames.length; i++)
		header.length += 2 + AuthenticationNames.data[i].length;
  XdmcpWriteHeader (&directBuffer, &header);
  XdmcpWriteARRAYofARRAY8 (&directBuffer, &AuthenticationNames);
#if defined(STREAMSCONN)
  if ((socketFD = t_open ("/dev/udp", O_RDWR, 0)) < 0)
		return 0;

  if (t_bind( socketFD, NULL, NULL ) < 0)
	{
	  t_close(socketFD);
	  return 0;
	}

  /*
   * This part of the code looks contrived. It will actually fit in nicely
   * when the CLTS part of Xtrans is implemented.
   */
  {
		struct netconfig *nconf;

		if( (nconf=getnetconfigent("udp")) == NULL )
	  {
	    t_unbind(socketFD);
	    t_close(socketFD);
	    return 0;
	  }

		if( netdir_options(nconf, ND_SET_BROADCAST, socketFD, NULL) )
	  {
	    freenetconfigent(nconf);
	    t_unbind(socketFD);
	    t_close(socketFD);
	    return 0;
	  }

		freenetconfigent(nconf);
  }
#else
#ifdef MINIX
  udp_device= getenv("UDP_DEVICE");
  if (udp_device == NULL)
  	udp_device= UDP_DEVICE;
  if ((socketFD = open(udp_device, O_RDWR)) == -1)
    return 0;
  udpopt.nwuo_flags= NWUO_SHARED | NWUO_LP_SEL | NWUO_EN_LOC |
		NWUO_EN_BROAD | NWUO_RP_ANY | NWUO_RA_ANY | NWUO_RWDATALL |
		NWUO_DI_IPOPT;
  if (ioctl(socketFD, NWIOSUDPOPT, &udpopt) == -1)
	{
	  close(socketFD);
	  return 0;
	}
  if ((flags= fcntl(socketFD, F_GETFD)) == -1)
	{
	  close(socketFD);
	  return 0;
	}
  if (fcntl(socketFD, F_SETFD, flags | FD_ASYNCHIO) == -1)
	{
	  close(socketFD);
	  return 0;
	}
  nbio_register(socketFD);
  ref.ref_int= socketFD;
  nbio_setcallback(socketFD, ASIO_READ, read_cb, ref);
#else /* !MINIX */
  if ((socketFD = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
		return 0;
#endif /* MINIX */
#endif
#ifndef STREAMSCONN
#ifdef SO_BROADCAST
  soopts = 1;
  if (setsockopt (socketFD, SOL_SOCKET, SO_BROADCAST, (char *)&soopts, sizeof (soopts)) < 0)
	perror ("setsockopt");
#endif
#endif

  while (*argv)
	{
	  registerHostname (*argv);
	  ++argv;
	}
  pingTry = 0;

	return 1;
}

void

kdm'CXdmcp::chooseHost() (./kdebase/kdm/CXdmcp.cpp:874)

CXdmcp::chooseHost (const char *r)
{
	HostName *h;
  for (h = hostNamedb; h; h = h->next) {
		if (!strcmp (r, h->fullname))
	  	break;
  }
  if(!h)
		return;

  if (app_resources.xdmAddress)
	{
	  struct sockaddr_in  in_addr;
	  struct sockaddr	*addr = NULL;
	  int		family;
	  int		len = 0;
	  int		fd;
	  char		buf[1024];
	  XdmcpBuffer	buffer;
	  char		*xdm;
#if defined(STREAMSCONN)
	  struct  t_call  call, rcv;
#endif
#ifdef MINIX
	  char		*tcp_device;
	  nwio_tcpconf_t	tcpconf;
	  nwio_tcpcl_t	tcpcl;
#endif

	  xdm = (char *) app_resources.xdmAddress->data;
	  family = (xdm[0] << 8) + xdm[1];
	  switch (family) {
	  case AF_INET:
#ifdef BSD44SOCKETS
	    in_addr.sin_len = sizeof(in_addr);
#endif
	    in_addr.sin_family = family;
	    memmove( &in_addr.sin_port, xdm + 2, 2);
	    memmove( &in_addr.sin_addr, xdm + 4, 4);
	    addr = (struct sockaddr *) &in_addr;
	    len = sizeof (in_addr);
	    break;
	  }
#if defined(STREAMSCONN)
	  if ((fd = t_open ("/dev/tcp", O_RDWR, NULL)) == -1)
	    {
	      fprintf (stderr, "Cannot create response endpoint\n");
	      fflush(stderr);
	      exit (REMANAGE_DISPLAY);
	    }
	  if (t_bind (fd, NULL, NULL) == -1)
	    {
	      fprintf (stderr, "Cannot bind response endpoint\n");
	      fflush(stderr);
	      t_close (fd);
	      exit (REMANAGE_DISPLAY);
	    }
	  call.addr.buf=(char *)addr;
	  call.addr.len=len;
	  call.addr.maxlen=len;
	  call.opt.len=0;
	  call.opt.maxlen=0;
	  call.udata.len=0;
	  call.udata.maxlen=0;
	  if (t_connect (fd, &call, NULL) == -1)
	    {
	      t_error ("Cannot connect to xdm\n");
	      fflush(stderr);
	      t_unbind (fd);
	      t_close (fd);
	      exit (REMANAGE_DISPLAY);
	    }
#else
#ifdef MINIX
	  tcp_device= getenv("TCP_DEVICE");
	  if (tcp_device == NULL)
	    tcp_device= TCP_DEVICE;
	  if ((fd= open(tcp_device, O_RDWR)) == -1)
	    {
	      fprintf (stderr, "Cannot open '%s': %s\n", tcp_device,
		       strerror(errno));
	      exit (REMANAGE_DISPLAY);
	    }
	  tcpconf.nwtc_flags= NWTC_EXCL | NWTC_LP_SEL | NWTC_SET_RA | NWTC_SET_RP;
	  tcpconf.nwtc_remport= in_addr.sin_port;
	  tcpconf.nwtc_remaddr= in_addr.sin_addr.s_addr;
	  if (ioctl(fd, NWIOSTCPCONF, &tcpconf) == -1)
	    {
	      fprintf (stderr, "NWIOSTCPCONF failed: %s\n", strerror(errno));
	      exit (REMANAGE_DISPLAY);
	    }
	  tcpcl.nwtcl_flags= 0;
	  if (ioctl(fd, NWIOTCPCONN, &tcpcl) == -1)
	    {
	      fprintf (stderr, "NWIOTCPCONN failed: %s\n", strerror(errno));
	      exit (REMANAGE_DISPLAY);
	    }
#else /* !MINIX */
	  if ((fd = socket (family, SOCK_STREAM, 0)) == -1)
	    {
	      fprintf (stderr, "Cannot create response socket\n");
	      exit (REMANAGE_DISPLAY);
	    }
	  if (::connect (fd, addr, len) == -1)
	    {
	      fprintf (stderr, "Cannot connect to xdm\n");
	      exit (REMANAGE_DISPLAY);
	    }
#endif /* MINIX */
#endif
	  buffer.data = (BYTE *) buf;
	  buffer.size = sizeof (buf);
	  buffer.pointer = 0;
	  buffer.count = 0;
	  XdmcpWriteARRAY8 (&buffer, app_resources.clientAddress);
	  XdmcpWriteCARD16 (&buffer, (CARD16) app_resources.connectionType);
	  XdmcpWriteARRAY8 (&buffer, &h->hostaddr);
#if defined(STREAMSCONN)
	  if( t_snd (fd, (char *)buffer.data, buffer.pointer, 0) < 0 )
	    {
	      fprintf (stderr, "Cannot send to xdm\n");
	      fflush(stderr);
	      t_unbind (fd);
	      t_close (fd);
	      exit (REMANAGE_DISPLAY);
	    }
	  sleep(5);	/* Hack because sometimes the connection gets
			   closed before the data arrives on the other end. */
	  t_snddis (fd,NULL);
	  t_unbind (fd);
	  t_close (fd);
#else
	  write (fd, (char *)buffer.data, buffer.pointer);
	  close (fd);
#endif
	}
      else
	{
	  int i;

	  printf ("%u\n", h->connectionType);
	  for (i = 0; i < (int)h->hostaddr.length; i++)
	    printf ("%u%s", h->hostaddr.data[i],
		    i == h->hostaddr.length - 1 ? "\n" : " ");
	}
}


static void

kdm'CXdmcp::read_cb() (./kdebase/kdm/CXdmcp.cpp:1043)

void CXdmcp::read_cb(nbio_ref_t ref, int res, int err)
{
	if (!read_inprogress)
		abort();
  if (res > 0)
	{
	  read_size= res;
	}
  else
  {
	  fprintf(stderr, "chooser: read error: %s\n", res == 0 ?
		  "EOF" : strerror(err));
	  read_size= 0;
	}
      read_inprogress= 0;
}

kdm'CXdmcp::~CXdmcp() (./kdebase/kdm/CXdmcp.cpp:1060)

CXdmcp::~CXdmcp()
{
	emptyHostnames();
}


kdm'CXdmcp::CXdmcp() (./kdebase/kdm/CXdmcp.cpp:1065)

CXdmcp::CXdmcp( int argc, char **argv )
{
	Widget toplevel;

  toplevel = XtInitialize (argv[0], "Chooser", options, XtNumber(options), &argc, argv);
  
  XtAddConverter(XtRString, XtRARRAY8, &CvtStringToARRAY8, NULL, 0);

	XtGetApplicationResources (toplevel, (XtPointer) &app_resources, resources,
	XtNumber (resources), NULL, (Cardinal) 0);

  initXDMCP (argv + 1);

	t = new QTimer( this);
	sn = new QSocketNotifier( socketFD, QSocketNotifier::Read);

	connect( t, SIGNAL( timeout()), this, SLOT( doPingHosts()));

	// connections
  connect( sn, SIGNAL( activated(int)), this, SLOT( slotReceivePacket(int)));
}