#ifndef WIN32
#include <netdnet/dn.h>
#include <netdnet/dnetdb.h>
#include <sys/ioctl.h>
#endif
#include <stdio.h>
#ifdef WIN32
#define _WILLWINSOCK_
#define BOOL wBOOL
#undef Status
#define Status wStatus
#include <prgpre.h>
#undef Status
#define Status int
#undef BOOL
#include <X11/Xw32defs.h>
#undef close
#define close closesocket
#endif
#if defined(X11_t)
#define DNETOBJ "X$X"
#endif
#if defined(XIM_t)
#define DNETOBJ "IMSERVER$"
#endif
#if defined(FS_t) || defined(FONT_t)
#define DNETOBJ "X$FONT"
#endif
#if defined(ICE_t)
#define DNETOBJ ""
#endif
#if defined(TEST_t)
#define DNETOBJ "X$TEST"
#endif
static int
TRANS(DNETGetAddr) (XtransConnInfo ciptr)
{
struct sockaddr_dn sockname;
int namelen = sizeof(sockname);
PRMSG (3,"DNETGetAddr(%x)\n", ciptr, 0, 0);
if (getsockname (ciptr->fd, (struct sockaddr *) &sockname, &namelen) < 0)
{
PRMSG (1,"DNETGetAddr: getsockname() failed: %d\n",
EGET(), 0, 0);
return -1;
}
if ((ciptr->addr = (char *) xalloc (namelen)) == NULL)
{
PRMSG (1, "DNETGetAddr: Can't allocate space for the addr\n",
0, 0, 0);
return -1;
}
ciptr->family = sockname.sdn_family;
ciptr->addrlen = namelen;
memcpy (ciptr->addr, &sockname, ciptr->addrlen);
return 0;
}
static int
TRANS(DNETGetPeerAddr) (XtransConnInfo ciptr)
{
struct sockaddr_dn sockname;
int namelen = sizeof(sockname);
PRMSG (3,"DNETGetPeerAddr(%x)\n", ciptr, 0, 0);
if (getpeername (ciptr->fd, (struct sockaddr *) &sockname, &namelen) < 0)
{
PRMSG (1,"DNETGetPeerAddr: getpeername() failed: %d\n",
EGET(), 0, 0);
return -1;
}
if ((ciptr->peeraddr = (char *) xalloc (namelen)) == NULL)
{
PRMSG (1,
"DNETGetPeerAddr: Can't allocate space for the addr\n",
0, 0, 0);
return -1;
}
ciptr->peeraddrlen = namelen;
memcpy (ciptr->peeraddr, &sockname, ciptr->peeraddrlen);
return 0;
}
#ifdef TRANS_CLIENT
static XtransConnInfo
TRANS(DNETOpenCOTSClient) (Xtransport *thistrans, char *protocol,
char *host, char *port)
{
XtransConnInfo ciptr;
PRMSG (2,"DNETOpenCOTSClient(%s,%s,%s)\n", protocol, host, port);
if ((ciptr = (XtransConnInfo) xcalloc (
1, sizeof(struct _XtransConnInfo))) == NULL)
{
PRMSG (1, "DNETOpenCOTSClient: malloc failed\n", 0, 0, 0);
return NULL;
}
ciptr->index = 0;
return ciptr;
}
#endif
#ifdef TRANS_SERVER
static XtransConnInfo
TRANS(DNETOpenCOTSServer) (Xtransport *thistrans, char *protocol,
char *host, char *port)
{
XtransConnInfo ciptr;
PRMSG (2,"DNETOpenCOTSServer(%s,%s,%s)\n", protocol, host, port);
if ((ciptr = (XtransConnInfo) xcalloc (
1, sizeof(struct _XtransConnInfo))) == NULL)
{
PRMSG (1, "DNETOpenCOTSServer: malloc failed\n", 0, 0, 0);
return NULL;
}
if ((ciptr->fd = socket (AF_DECnet, SOCK_STREAM, 0)) < 0)
{
xfree ((char *) ciptr);
return NULL;
}
ciptr->index = 0;
return (ciptr);
}
#endif
#ifdef TRANS_CLIENT
static XtransConnInfo
TRANS(DNETOpenCLTSClient) (Xtransport *thistrans, char *protocol,
char *host, char *port)
{
XtransConnInfo ciptr;
PRMSG (2,"DNETOpenCLTSClient(%s,%s,%s)\n", protocol, host, port);
if ((ciptr = (XtransConnInfo) xcalloc (
1, sizeof (struct _XtransConnInfo))) == NULL)
{
PRMSG (1, "DNETOpenCLTSClient: malloc failed\n", 0, 0, 0);
return NULL;
}
ciptr->index = 0;
return ciptr;
}
#endif
#ifdef TRANS_SERVER
static XtransConnInfo
TRANS(DNETOpenCLTSServer) (Xtransport *thistrans, char *protocol,
char *host, char *port)
{
PRMSG (2,"DNETOpenCLTSServer(%s,%s,%s)\n", protocol, host, port);
return NULL;
}
#endif
#ifdef TRANS_REOPEN
static XtransConnInfo
TRANS(DNETReopenCOTSServer) (Xtransport *thistrans, int fd, char *port)
{
XtransConnInfo ciptr;
PRMSG (2,"DNETReopenCOTSServer(%d,%s)\n", fd, port, 0);
if ((ciptr = (XtransConnInfo) xcalloc (
1, sizeof(struct _XtransConnInfo))) == NULL)
{
PRMSG (1, "DNETReopenCOTSServer: malloc failed\n", 0, 0, 0);
return NULL;
}
ciptr->fd = fd;
ciptr->index = 0;
return (ciptr);
}
static XtransConnInfo
TRANS(DNETReopenCLTSServer) (Xtransport *thistrans, int fd, char *port)
{
XtransConnInfo ciptr;
PRMSG (2,"DNETReopenCLTSServer(%d,%s)\n", fd, port, 0);
if ((ciptr = (XtransConnInfo) xcalloc (
1, sizeof(struct _XtransConnInfo))) == NULL)
{
PRMSG (1, "DNETReopenCLTSServer: malloc failed\n", 0, 0, 0);
return NULL;
}
ciptr->fd = fd;
ciptr->index = 0;
return (ciptr);
}
#endif
static int
TRANS(DNETSetOption) (XtransConnInfo ciptr, int option, int arg)
{
PRMSG (2,"DNETSetOption(%d,%d,%d)\n", ciptr->fd, option, arg);
return -1;
}
#ifdef TRANS_SERVER
static int
TRANS(DNETCreateListener) (XtransConnInfo ciptr, char *port, unsigned int flags)
{
struct sockaddr_dn dnsock;
int fd = ciptr->fd;
PRMSG (3, "DNETCreateListener(%x,%d)\n", ciptr, fd, 0);
bzero ((char *) &dnsock, sizeof (dnsock));
dnsock.sdn_family = AF_DECnet;
if (port && *port )
sprintf (dnsock.sdn_objname, "%s%s", DNETOBJ, port);
else
#ifdef X11_t
return -1;
#else
sprintf (dnsock.sdn_objname, "%s%d", DNETOBJ, getpid ());
#endif
dnsock.sdn_objnamel = strlen (dnsock.sdn_objname);
if (bind (fd, (struct sockaddr *) &dnsock, sizeof (dnsock)))
{
close (fd);
return -1;
}
if (listen (fd, 5))
{
close (fd);
return (-1);
}
ciptr->flags = 1 | (ciptr->flags & TRANS_KEEPFLAGS);
return 0;
}
static XtransConnInfo
TRANS(DNETAccept) (XtransConnInfo ciptr, int *status)
{
XtransConnInfo newciptr;
struct sockaddr_dn sockname;
int namelen = sizeof(sockname);
PRMSG (2, "DNETAccept(%x,%d)\n", ciptr, ciptr->fd, 0);
if ((newciptr = (XtransConnInfo) xcalloc(
1, sizeof (struct _XtransConnInfo))) == NULL)
{
PRMSG (1, "DNETAccept: malloc failed\n", 0, 0, 0);
*status = TRANS_ACCEPT_BAD_MALLOC;
return NULL;
}
if((newciptr->fd = accept (ciptr->fd,
(struct sockaddr *) &sockname, &namelen)) < 0)
{
PRMSG (1, "DNETAccept: accept() failed\n", 0, 0, 0);
xfree (newciptr);
*status = TRANS_ACCEPT_FAILED;
return NULL;
}
if (TRANS(DNETGetAddr) (newciptr) < 0)
{
PRMSG(1,
"DNETAccept: ...DNETGetAddr() failed:\n", 0, 0, 0);
close (newciptr->fd);
xfree (newciptr);
*status = TRANS_ACCEPT_MISC_ERROR;
return NULL;
}
if (TRANS(DNETGetPeerAddr) (newciptr) < 0)
{
PRMSG(1,
"DNETAccept: ...DNETGetPeerAddr() failed:\n", 0, 0, 0);
close (newciptr->fd);
if (newciptr->addr) xfree (newciptr->addr);
xfree (newciptr);
*status = TRANS_ACCEPT_MISC_ERROR;
return NULL;
}
*status = 0;
return newciptr;
}
#endif
#ifdef TRANS_CLIENT
#define OBJBUFSIZE 64
static int
TRANS(DNETConnect) (XtransConnInfo ciptr, char *host, char *port)
{
char objname[OBJBUFSIZE];
extern int dnet_conn();
PRMSG (2,"DNETConnect(%d,%s,%s)\n", ciptr->fd, host, port);
#ifdef X11_t
if (is_numeric (port))
{
short tmpport = (short) atoi (port);
sprintf (objname, "X$X%d", tmpport);
}
else
#endif
strncpy(objname, port, OBJBUFSIZE);
if (!host) host = "0";
if ((ciptr->fd = dnet_conn (host, objname, SOCK_STREAM, 0, 0, 0, 0)) < 0)
{
return TRANS_CONNECT_FAILED;
}
if (TRANS(DNETGetAddr) (ciptr) < 0)
{
PRMSG (1,
"DNETConnect: ...DNETGetAddr() failed:\n", 0, 0, 0);
return TRANS_CONNECT_FAILED;
}
if (TRANS(DNETGetPeerAddr) (ciptr) < 0)
{
PRMSG (1,
"DNETConnect: ...DNETGetPeerAddr() failed:\n",
0, 0, 0);
return TRANS_CONNECT_FAILED;
}
return 0;
}
#endif
static int
TRANS(DNETBytesReadable) (XtransConnInfo ciptr, BytesReadable_t *pend)
{
PRMSG (2,"DNETBytesReadable(%x,%d,%x)\n", ciptr, ciptr->fd, pend);
#ifdef WIN32
return ioctlsocket ((SOCKET) ciptr->fd, FIONREAD, (u_long *) pend);
#else
return ioctl(ciptr->fd, FIONREAD, (char *)pend);
#endif
}
static int
TRANS(DNETRead) (XtransConnInfo ciptr, char *buf, int size)
{
PRMSG (2,"DNETRead(%d,%x,%d)\n", ciptr->fd, buf, size);
#ifdef WIN32
return recv ((SOCKET)ciptr->fd, buf, size, 0);
#else
return read (ciptr->fd, buf, size);
#endif
}
static int
TRANS(DNETWrite) (XtransConnInfo ciptr, char *buf, int size)
{
PRMSG (2,"DNETWrite(%d,%x,%d)\n", ciptr->fd, buf, size);
#ifdef WIN32
return send ((SOCKET)ciptr->fd, buf, size, 0);
#else
return write (ciptr->fd, buf, size);
#endif
}
static int
TRANS(DNETReadv) (XtransConnInfo ciptr, struct iovec *buf, int size)
{
PRMSG (2,"DNETReadv(%d,%x,%d)\n", ciptr->fd, buf, size);
return READV (ciptr, buf, size);
}
static int
TRANS(DNETWritev) (XtransConnInfo ciptr, struct iovec *buf, int size)
{
PRMSG (2,"DNETWritev(%d,%x,%d)\n", ciptr->fd, buf, size);
return WRITEV (ciptr, buf, size);
}
static int
TRANS(DNETDisconnect) (XtransConnInfo ciptr)
{
PRMSG (2,"DNETDisconnect(%x,%d)\n", ciptr, ciptr->fd, 0);
return shutdown (ciptr->fd, 2);
}
static int
TRANS(DNETClose) (XtransConnInfo ciptr)
{
PRMSG (2,"DNETClose(%x,%d)\n", ciptr, ciptr->fd, 0);
return close (ciptr->fd);
}
Xtransport TRANS(DNETFuncs) = {
"dnet",
0,
#ifdef TRANS_CLIENT
TRANS(DNETOpenCOTSClient),
#endif
#ifdef TRANS_SERVER
TRANS(DNETOpenCOTSServer),
#endif
#ifdef TRANS_CLIENT
TRANS(DNETOpenCLTSClient),
#endif
#ifdef TRANS_SERVER
TRANS(DNETOpenCLTSServer),
#endif
#ifdef TRANS_REOPEN
TRANS(DNETReopenCOTSServer),
TRANS(DNETReopenCLTSServer),
#endif
TRANS(DNETSetOption),
#ifdef TRANS_SERVER
TRANS(DNETCreateListener),
NULL,
TRANS(DNETAccept),
#endif
#ifdef TRANS_CLIENT
TRANS(DNETConnect),
#endif
TRANS(DNETBytesReadable),
TRANS(DNETRead),
TRANS(DNETWrite),
TRANS(DNETReadv),
TRANS(DNETWritev),
TRANS(DNETDisconnect),
TRANS(DNETClose),
TRANS(DNETClose),
};