#ifdef XTHREADS
#include <X11/Xthreads.h>
#endif
#ifdef X11_t
#define FamilyInternet 0
#define FamilyDECnet 1
#define FamilyChaos 2
#define FamilyInternet6 6
#define FamilyAmoeba 33
#define FamilyLocalHost 252
#define FamilyKrb5Principal 253
#define FamilyNetname 254
#define FamilyLocal 256
#define FamilyWild 65535
int
TRANS(ConvertAddress)(int *familyp, int *addrlenp, Xtransaddr **addrp)
{
PRMSG(2,"ConvertAddress(%d,%d,%x)\n",*familyp,*addrlenp,*addrp);
switch( *familyp )
{
#if defined(TCPCONN) || defined(STREAMSCONN)
case AF_INET:
{
struct sockaddr_in saddr;
#ifdef CRAY
#ifdef OLDTCP
int len = sizeof(saddr.sin_addr);
#else
int len = SIZEOF_in_addr;
#endif
char *cp = (char *) &saddr.sin_addr;
#else
int len = sizeof(saddr.sin_addr.s_addr);
char *cp = (char *) &saddr.sin_addr.s_addr;
#endif
memcpy (&saddr, *addrp, sizeof (struct sockaddr_in));
if ((len == 4) && (cp[0] == 127) && (cp[1] == 0) &&
(cp[2] == 0) && (cp[3] == 1))
{
*familyp=FamilyLocal;
}
else
{
*familyp=FamilyInternet;
*addrlenp=len;
memcpy(*addrp,&saddr.sin_addr,len);
}
break;
}
#if defined(IPv6) && defined(AF_INET6)
case AF_INET6:
{
struct sockaddr_in6 saddr6;
memcpy (&saddr6, *addrp, sizeof (struct sockaddr_in6));
if (IN6_IS_ADDR_LOOPBACK(&saddr6.sin6_addr))
{
*familyp=FamilyLocal;
}
else if (IN6_IS_ADDR_V4MAPPED(&(saddr6.sin6_addr))) {
char *cp = (char *) &saddr6.sin6_addr.s6_addr[12];
if ((cp[0] == 127) && (cp[1] == 0) &&
(cp[2] == 0) && (cp[3] == 1))
{
*familyp=FamilyLocal;
}
else
{
*familyp=FamilyInternet;
*addrlenp = sizeof (struct in_addr);
memcpy(*addrp,cp,*addrlenp);
}
}
else
{
*familyp=FamilyInternet6;
*addrlenp=sizeof(saddr6.sin6_addr);
memcpy(*addrp,&saddr6.sin6_addr,sizeof(saddr6.sin6_addr));
}
break;
}
#endif
#endif
#if defined(DNETCONN)
case AF_DECnet:
{
struct sockaddr_dn saddr;
memcpy (&saddr, *addrp, sizeof (struct sockaddr_dn));
*familyp=FamilyDECnet;
*addrlenp=sizeof(struct dn_naddr);
memcpy(*addrp,&saddr.sdn_add,*addrlenp);
break;
}
#endif
#if defined(UNIXCONN) || defined(LOCALCONN) || defined(OS2PIPECONN)
case AF_UNIX:
{
*familyp=FamilyLocal;
break;
}
#endif
default:
PRMSG(1,"ConvertAddress: Unknown family type %d\n",
*familyp, 0,0 );
return -1;
}
if (*familyp == FamilyLocal)
{
char hostnamebuf[256];
int len = TRANS(GetHostname) (hostnamebuf, sizeof hostnamebuf);
if (len > 0) {
if (*addrp && *addrlenp < (len + 1))
{
xfree ((char *) *addrp);
*addrp = NULL;
}
if (!*addrp)
*addrp = (Xtransaddr *) xalloc (len + 1);
if (*addrp) {
strcpy ((char *) *addrp, hostnamebuf);
*addrlenp = len;
} else {
*addrlenp = 0;
}
}
else
{
if (*addrp)
xfree ((char *) *addrp);
*addrp = NULL;
*addrlenp = 0;
}
}
return 0;
}
#endif
#ifdef ICE_t
#include <signal.h>
char *
TRANS(GetMyNetworkId) (XtransConnInfo ciptr)
{
int family = ciptr->family;
char *addr = ciptr->addr;
char hostnamebuf[256];
char *networkId = NULL;
char *transName = ciptr->transptr->TransName;
if (gethostname (hostnamebuf, sizeof (hostnamebuf)) < 0)
{
return (NULL);
}
switch (family)
{
#if defined(UNIXCONN) || defined(STREAMSCONN) || defined(LOCALCONN) || defined(OS2PIPECONN)
case AF_UNIX:
{
struct sockaddr_un *saddr = (struct sockaddr_un *) addr;
networkId = (char *) xalloc (3 + strlen (transName) +
strlen (hostnamebuf) + strlen (saddr->sun_path));
sprintf (networkId, "%s/%s:%s", transName,
hostnamebuf, saddr->sun_path);
break;
}
#endif
#if defined(TCPCONN) || defined(STREAMSCONN)
case AF_INET:
#if defined(IPv6) && defined(AF_INET6)
case AF_INET6:
#endif
{
struct sockaddr_in *saddr = (struct sockaddr_in *) addr;
#if defined(IPv6) && defined(AF_INET6)
struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *) addr;
#endif
int portnum;
char portnumbuf[10];
#if defined(IPv6) && defined(AF_INET6)
if (family == AF_INET6)
portnum = ntohs (saddr6->sin6_port);
else
#endif
portnum = ntohs (saddr->sin_port);
sprintf (portnumbuf, "%d", portnum);
networkId = (char *) xalloc (3 + strlen (transName) +
strlen (hostnamebuf) + strlen (portnumbuf));
sprintf (networkId, "%s/%s:%s", transName, hostnamebuf, portnumbuf);
break;
}
#endif
#if defined(DNETCONN)
case AF_DECnet:
{
struct sockaddr_dn *saddr = (struct sockaddr_dn *) addr;
networkId = (char *) xalloc (
13 + strlen (hostnamebuf) + saddr->sdn_objnamel);
sprintf (networkId, "dnet/%s::%s",
hostnamebuf, saddr->sdn_objname);
break;
}
#endif
default:
break;
}
return (networkId);
}
#include <setjmp.h>
static jmp_buf env;
#ifdef SIGALRM
static volatile int nameserver_timedout = 0;
static
#ifdef SIGNALRETURNSINT
int
#else
void
#endif
nameserver_lost(int sig)
{
nameserver_timedout = 1;
longjmp (env, -1);
#ifdef SIGNALRETURNSINT
return -1;
#endif
}
#endif
char *
TRANS(GetPeerNetworkId) (XtransConnInfo ciptr)
{
int family = ciptr->family;
char *peer_addr = ciptr->peeraddr;
char *hostname;
char addrbuf[256];
const char *addr = NULL;
switch (family)
{
case AF_UNSPEC:
#if defined(UNIXCONN) || defined(STREAMSCONN) || defined(LOCALCONN) || defined(OS2PIPECONN)
case AF_UNIX:
{
if (gethostname (addrbuf, sizeof (addrbuf)) == 0)
addr = addrbuf;
break;
}
#endif
#if defined(TCPCONN) || defined(STREAMSCONN)
case AF_INET:
#if defined(IPv6) && defined(AF_INET6)
case AF_INET6:
#endif
{
struct sockaddr_in *saddr = (struct sockaddr_in *) peer_addr;
#if defined(IPv6) && defined(AF_INET6)
struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *) peer_addr;
#endif
char *address;
int addresslen;
#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
_Xgethostbynameparams hparams;
#endif
struct hostent * volatile hostp = NULL;
#if defined(IPv6) && defined(AF_INET6)
if (family == AF_INET6)
{
address = (char *) &saddr6->sin6_addr;
addresslen = sizeof (saddr6->sin6_addr);
}
else
#endif
{
address = (char *) &saddr->sin_addr;
addresslen = sizeof (saddr->sin_addr);
}
#ifdef SIGALRM
nameserver_timedout = 0;
signal (SIGALRM, nameserver_lost);
alarm (4);
if (setjmp(env) == 0) {
#endif
hostp = _XGethostbyaddr (address, addresslen, family, hparams);
#ifdef SIGALRM
}
alarm (0);
#endif
if (hostp != NULL)
addr = hostp->h_name;
else
#if defined(IPv6) && defined(AF_INET6)
addr = inet_ntop (family, address, addrbuf, sizeof (addrbuf));
#else
addr = inet_ntoa (saddr->sin_addr);
#endif
break;
}
#endif
#if defined(DNETCONN)
case AF_DECnet:
{
struct sockaddr_dn *saddr = (struct sockaddr_dn *) peer_addr;
struct nodeent *np;
if (np = getnodebyaddr(saddr->sdn_add.a_addr,
saddr->sdn_add.a_len, AF_DECnet)) {
sprintf(addrbuf, "%s:", np->n_name);
} else {
sprintf(addrbuf, "%s:", dnet_htoa(&saddr->sdn_add));
}
addr = addrbuf;
break;
}
#endif
default:
return (NULL);
}
hostname = (char *) xalloc (
strlen (ciptr->transptr->TransName) + strlen (addr) + 2);
strcpy (hostname, ciptr->transptr->TransName);
strcat (hostname, "/");
if (addr)
strcat (hostname, addr);
return (hostname);
}
#endif
#if defined(WIN32) && (defined(TCPCONN) || defined(DNETCONN))
int
TRANS(WSAStartup) (void)
{
static WSADATA wsadata;
PRMSG (2,"WSAStartup()\n", 0, 0, 0);
if (!wsadata.wVersion && WSAStartup(MAKEWORD(1,1), &wsadata))
return 1;
return 0;
}
#endif
static int
is_numeric (char *str)
{
int i;
for (i = 0; i < (int) strlen (str); i++)
if (!isdigit (str[i]))
return (0);
return (1);
}
#ifdef TRANS_SERVER
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#if !defined(S_IFLNK) && !defined(S_ISLNK)
#define lstat(a,b) stat(a,b)
#endif
static int
trans_mkdir(char *path, int mode)
{
struct stat buf;
if (mkdir(path, mode) == 0) {
chmod(path, mode);
return 0;
}
if (errno == EEXIST) {
if (lstat(path, &buf) != 0) {
PRMSG(1, "mkdir: (l)stat failed for %s (%d)\n",
path, errno, 0);
return -1;
}
if (S_ISDIR(buf.st_mode)) {
int updateOwner = 0;
int updateMode = 0;
int updatedOwner = 0;
int updatedMode = 0;
if (buf.st_uid != 0)
updateOwner = 1;
if ((~mode) & 0077 & buf.st_mode)
updateMode = 1;
if ((mode & 01000) &&
(buf.st_mode & 0002) && !(buf.st_mode & 01000))
updateMode = 1;
#ifdef HAS_FCHOWN
if (updateMode || updateOwner) {
int fd = -1;
struct stat fbuf;
if ((fd = open(path, O_RDONLY)) != -1) {
if (fstat(fd, &fbuf) == -1) {
PRMSG(1, "mkdir: fstat failed for %s (%d)\n",
path, errno, 0);
return -1;
}
if (!S_ISDIR(fbuf.st_mode) ||
buf.st_dev != fbuf.st_dev ||
buf.st_ino != fbuf.st_ino) {
PRMSG(1, "mkdir: inode for %s changed\n",
path, 0, 0);
return -1;
}
if (updateOwner && fchown(fd, 0, 0) == 0)
updatedOwner = 1;
if (updateMode && fchmod(fd, mode) == 0)
updatedMode = 1;
close(fd);
}
}
#endif
if (updateOwner && !updatedOwner) {
PRMSG(1, "mkdir: Owner of %s should be set to root\n",
path, 0, 0);
#if !defined(__CYGWIN__) && !defined(__DARWIN__)
sleep(5);
#endif
}
if (updateMode && !updatedMode) {
PRMSG(1, "mkdir: Mode of %s should be set to %04o\n",
path, mode, 0);
#if !defined(__CYGWIN__) && !defined(__DARWIN__)
sleep(5);
#endif
}
return 0;
}
}
return -1;
}
#endif