diff options
Diffstat (limited to 'kdm/backend/choose.c')
-rw-r--r-- | kdm/backend/choose.c | 1051 |
1 files changed, 0 insertions, 1051 deletions
diff --git a/kdm/backend/choose.c b/kdm/backend/choose.c deleted file mode 100644 index ead841228..000000000 --- a/kdm/backend/choose.c +++ /dev/null @@ -1,1051 +0,0 @@ -/* - -Copyright 1990, 1998 The Open Group -Copyright 2002-2004 Oswald Buddenhagen <[email protected]> - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -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 COPYRIGHT HOLDERS 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 a copyright holder 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 copyright holder. - -*/ - -/* - * xdm - display manager daemon - * Author: Keith Packard, MIT X Consortium - * - * chooser backend - */ - -#include <config.h> - -#ifdef XDMCP - -#include "dm.h" -#include "dm_error.h" -#include "dm_socket.h" - -#include <ctype.h> - -#ifdef __svr4__ -# include <sys/sockio.h> -#endif -#include <arpa/inet.h> - -#include <sys/ioctl.h> -#ifdef STREAMSCONN -# ifdef WINTCP /* NCR with Wollongong TCP */ -# include <netinet/ip.h> -# endif -# include <stropts.h> -# include <tiuser.h> -# include <netconfig.h> -# include <netdir.h> -#endif - -#if !defined(__GNU__) && !defined(__hpux) /* XXX __hpux might be wrong */ -# include <net/if.h> -#endif - -#include <netdb.h> - -typedef struct _IndirectUsers { - struct _IndirectUsers *next; - ARRAY8 client; - CARD16 connectionType; -} IndirectUsersRec, *IndirectUsersPtr; - -static IndirectUsersPtr indirectUsers; - -int -RememberIndirectClient( ARRAY8Ptr clientAddress, CARD16 connectionType ) -{ - IndirectUsersPtr i; - - for (i = indirectUsers; i; i = i->next) - if (XdmcpARRAY8Equal( clientAddress, &i->client ) && - connectionType == i->connectionType) - return 1; - if (!(i = (IndirectUsersPtr)Malloc( sizeof(IndirectUsersRec) ))) - return 0; - if (!XdmcpCopyARRAY8( clientAddress, &i->client )) { - free( (char *)i ); - return 0; - } - i->connectionType = connectionType; - i->next = indirectUsers; - indirectUsers = i; - return 1; -} - -void -ForgetIndirectClient( ARRAY8Ptr clientAddress, CARD16 connectionType ) -{ - IndirectUsersPtr *i, ni; - - for (i = &indirectUsers; *i; i = &(*i)->next) - if (XdmcpARRAY8Equal( clientAddress, &(*i)->client ) && - connectionType == (*i)->connectionType) - { - ni = (*i)->next; - XdmcpDisposeARRAY8( &(*i)->client ); - free( (char *)(*i) ); - (*i) = ni; - break; - } -} - -int -IsIndirectClient( ARRAY8Ptr clientAddress, CARD16 connectionType ) -{ - IndirectUsersPtr i; - - for (i = indirectUsers; i; i = i->next) - if (XdmcpARRAY8Equal( clientAddress, &i->client ) && - connectionType == i->connectionType) - return 1; - return 0; -} - -typedef struct _Choices { - struct _Choices *next; - ARRAY8 client; - CARD16 connectionType; - ARRAY8 choice; - Time_t time; -} ChoiceRec, *ChoicePtr; - -static ChoicePtr choices; - -ARRAY8Ptr -IndirectChoice( ARRAY8Ptr clientAddress, CARD16 connectionType ) -{ - ChoicePtr c, next, prev; - - prev = 0; - for (c = choices; c; c = next) { - next = c->next; - Debug( "choice checking timeout: %ld >? %d\n", - (long)(now - c->time), choiceTimeout ); - if (now - c->time > (Time_t)choiceTimeout) { - Debug( "timeout choice %ld > %d\n", - (long)(now - c->time), choiceTimeout ); - if (prev) - prev->next = next; - else - choices = next; - XdmcpDisposeARRAY8( &c->client ); - XdmcpDisposeARRAY8( &c->choice ); - free( (char *)c ); - } else { - if (XdmcpARRAY8Equal( clientAddress, &c->client ) && - connectionType == c->connectionType) - return &c->choice; - prev = c; - } - } - return 0; -} - -int -RegisterIndirectChoice( ARRAY8Ptr clientAddress, CARD16 connectionType, - ARRAY8Ptr choice ) -{ - ChoicePtr c; - int insert; -#if 0 - int found = 0; -#endif - - Debug( "got indirect choice back\n" ); - for (c = choices; c; c = c->next) { - if (XdmcpARRAY8Equal( clientAddress, &c->client ) && - connectionType == c->connectionType) { -#if 0 - found = 1; -#endif - break; - } - } -#if 0 - if (!found) - return 0; -#endif - - insert = 0; - if (!c) { - insert = 1; - c = (ChoicePtr)Malloc( sizeof(ChoiceRec) ); - if (!c) - return 0; - c->connectionType = connectionType; - if (!XdmcpCopyARRAY8( clientAddress, &c->client )) { - free( (char *)c ); - return 0; - } - } else - XdmcpDisposeARRAY8( &c->choice ); - if (!XdmcpCopyARRAY8( choice, &c->choice )) { - XdmcpDisposeARRAY8( &c->client ); - free( (char *)c ); - return 0; - } - if (insert) { - c->next = choices; - choices = c; - } - c->time = now; - return 1; -} - -#if 0 -static void -RemoveIndirectChoice( ARRAY8Ptr clientAddress, CARD16 connectionType ) -{ - ChoicePtr c, prev; - - prev = 0; - for (c = choices; c; c = c->next) { - if (XdmcpARRAY8Equal( clientAddress, &c->client ) && - connectionType == c->connectionType) - { - if (prev) - prev->next = c->next; - else - choices = c->next; - XdmcpDisposeARRAY8( &c->client ); - XdmcpDisposeARRAY8( &c->choice ); - free( (char *)c ); - return; - } - prev = c; - } -} -#endif - - -/* ####################### */ - - -typedef struct _hostAddr { - struct _hostAddr *next; - struct sockaddr *addr; - int addrlen; - xdmOpCode type; -} HostAddr; - -static HostAddr *hostAddrdb; - -typedef struct _hostName { - struct _hostName *next; - unsigned willing:1, alive:1; - ARRAY8 hostname, status; - CARD16 connectionType; - ARRAY8 hostaddr; -} HostName; - -static HostName *hostNamedb; - -static XdmcpBuffer directBuffer, broadcastBuffer; -static XdmcpBuffer buffer; - -static int socketFD; -#if defined(IPv6) && defined(AF_INET6) -static int socket6FD; -#endif - - -static void -doPingHosts() -{ - HostAddr *hosts; - - for (hosts = hostAddrdb; hosts; hosts = hosts->next) -#if defined(IPv6) && defined(AF_INET6) - XdmcpFlush( hosts->addr->sa_family == AF_INET6 ? socket6FD : socketFD, -#else - XdmcpFlush( socketFD, -#endif - hosts->type == QUERY ? &directBuffer : &broadcastBuffer, - (XdmcpNetaddr)hosts->addr, hosts->addrlen ); -} - -static int -addHostname( ARRAY8Ptr hostname, ARRAY8Ptr status, - struct sockaddr *addr, int will ) -{ - HostName **names, *name; - ARRAY8 hostAddr; - CARD16 connectionType; - - switch (addr->sa_family) { - case AF_INET: - hostAddr.data = - (CARD8 *)& ((struct sockaddr_in *)addr)->sin_addr; - hostAddr.length = 4; - connectionType = FamilyInternet; - break; -#if defined(IPv6) && defined(AF_INET6) - case AF_INET6: - hostAddr.data = - (CARD8 *)&((struct sockaddr_in6 *)addr)->sin6_addr; - hostAddr.length = 16; - connectionType = FamilyInternet6; - break; -#endif - 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; - XdmcpDisposeARRAY8( &name->status ); - XdmcpDisposeARRAY8( hostname ); - - GSendInt( G_Ch_ChangeHost ); - goto gotold; - } - } - if (!(name = (HostName *)Malloc( sizeof(*name) ))) - return 0; - if (hostname->length) { - switch (addr->sa_family) { - case AF_INET: -#if defined(IPv6) && defined(AF_INET6) - case AF_INET6: -#endif - { - struct hostent *hostent; - char *host; - - hostent = gethostbyaddr( (char *)hostAddr.data, - hostAddr.length, addr->sa_family ); - if (hostent) { - XdmcpDisposeARRAY8( hostname ); - host = hostent->h_name; - XdmcpAllocARRAY8( hostname, strlen( host ) ); - memmove( hostname->data, host, hostname->length ); - } - } - } - } - if (!XdmcpAllocARRAY8( &name->hostaddr, hostAddr.length )) { - free( (char *)name ); - return 0; - } - memmove( name->hostaddr.data, hostAddr.data, hostAddr.length ); - name->connectionType = connectionType; - name->hostname = *hostname; - - *names = name; - name->next = 0; - - GSendInt( G_Ch_AddHost ); - gotold: - name->alive = 1; - name->willing = will; - name->status = *status; - - GSendInt( (int)name ); /* just an id */ - GSendNStr( (char *)name->hostname.data, name->hostname.length ); - GSendNStr( (char *)name->status.data, name->status.length ); - GSendInt( will ); - - return 1; -} - -static void -disposeHostname( HostName *host ) -{ - XdmcpDisposeARRAY8( &host->hostname ); - XdmcpDisposeARRAY8( &host->hostaddr ); - XdmcpDisposeARRAY8( &host->status ); - free( (char *)host ); -} - -static void -emptyHostnames( void ) -{ - HostName *host, *nhost; - - for (host = hostNamedb; host; host = nhost) { - nhost = host->next; - disposeHostname( host ); - } - hostNamedb = 0; -} - -static void -receivePacket( int sfd ) -{ - XdmcpHeader header; - ARRAY8 authenticationName; - ARRAY8 hostname; - ARRAY8 status; - int saveHostname = 0; -#if defined(IPv6) && defined(AF_INET6) - struct sockaddr_storage addr; -#else - struct sockaddr addr; -#endif - int addrlen; - - addrlen = sizeof(addr); - if (!XdmcpFill( sfd, &buffer, (XdmcpNetaddr)&addr, &addrlen )) - return; - 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, - (struct sockaddr *)&addr, 1 )) - 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, - (struct sockaddr *)&addr, 0 )) - saveHostname = 1; - } - } - break; - default: - break; - } - if (!saveHostname) { - XdmcpDisposeARRAY8( &hostname ); - XdmcpDisposeARRAY8( &status ); - } -} - -static void -addHostaddr( HostAddr **hosts, struct sockaddr *addr, int len, xdmOpCode type ) -{ - HostAddr *host; - - Debug( "adding host %[*hhu, type %d\n", len, addr, type ); - for (host = *hosts; host; host = host->next) - if (host->type == type && host->addr->sa_family == addr->sa_family) - switch (addr->sa_family) { - case AF_INET: - { - struct sockaddr_in *na = (struct sockaddr_in *)addr; - struct sockaddr_in *oa = (struct sockaddr_in *)host->addr; - if (na->sin_port == oa->sin_port && - na->sin_addr.s_addr == oa->sin_addr.s_addr) - return; - break; - } -#if defined(IPv6) && defined(AF_INET6) - case AF_INET6: - { - struct sockaddr_in6 *na = (struct sockaddr_in6 *)addr; - struct sockaddr_in6 *oa = (struct sockaddr_in6 *)host->addr; - if (na->sin6_port == oa->sin6_port && - !memcmp( &na->sin6_addr, &oa->sin6_addr, 16 )) - return; - break; - } -#endif - default: /* ... */ - break; - } - Debug( " not dupe\n" ); - if (!(host = (HostAddr *)Malloc( sizeof(*host) ))) - return; - if (!(host->addr = (struct sockaddr *)Malloc( len ))) { - free( (char *)host ); - return; - } - memcpy( (char *)host->addr, (char *)addr, len ); - host->addrlen = len; - host->type = type; - host->next = *hosts; - *hosts = host; -} - -static void -registerHostaddr( struct sockaddr *addr, int len, xdmOpCode type ) -{ - addHostaddr( &hostAddrdb, addr, len, type ); -} - -static void -emptyPingHosts( void ) -{ - HostAddr *host, *nhost; - - for (host = hostAddrdb; host; host = nhost) { - nhost = host->next; - free( host->addr ); - free( host ); - } - hostAddrdb = 0; -} - -/* Handle variable length ifreq in BNR2 and later */ -#ifdef VARIABLE_IFREQ -# define ifr_size(p) \ - (sizeof(struct ifreq) + \ - (p->ifr_addr.sa_len > sizeof (p->ifr_addr) ? \ - p->ifr_addr.sa_len - sizeof (p->ifr_addr) : 0)) -#else -# define ifr_size(p) (sizeof(struct ifreq)) -#endif - -#define IFC_REQ(ifc) ifc.ifc_req - -#ifndef SYSV_SIOCGIFCONF -# define ifioctl ioctl -#endif - -static void -registerBroadcastForPing( void ) -{ - struct sockaddr_in in_addr; - -#ifdef __GNU__ - 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 /* __GNU__ */ - struct ifconf ifc; - register struct ifreq *ifr; - struct sockaddr broad_addr; - char buf[2048], *cp, *cplim; -# 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( "RegisterBroadcastForPing() 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( "RegisterBroadcastForPing() 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; - - cplim = (char *)IFC_REQ( ifc ) + ifc.ifc_len; - - for (cp = (char *)IFC_REQ( ifc ); cp < cplim; cp += ifr_size(ifr)) -# endif /* WINTCP */ - { -# ifndef WINTCP - ifr = (struct ifreq *)cp; -# endif - if (ifr->ifr_addr.sa_family != AF_INET) - continue; - - broad_addr = ifr->ifr_addr; - ((struct sockaddr_in *)&broad_addr)->sin_addr.s_addr = - htonl( INADDR_BROADCAST ); -# ifdef SIOCGIFBRDADDR - { - struct ifreq broad_req; - - broad_req = *ifr; -# ifdef WINTCP /* NCR with Wollongong TCP */ - ioc.ic_cmd = IPIOC_GETIFFLAGS; - ioc.ic_timout = 0; - ioc.ic_len = sizeof(broad_req); - ioc.ic_dp = (char *)&broad_req; - - if (ioctl (ipfd, I_STR, (char *) &ioc ) != -1 && -# else /* WINTCP */ - if (ifioctl( socketFD, SIOCGIFFLAGS, (char *)&broad_req ) != - -1 && -# endif /* WINTCP */ - (broad_req.ifr_flags & IFF_BROADCAST) && - (broad_req.ifr_flags & IFF_UP)) - { - broad_req = *ifr; -# ifdef WINTCP /* NCR with Wollongong TCP */ - ioc.ic_cmd = IPIOC_GETIFBRDADDR; - ioc.ic_timout = 0; - ioc.ic_len = sizeof(broad_req); - ioc.ic_dp = (char *)&broad_req; - - if (ioctl( ipfd, I_STR, (char *) &ioc) != -1 ) -# else /* WINTCP */ - if (ifioctl( socketFD, SIOCGIFBRDADDR, (char *)&broad_req ) - != -1) -# endif /* WINTCP */ - broad_addr = broad_req.ifr_addr; - else - continue; - } else - continue; - } -# endif - in_addr = *((struct sockaddr_in *)&broad_addr); - in_addr.sin_port = htons( XDM_UDP_PORT ); -# ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - in_addr.sin_len = sizeof(in_addr); -# endif - registerHostaddr( (struct sockaddr *)&in_addr, sizeof(in_addr), - BROADCAST_QUERY ); - } -#endif -} - -static int -makeSockAddrs( const char *name, HostAddr **hosts ) -{ -#if defined(IPv6) && defined(AF_INET6) - struct addrinfo *ai, *nai, hints; - bzero( &hints, sizeof(hints) ); - hints.ai_socktype = SOCK_DGRAM; - if (getaddrinfo( name, stringify( XDM_UDP_PORT ), &hints, &ai )) - return 0; - for (nai = ai; nai; nai = nai->ai_next) - if ((nai->ai_family == AF_INET) || (nai->ai_family == AF_INET6)) - addHostaddr( hosts, nai->ai_addr, nai->ai_addrlen, - (nai->ai_family == AF_INET ? - IN_MULTICAST( ((struct sockaddr_in *)nai->ai_addr)->sin_addr.s_addr ) : - IN6_IS_ADDR_MULTICAST( &((struct sockaddr_in6 *)nai->ai_addr)->sin6_addr )) ? - BROADCAST_QUERY : QUERY ); -#else - struct sockaddr_in in_addr; - /* Per RFC 1123, check first for IP address in dotted-decimal form */ - if ((in_addr.sin_addr.s_addr = inet_addr( name )) == (unsigned)-1) { - struct hostent *hostent; - if (!(hostent = gethostbyname( name )) || - hostent->h_addrtype != AF_INET) - return 0; - memcpy( &in_addr.sin_addr, hostent->h_addr, 4 ); - } - in_addr.sin_family = AF_INET; - in_addr.sin_port = htons( XDM_UDP_PORT ); -# ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - in_addr.sin_len = sizeof(in_addr); -# endif - addHostaddr( hosts, (struct sockaddr *)&in_addr, sizeof(in_addr), -# ifdef IN_MULTICAST - IN_MULTICAST( in_addr.sin_addr.s_addr ) ? - BROADCAST_QUERY : -# endif - QUERY ); -#endif - return 1; -} - -/* - * Register the address for this host. - * Called for interactively specified hosts. - * The special names "BROADCAST" and "*" look up all the broadcast - * addresses on the local host. - */ - -static int -registerForPing( const char *name ) -{ - Debug( "manual host registration: %s\n", name ); - if (!strcmp( name, "BROADCAST" ) || !strcmp( name, "*" )) - registerBroadcastForPing(); - else if (!makeSockAddrs( name, &hostAddrdb )) - return 0; - return 1; -} - -/*ARGSUSED*/ -static void -AddChooserHost( - CARD16 connectionType, - ARRAY8Ptr addr, - char *closure ATTR_UNUSED ) -{ - if (connectionType == FamilyBroadcast) { - registerBroadcastForPing(); - return; - } - Debug( "internal host registration: %[*hhu, family %hx\n", - addr->length, addr->data, connectionType ); - if (connectionType == FamilyInternet) { - struct sockaddr_in in_addr; - in_addr.sin_family = AF_INET; - memmove( &in_addr.sin_addr, addr->data, 4 ); - in_addr.sin_port = htons( XDM_UDP_PORT ); -#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - in_addr.sin_len = sizeof(in_addr); -#endif - registerHostaddr( (struct sockaddr *)&in_addr, sizeof(in_addr), -#ifdef IN_MULTICAST - IN_MULTICAST( in_addr.sin_addr.s_addr ) ? - BROADCAST_QUERY : -#endif - QUERY ); - } -#if defined(IPv6) && defined(AF_INET6) - else if (connectionType == FamilyInternet6) { - struct sockaddr_in6 in6_addr; - in6_addr.sin6_family = AF_INET6; - memmove( &in6_addr.sin6_addr, addr->data, 16 ); - in6_addr.sin6_port = htons( XDM_UDP_PORT ); -#ifdef SIN6_LEN - in6_addr.sin6_len = sizeof(in6_addr); -#endif - registerHostaddr( (struct sockaddr *)&in6_addr, sizeof(in6_addr), - IN6_IS_ADDR_MULTICAST( &in6_addr.sin6_addr ) ? - BROADCAST_QUERY : QUERY ); - } -#endif -} - -static ARRAYofARRAY8 AuthenticationNames; - -#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 - -static int -initXDMCP() -{ - XdmcpHeader header; -#if 0 - int i; -#endif -#ifndef STREAMSCONN -#ifdef SO_BROADCAST - int soopts; -#endif -#endif - - header.version = XDM_PROTOCOL_VERSION; - header.length = 1; -#if 0 - for (i = 0; i < (int)AuthenticationNames.length; i++) - header.length += 2 + AuthenticationNames.data[i].length; -#endif - - header.opcode = (CARD16)BROADCAST_QUERY; - XdmcpWriteHeader( &broadcastBuffer, &header ); - XdmcpWriteARRAYofARRAY8( &broadcastBuffer, &AuthenticationNames ); - - header.opcode = (CARD16)QUERY; - 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 - if ((socketFD = socket( AF_INET, SOCK_DGRAM, 0 )) < 0) - return 0; -#if defined(IPv6) && defined(AF_INET6) - socket6FD = socket( AF_INET6, SOCK_DGRAM, 0 ); -#endif -# ifdef SO_BROADCAST - soopts = 1; - if (setsockopt( socketFD, SOL_SOCKET, SO_BROADCAST, (char *)&soopts, - sizeof(soopts) ) < 0) - perror( "setsockopt" ); -# endif -#endif - - return 1; -} - -static void ATTR_NORETURN -chooseHost( int hid ) -{ - HostName *h; -#if defined(IPv6) && defined(AF_INET6) - char addr[64]; -#endif - - for (h = hostNamedb; h; h = h->next) - if ((int)h == hid) { - /* XXX error handling */ - GSet( &mstrtalk ); - if ((td->displayType & d_location) == dLocal) { - GSendInt( D_RemoteHost ); -#if defined(IPv6) && defined(AF_INET6) - switch (h->connectionType) { - case FamilyInternet6: - inet_ntop( AF_INET6, h->hostaddr.data, addr, sizeof(addr) ); - break; - default: /* FamilyInternet */ - inet_ntop( AF_INET, h->hostaddr.data, addr, sizeof(addr) ); - break; - } - GSendStr( addr ); -#else - GSendStr( inet_ntoa( *(struct in_addr *)h->hostaddr.data ) ); -#endif - CloseGreeter( FALSE ); - SessionExit( EX_REMOTE ); - } else { - GSendInt( D_ChooseHost ); - GSendArr( td->clientAddr.length, (char *)td->clientAddr.data ); - GSendInt( td->connectionType ); - GSendArr( h->hostaddr.length, (char *)h->hostaddr.data ); - CloseGreeter( FALSE ); - goto bout; - } - break; - } -/* LogError( "Internal error: chose unexisting host\n" ); */ - bout: - SessionExit( EX_NORMAL ); -} - -static void -directChooseHost( const char *name ) -{ - HostAddr *hosts = 0; - - if (!makeSockAddrs( name, &hosts )) - return; - GSendInt( G_Ch_Exit ); - /* XXX error handling */ - GSet( &mstrtalk ); - if ((td->displayType & d_location) == dLocal) { - GSendInt( D_RemoteHost ); - GSendStr( name ); - CloseGreeter( FALSE ); - SessionExit( EX_REMOTE ); - } else { - GSendInt( D_ChooseHost ); - GSendArr( td->clientAddr.length, (char *)td->clientAddr.data ); - GSendInt( td->connectionType ); - GSendArr( hosts->addrlen, (char *)hosts->addr ); - CloseGreeter( FALSE ); - SessionExit( EX_NORMAL ); - } -} - -#define PING_TRIES 3 - -int -DoChoose() -{ - HostName **hp, *h; - char *host, **hostp; - struct timeval *to, tnow, nextPing; - int pingTry, n, cmd; - FD_TYPE rfds; - static int xdmcpInited; - - OpenGreeter(); - GSendInt( G_Choose ); - switch (cmd = CtrlGreeterWait( TRUE )) { - case G_Ready: - break; - default: /* error */ - return cmd; - } - - if (!xdmcpInited) { - if (!initXDMCP()) - SessionExit( EX_UNMANAGE_DPY ); - xdmcpInited = 1; - } - if ((td->displayType & d_location) == dLocal) { - /* XXX the config reader should do the lookup already */ - for (hostp = td->chooserHosts; *hostp; hostp++) - if (!registerForPing( *hostp )) - LogError( "Unkown host %\"s specified for local chooser preload of display %s\n", *hostp, td->name ); - } else - ForEachChooserHost( &td->clientAddr, td->connectionType, - AddChooserHost, 0 ); - - GSendInt( 0 ); /* entering async mode signal */ - - reping: - for (h = hostNamedb; h; h = h->next) - h->alive = 0; - pingTry = 0; - goto pingen; - - for (;;) { - to = 0; - if (pingTry <= PING_TRIES) { - gettimeofday( &tnow, 0 ); - if (nextPing.tv_sec < tnow.tv_sec || - (nextPing.tv_sec == tnow.tv_sec && - nextPing.tv_usec < tnow.tv_usec)) { - if (pingTry < PING_TRIES) { - pingen: - pingTry++; - doPingHosts(); - gettimeofday( &tnow, 0 ); - nextPing = tnow; - nextPing.tv_sec++; - } else { - for (hp = &hostNamedb; *hp; ) - if (!(*hp)->alive) { - h = (*hp)->next; - disposeHostname( *hp ); - GSendInt( G_Ch_RemoveHost ); - GSendInt( (int)*hp ); /* just an id */ - *hp = h; - } else - hp = &(*hp)->next; - goto noto; - } - } - to = &tnow; - tnow.tv_sec = nextPing.tv_sec - tnow.tv_sec; - tnow.tv_usec = nextPing.tv_usec - tnow.tv_usec; - if (tnow.tv_usec < 0) { - tnow.tv_usec += 1000000; - tnow.tv_sec--; - } - } - noto: - FD_ZERO( &rfds ); - FD_SET( grtproc.pipe.rfd, &rfds ); - FD_SET( socketFD, &rfds ); -#if defined(IPv6) && defined(AF_INET6) - if (socket6FD >= 0) - FD_SET( socket6FD, &rfds ); -#endif - n = grtproc.pipe.rfd; - if (socketFD > n) - n = socketFD; -#if defined(IPv6) && defined(AF_INET6) - if (socket6FD > n) - n = socket6FD; -#endif - if (select( n + 1, &rfds, 0, 0, to ) > 0) { - if (FD_ISSET( grtproc.pipe.rfd, &rfds )) - switch (cmd = CtrlGreeterWait( FALSE )) { - case -1: - break; - case G_Ch_Refresh: - goto reping; - case G_Ch_RegisterHost: - host = GRecvStr(); - if (!registerForPing( host )) { - GSendInt( G_Ch_BadHost ); - GSendStr( host ); - } - free( host ); - goto reping; - case G_Ch_DirectChoice: - host = GRecvStr(); - directChooseHost( host ); - GSendInt( G_Ch_BadHost ); - GSendStr( host ); - free( host ); - break; - case G_Ready: - chooseHost( GRecvInt() ); - /* NOTREACHED */ - default: - emptyHostnames(); - emptyPingHosts(); - return cmd; - } - if (FD_ISSET( socketFD, &rfds )) - receivePacket( socketFD ); -#if defined(IPv6) && defined(AF_INET6) - if (socket6FD >= 0 && FD_ISSET( socket6FD, &rfds )) - receivePacket( socket6FD ); -#endif - } - } - -} - -#endif /* XDMCP */ |