#if defined(STREAMSCONN) && defined(SVR4)
#undef STREAMSCONN
#define TCPCONN
#endif
#ifdef WIN32
#include <X11/Xwinsock.h>
#define EPROTOTYPE WSAEPROTOTYPE
#endif
#include <X11/X.h>
#include <signal.h>
#include <setjmp.h>
#include <ctype.h>
#ifndef __TYPES__
#include <sys/types.h>
#define __TYPES__
#endif
#ifndef WIN32
#ifndef STREAMSCONN
#ifndef Lynx
#include <sys/socket.h>
#else
#include <socket.h>
#endif
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#ifdef SYSV
#ifdef i386
#if !defined(sco) && !defined(sun)
#include <net/errno.h>
#endif
#endif
#endif
#endif
#endif
#include <errno.h>
#include "xauth.h"
#ifdef DNETCONN
#include <netdnet/dn.h>
#include <netdnet/dnetdb.h>
#endif
#ifndef WIN32
#include <arpa/inet.h>
#endif
#ifdef SIGALRM
static volatile Bool nameserver_timedout = False;
static jmp_buf env;
static
#ifdef SIGNALRETURNSINT
int
#else
void
#endif
nameserver_lost(int sig)
{
nameserver_timedout = True;
longjmp (env, -1);
#ifdef SIGNALRETURNSINT
return -1;
#endif
}
#endif
char *
get_hostname (auth)
Xauth *auth;
{
static struct hostent *hp;
int af;
#ifdef DNETCONN
struct nodeent *np;
static char nodeaddr[4 + 2 * DN_MAXADDL];
#endif
hp = NULL;
if (auth->address_length == 0)
return "Illegal Address";
#ifdef TCPCONN
if (auth->family == FamilyInternet
#if defined(IPv6) && defined(AF_INET6)
|| auth->family == FamilyInternet6
#endif
)
{
#if defined(IPv6) && defined(AF_INET6)
if (auth->family == FamilyInternet6)
af = AF_INET6;
else
#endif
af = AF_INET;
if (no_name_lookups == False) {
#ifdef SIGALRM
nameserver_timedout = False;
signal (SIGALRM, nameserver_lost);
alarm (4);
if (setjmp(env) == 0) {
#endif
hp = gethostbyaddr (auth->address, auth->address_length, af);
#ifdef SIGALRM
}
alarm (0);
#endif
}
if (hp)
return (hp->h_name);
#if defined(IPv6) && defined(AF_INET6)
else if (af == AF_INET6) {
static char addr[INET6_ADDRSTRLEN+2];
addr[0] = '[';
if (inet_ntop(af, auth->address, addr + 1, INET6_ADDRSTRLEN) == NULL)
return NULL;
strcat(addr, "]");
return addr;
}
#endif
else {
return (inet_ntoa(*((struct in_addr *)(auth->address))));
}
}
#endif
#ifdef DNETCONN
if (auth->family == FamilyDECnet) {
struct dn_naddr *addr_ptr = (struct dn_naddr *) auth->address;
if ((no_name_lookups == False) &&
(np = getnodebyaddr(addr_ptr->a_addr, addr_ptr->a_len, AF_DECnet))) {
sprintf(nodeaddr, "%s:", np->n_name);
} else {
sprintf(nodeaddr, "%s:", dnet_htoa(auth->address));
}
return(nodeaddr);
}
#endif
return (NULL);
}
#if defined(TCPCONN) && (!defined(IPv6) || !defined(AF_INET6))
static Bool
get_inet_address(char *name, unsigned int *resultp)
{
unsigned int hostinetaddr = inet_addr (name);
struct hostent *host_ptr;
struct sockaddr_in inaddr;
#ifndef INADDR_NONE
#define INADDR_NONE -1
#endif
if (hostinetaddr == INADDR_NONE) {
if ((host_ptr = gethostbyname (name)) == NULL) {
errno = EINVAL;
return False;
}
if (host_ptr->h_addrtype != AF_INET) {
errno = EPROTOTYPE;
return False;
}
memmove( (char *)&hostinetaddr, (char *)host_ptr->h_addr,
sizeof(inaddr.sin_addr));
}
*resultp = hostinetaddr;
return True;
}
#endif
#ifdef DNETCONN
static Bool get_dnet_address (name, resultp)
char *name;
struct dn_naddr *resultp;
{
struct dn_naddr *dnaddrp, dnaddr;
struct nodeent *np;
if (dnaddrp = dnet_addr (name)) {
dnaddr = *dnaddrp;
} else {
if ((np = getnodebyname (name)) == NULL) return False;
dnaddr.a_len = np->n_length;
memmove( dnaddr.a_addr, np->n_addr, np->n_length);
}
*resultp = dnaddr;
return True;
}
#endif
struct addrlist *get_address_info (
int family,
char *fulldpyname,
int prefix,
char *host)
{
struct addrlist *retval = NULL;
int len = 0;
void *src = NULL;
#ifdef TCPCONN
#if defined(IPv6) && defined(AF_INET6)
struct addrlist *lastrv = NULL;
struct addrinfo *firstai = NULL;
struct addrinfo *ai = NULL;
struct addrinfo hints;
#else
unsigned int hostinetaddr;
#endif
#endif
#ifdef DNETCONN
struct dn_naddr dnaddr;
#endif
char buf[255];
switch (family) {
case FamilyLocal:
if (prefix == 0 && (strncmp (fulldpyname, "unix:", 5) == 0 ||
fulldpyname[0] == ':')) {
if (!get_local_hostname (buf, sizeof buf)) {
len = 0;
} else {
src = buf;
len = strlen (buf);
}
} else {
src = fulldpyname;
len = prefix;
}
break;
case FamilyInternet:
#ifdef TCPCONN
#if defined(IPv6) && defined(AF_INET6)
case FamilyInternet6:
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = 0;
if (getaddrinfo(host,NULL,&hints,&firstai) !=0) return NULL;
for (ai = firstai; ai != NULL; ai = ai->ai_next) {
if (ai->ai_family == AF_INET) {
struct sockaddr_in *sin = (struct sockaddr_in *)ai->ai_addr;
src = &(sin->sin_addr);
len = sizeof(sin->sin_addr);
family = FamilyInternet;
} else if (ai->ai_family == AF_INET6) {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ai->ai_addr;
src = &(sin6->sin6_addr);
len = sizeof(sin6->sin6_addr);
family = FamilyInternet6;
}
if (len > 0 && src != NULL) {
struct addrlist *newrv = malloc (sizeof(struct addrlist));
if (newrv) {
newrv->address = malloc (len);
if (newrv->address) {
memcpy(newrv->address, src, len);
newrv->next = NULL;
newrv->family = family;
newrv->len = len;
if (retval == NULL) {
lastrv = retval = newrv;
} else {
lastrv->next = newrv;
lastrv = newrv;
}
} else {
free(newrv);
}
}
}
len = 0;
src = NULL;
}
freeaddrinfo(firstai);
break;
#else
if (!get_inet_address (host, &hostinetaddr)) return NULL;
src = (char *) &hostinetaddr;
len = 4;
break;
#endif
#else
return NULL;
#endif
case FamilyDECnet:
#ifdef DNETCONN
if (!get_dnet_address (host, &dnaddr)) return NULL;
src = (char *) &dnaddr;
len = (sizeof dnaddr);
break;
#else
#endif
default:
src = NULL;
len = 0;
}
if (len > 0 && src != NULL) {
retval = malloc (sizeof(struct addrlist));
if (retval) {
retval->address = malloc (len);
if (retval->address) {
memcpy(retval->address, src, len);
retval->next = NULL;
retval->family = family;
retval->len = len;
} else {
free(retval);
retval = NULL;
}
}
}
return retval;
}