#include <errno.h>
#include <ctype.h>
#include <sys/signal.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#if defined(SVR4)
#include <sys/filio.h>
#endif
#ifdef sun
# include <stropts.h>
#else
# include <sys/stropts.h>
#endif
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/socket.h>
#ifndef X_NO_SYS_UN
#include <sys/un.h>
#endif
#if !defined(sun)
# define LOCAL_TRANS_PTS
#endif
#if defined(SVR4) || defined(__SVR4)
# define LOCAL_TRANS_NAMED
#endif
#if defined(__SCO__) || defined(__UNIXWARE__)
# define LOCAL_TRANS_SCO
#endif
static int TRANS(LocalClose)(XtransConnInfo ciptr);
static int
TRANS(OpenFail)(XtransConnInfo ciptr, char *port)
{
return -1;
}
#ifdef TRANS_REOPEN
static int
TRANS(ReopenFail)(XtransConnInfo ciptr, int fd, char *port)
{
return 0;
}
#endif
static int
TRANS(FillAddrInfo)(XtransConnInfo ciptr, char *sun_path, char *peer_sun_path)
{
struct sockaddr_un *sunaddr;
struct sockaddr_un *p_sunaddr;
ciptr->family = AF_UNIX;
ciptr->addrlen = sizeof (struct sockaddr_un);
if ((sunaddr = (struct sockaddr_un *) xalloc (ciptr->addrlen)) == NULL)
{
PRMSG(1,"FillAddrInfo: failed to allocate memory for addr\n", 0, 0, 0);
return 0;
}
sunaddr->sun_family = AF_UNIX;
if (strlen(sun_path) > sizeof(sunaddr->sun_path) - 1) {
PRMSG(1, "FillAddrInfo: path too long\n", 0, 0, 0);
return 0;
}
strcpy (sunaddr->sun_path, sun_path);
#if defined(BSD44SOCKETS)
sunaddr->sun_len = strlen (sunaddr->sun_path);
#endif
ciptr->addr = (char *) sunaddr;
ciptr->peeraddrlen = sizeof (struct sockaddr_un);
if ((p_sunaddr = (struct sockaddr_un *) xalloc (
ciptr->peeraddrlen)) == NULL)
{
PRMSG(1,
"FillAddrInfo: failed to allocate memory for peer addr\n",
0,0,0);
xfree ((char *) sunaddr);
ciptr->addr = NULL;
return 0;
}
p_sunaddr->sun_family = AF_UNIX;
if (strlen(peer_sun_path) > sizeof(p_sunaddr->sun_path) - 1) {
PRMSG(1, "FillAddrInfo: peer path too long\n", 0, 0, 0);
return 0;
}
strcpy (p_sunaddr->sun_path, peer_sun_path);
#if defined(BSD44SOCKETS)
p_sunaddr->sun_len = strlen (p_sunaddr->sun_path);
#endif
ciptr->peeraddr = (char *) p_sunaddr;
return 1;
}
#ifdef LOCAL_TRANS_PTS
#if defined(SYSV) && !defined(__SCO__)
#define SIGNAL_T int
#else
#define SIGNAL_T void
#endif
typedef SIGNAL_T (*PFV)();
extern PFV signal();
extern char *ptsname(
int
);
static void _dummy(int sig)
{
}
#endif
#ifndef sun
#define X_STREAMS_DIR "/dev/X"
#define DEV_SPX "/dev/spx"
#else
#ifndef X11_t
#define X_STREAMS_DIR "/dev/X"
#else
#define X_STREAMS_DIR "/tmp/.X11-pipe"
#endif
#endif
#define DEV_PTMX "/dev/ptmx"
#if defined(X11_t)
#define PTSNODENAME "/dev/X/server."
#ifdef sun
#define NAMEDNODENAME "/tmp/.X11-pipe/X"
#else
#define NAMEDNODENAME "/dev/X/Nserver."
#define SCORNODENAME "/dev/X%1sR"
#define SCOSNODENAME "/dev/X%1sS"
#endif
#endif
#if defined(XIM_t)
#ifdef sun
#define NAMEDNODENAME "/tmp/.XIM-pipe/XIM"
#else
#define PTSNODENAME "/dev/X/XIM."
#define NAMEDNODENAME "/dev/X/NXIM."
#define SCORNODENAME "/dev/XIM.%sR"
#define SCOSNODENAME "/dev/XIM.%sS"
#endif
#endif
#if defined(FS_t) || defined (FONT_t)
#ifdef sun
#define NAMEDNODENAME "/tmp/.font-pipe/fs"
#else
#define PTSNODENAME "/dev/X/fontserver."
#define NAMEDNODENAME "/dev/X/Nfontserver."
#define SCORNODENAME "/dev/fontserver.%sR"
#define SCOSNODENAME "/dev/fontserver.%sS"
#endif
#endif
#if defined(ICE_t)
#ifdef sun
#define NAMEDNODENAME "/tmp/.ICE-pipe/"
#else
#define PTSNODENAME "/dev/X/ICE."
#define NAMEDNODENAME "/dev/X/NICE."
#define SCORNODENAME "/dev/ICE.%sR"
#define SCOSNODENAME "/dev/ICE.%sS"
#endif
#endif
#if defined(TEST_t)
#ifdef sun
#define NAMEDNODENAME "/tmp/.Test-unix/test"
#endif
#define PTSNODENAME "/dev/X/transtest."
#define NAMEDNODENAME "/dev/X/Ntranstest."
#define SCORNODENAME "/dev/transtest.%sR"
#define SCOSNODENAME "/dev/transtest.%sS"
#endif
#ifdef LOCAL_TRANS_PTS
#ifdef TRANS_CLIENT
static int
TRANS(PTSOpenClient)(XtransConnInfo ciptr, char *port)
{
#ifdef PTSNODENAME
int fd,server,exitval,alarm_time,ret;
char server_path[64];
char *slave, namelen;
char buf[20];
PFV savef;
pid_t saved_pid;
#endif
PRMSG(2,"PTSOpenClient(%s)\n", port, 0,0 );
#if !defined(PTSNODENAME)
PRMSG(1,"PTSOpenClient: Protocol is not supported by a pts connection\n", 0,0,0);
return -1;
#else
if (port && *port ) {
if( *port == '/' ) {
(void) sprintf(server_path, "%s", port);
} else {
(void) sprintf(server_path, "%s%s", PTSNODENAME, port);
}
} else {
(void) sprintf(server_path, "%s%d", PTSNODENAME, getpid());
}
if ((server = open (server_path, O_RDWR)) < 0) {
PRMSG(1,"PTSOpenClient: failed to open %s\n", server_path, 0,0);
return -1;
}
if ((fd = open(DEV_PTMX, O_RDWR)) < 0) {
PRMSG(1,"PTSOpenClient: failed to open %s\n", DEV_PTMX, 0,0);
return(-1);
}
(void) grantpt(fd);
(void) unlockpt(fd);
slave = ptsname(fd);
if( slave == NULL ) {
PRMSG(1,"PTSOpenClient: failed to get ptsname()\n", 0,0,0);
close(fd);
close(server);
return -1;
}
if(!(saved_pid=fork())) {
uid_t saved_euid;
saved_euid = geteuid();
if (setuid( getuid() ) == -1) {
exit(1);
}
if( chown( slave, saved_euid, -1 ) < 0 ) {
exit( 1 );
}
exit( 0 );
}
waitpid(saved_pid, &exitval, 0);
if (WIFEXITED(exitval) && WEXITSTATUS(exitval) != 0) {
close(fd);
close(server);
PRMSG(1, "PTSOpenClient: cannot set the owner of %s\n",
slave, 0, 0);
return(-1);
}
if (chmod(slave, 0666) < 0) {
close(fd);
close(server);
PRMSG(1,"PTSOpenClient: Cannot chmod %s\n", slave, 0,0);
return(-1);
}
namelen = strlen(slave);
buf[0] = namelen;
(void) sprintf(&buf[1], slave);
(void) write(server, buf, namelen+1);
(void) close(server);
savef = signal(SIGALRM, _dummy);
alarm_time = alarm (30);
ret = read(fd, buf, 1);
(void) alarm(alarm_time);
(void) signal(SIGALRM, savef);
if (ret != 1) {
PRMSG(1,
"PTSOpenClient: failed to get acknoledgement from server\n", 0, 0, 0);
(void) close(fd);
fd = -1;
}
if (TRANS(FillAddrInfo) (ciptr, slave, server_path) == 0)
{
PRMSG(1,"PTSOpenClient: failed to fill in addr info\n", 0, 0, 0);
close(fd);
return -1;
}
return(fd);
#endif
}
#endif
#ifdef TRANS_SERVER
static int
TRANS(PTSOpenServer)(XtransConnInfo ciptr, char *port)
{
#ifdef PTSNODENAME
int fd, server;
char server_path[64], *slave;
int mode;
#endif
PRMSG(2,"PTSOpenServer(%s)\n", port, 0,0 );
#if !defined(PTSNODENAME)
PRMSG(1,"PTSOpenServer: Protocol is not supported by a pts connection\n", 0,0,0);
return -1;
#else
if (port && *port ) {
if( *port == '/' ) {
(void) sprintf(server_path, "%s", port);
} else {
(void) sprintf(server_path, "%s%s", PTSNODENAME, port);
}
} else {
(void) sprintf(server_path, "%s%d", PTSNODENAME, getpid());
}
#ifdef HAS_STICKY_DIR_BIT
mode = 01777;
#else
mode = 0777;
#endif
if (trans_mkdir(X_STREAMS_DIR, mode) == -1) {
PRMSG (1, "PTSOpenServer: mkdir(%s) failed, errno = %d\n",
X_STREAMS_DIR, errno, 0);
return(-1);
}
#if 0
if( (fd=open(server_path, O_RDWR)) >= 0 ) {
PRMSG(1, "PTSOpenServer: A server is already running on port %s\n", port, 0,0 );
PRMSG(1, "PTSOpenServer: Remove %s if this is incorrect.\n", server_path, 0,0 );
close(fd);
return(-1);
}
#else
#endif
unlink(server_path);
if( (fd=open(DEV_PTMX, O_RDWR)) < 0) {
PRMSG(1, "PTSOpenServer: Unable to open %s\n", DEV_PTMX, 0,0 );
return(-1);
}
grantpt(fd);
unlockpt(fd);
if( (slave=ptsname(fd)) == NULL) {
PRMSG(1, "PTSOpenServer: Unable to get slave device name\n", 0,0,0 );
close(fd);
return(-1);
}
if( link(slave,server_path) < 0 ) {
PRMSG(1, "PTSOpenServer: Unable to link %s to %s\n", slave, server_path,0 );
close(fd);
return(-1);
}
if( chmod(server_path, 0666) < 0 ) {
PRMSG(1, "PTSOpenServer: Unable to chmod %s to 0666\n", server_path,0,0 );
close(fd);
return(-1);
}
if( (server=open(server_path, O_RDWR)) < 0 ) {
PRMSG(1, "PTSOpenServer: Unable to open server device %s\n", server_path,0,0 );
close(fd);
return(-1);
}
close(server);
if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
{
PRMSG(1,"PTSOpenServer: failed to fill in addr info\n", 0, 0, 0);
close(fd);
return -1;
}
return fd;
#endif
}
static int
TRANS(PTSAccept)(XtransConnInfo ciptr, XtransConnInfo newciptr, int *status)
{
int newfd;
int in;
unsigned char length;
char buf[256];
struct sockaddr_un *sunaddr;
PRMSG(2,"PTSAccept(%x->%d)\n",ciptr,ciptr->fd,0);
if( (in=read(ciptr->fd,&length,1)) <= 0 ){
if( !in ) {
PRMSG(2,
"PTSAccept: Incoming connection closed\n",0,0,0);
}
else {
PRMSG(1,
"PTSAccept: Error reading incoming connection. errno=%d \n",
errno,0,0);
}
*status = TRANS_ACCEPT_MISC_ERROR;
return -1;
}
if( (in=read(ciptr->fd,buf,length)) <= 0 ){
if( !in ) {
PRMSG(2,
"PTSAccept: Incoming connection closed\n",0,0,0);
}
else {
PRMSG(1,
"PTSAccept: Error reading device name for new connection. errno=%d \n",
errno,0,0);
}
*status = TRANS_ACCEPT_MISC_ERROR;
return -1;
}
buf[length] = '\0';
if( (newfd=open(buf,O_RDWR)) < 0 ) {
PRMSG(1, "PTSAccept: Failed to open %s\n",buf,0,0);
*status = TRANS_ACCEPT_MISC_ERROR;
return -1;
}
write(newfd,"1",1);
newciptr->addrlen=ciptr->addrlen;
if( (newciptr->addr=(char *)xalloc(newciptr->addrlen)) == NULL ) {
PRMSG(1,"PTSAccept: failed to allocate memory for peer addr\n",
0,0,0);
close(newfd);
*status = TRANS_ACCEPT_BAD_MALLOC;
return -1;
}
memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen);
newciptr->peeraddrlen=sizeof(struct sockaddr_un);
if( (sunaddr=(struct sockaddr_un *)xalloc(newciptr->peeraddrlen)) == NULL ) {
PRMSG(1,"PTSAccept: failed to allocate memory for peer addr\n",
0,0,0);
xfree(newciptr->addr);
close(newfd);
*status = TRANS_ACCEPT_BAD_MALLOC;
return -1;
}
sunaddr->sun_family=AF_UNIX;
strcpy(sunaddr->sun_path,buf);
#if defined(BSD44SOCKETS)
sunaddr->sun_len=strlen(sunaddr->sun_path);
#endif
newciptr->peeraddr=(char *)sunaddr;
*status = 0;
return newfd;
}
#endif
#endif
#ifdef LOCAL_TRANS_NAMED
#ifdef TRANS_CLIENT
static int
TRANS(NAMEDOpenClient)(XtransConnInfo ciptr, char *port)
{
#ifdef NAMEDNODENAME
int fd;
char server_path[64];
struct stat filestat;
# ifndef sun
extern int isastream(int);
# endif
#endif
PRMSG(2,"NAMEDOpenClient(%s)\n", port, 0,0 );
#if !defined(NAMEDNODENAME)
PRMSG(1,"NAMEDOpenClient: Protocol is not supported by a NAMED connection\n", 0,0,0);
return -1;
#else
if ( port && *port ) {
if( *port == '/' ) {
(void) snprintf(server_path, sizeof(server_path), "%s", port);
} else {
(void) snprintf(server_path, sizeof(server_path), "%s%s", NAMEDNODENAME, port);
}
} else {
(void) snprintf(server_path, sizeof(server_path), "%s%ld", NAMEDNODENAME, (long)getpid());
}
if ((fd = open(server_path, O_RDWR)) < 0) {
PRMSG(1,"NAMEDOpenClient: Cannot open %s for NAMED connection\n", server_path, 0,0 );
return -1;
}
if (fstat(fd, &filestat) < 0 ) {
PRMSG(1,"NAMEDOpenClient: Cannot stat %s for NAMED connection\n", server_path, 0,0 );
(void) close(fd);
return -1;
}
if ((filestat.st_mode & S_IFMT) != S_IFIFO) {
PRMSG(1,"NAMEDOpenClient: Device %s is not a FIFO\n", server_path, 0,0 );
(void) close(fd);
return -1;
}
if (isastream(fd) <= 0) {
PRMSG(1,"NAMEDOpenClient: %s is not a streams device\n", server_path, 0,0 );
(void) close(fd);
return -1;
}
if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
{
PRMSG(1,"NAMEDOpenClient: failed to fill in addr info\n",
0,0,0);
close(fd);
return -1;
}
return(fd);
#endif
}
#endif
#ifdef TRANS_SERVER
#ifdef NAMEDNODENAME
static int
TRANS(NAMEDOpenPipe)(const char *server_path)
{
PRMSG(2,"NAMEDOpenPipe(%s)\n", server_path, 0,0 );
int fd, pipefd[2];
struct stat sbuf;
int mode;
#if defined(sun) && defined(X11_t)
mode = 0775;
#else
#ifdef HAS_STICKY_DIR_BIT
mode = 01777;
#else
mode = 0777;
#endif
#endif
if (trans_mkdir(X_STREAMS_DIR, mode) == -1) {
PRMSG (1, "NAMEDOpenPipe: mkdir(%s) failed, errno = %d\n",
X_STREAMS_DIR, errno, 0);
return(-1);
}
if(stat(server_path, &sbuf) != 0) {
if (errno == ENOENT) {
if ((fd = creat(server_path, (mode_t)0666)) == -1) {
PRMSG(1, "NAMEDOpenPipe: Can't open %s\n", server_path, 0,0 );
return(-1);
}
close(fd);
if (chmod(server_path, (mode_t)0666) < 0) {
PRMSG(1, "NAMEDOpenPipe: Can't open %s\n", server_path, 0,0 );
return(-1);
}
} else {
PRMSG(1, "NAMEDOpenPipe: stat on %s failed\n", server_path, 0,0 );
return(-1);
}
}
if( pipe(pipefd) != 0) {
PRMSG(1, "NAMEDOpenPipe: pipe() failed, errno=%d\n",errno, 0,0 );
return(-1);
}
if( ioctl(pipefd[0], I_PUSH, "connld") != 0) {
PRMSG(1, "NAMEDOpenPipe: ioctl(I_PUSH,\"connld\") failed, errno=%d\n",errno, 0,0 );
close(pipefd[0]);
close(pipefd[1]);
return(-1);
}
if( fattach(pipefd[0], server_path) != 0) {
PRMSG(1, "NAMEDOpenPipe: fattach(%s) failed, errno=%d\n", server_path,errno, 0 );
close(pipefd[0]);
close(pipefd[1]);
return(-1);
}
return(pipefd[1]);
}
#endif
static int
TRANS(NAMEDOpenServer)(XtransConnInfo ciptr, char *port)
{
#ifdef NAMEDNODENAME
int fd;
char server_path[64];
#endif
PRMSG(2,"NAMEDOpenServer(%s)\n", port, 0,0 );
#if !defined(NAMEDNODENAME)
PRMSG(1,"NAMEDOpenServer: Protocol is not supported by a NAMED connection\n", 0,0,0);
return -1;
#else
if ( port && *port ) {
if( *port == '/' ) {
(void) snprintf(server_path, sizeof(server_path), "%s", port);
} else {
(void) snprintf(server_path, sizeof(server_path), "%s%s",
NAMEDNODENAME, port);
}
} else {
(void) snprintf(server_path, sizeof(server_path), "%s%ld",
NAMEDNODENAME, (long)getpid());
}
fd = TRANS(NAMEDOpenPipe)(server_path);
if (fd < 0) {
return -1;
}
if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
{
PRMSG(1,"NAMEDOpenServer: failed to fill in addr info\n", 0,0,0);
TRANS(LocalClose)(ciptr);
return -1;
}
return fd;
#endif
}
static int
TRANS(NAMEDResetListener) (XtransConnInfo ciptr)
{
int status = TRANS_RESET_NOOP;
struct sockaddr_un *sockname=(struct sockaddr_un *) ciptr->addr;
struct stat statb;
PRMSG(2,"NAMEDResetListener(%p, %d)\n", ciptr, ciptr->fd, 0 );
if (ciptr->fd != -1) {
if (stat (sockname->sun_path, &statb) == -1 ||
(statb.st_mode & S_IFMT) != S_IFIFO) {
PRMSG(3, "Pipe %s trashed, recreating\n", sockname->sun_path, 0, 0);
TRANS(LocalClose)(ciptr);
ciptr->fd = TRANS(NAMEDOpenPipe)(sockname->sun_path);
if (ciptr->fd >= 0)
return TRANS_RESET_NEW_FD;
else
return TRANS_CREATE_LISTENER_FAILED;
}
}
return TRANS_RESET_NOOP;
}
static int
TRANS(NAMEDAccept)(XtransConnInfo ciptr, XtransConnInfo newciptr, int *status)
{
struct strrecvfd str;
PRMSG(2,"NAMEDAccept(%x->%d)\n", ciptr, ciptr->fd, 0 );
if( ioctl(ciptr->fd, I_RECVFD, &str ) < 0 ) {
PRMSG(1, "NAMEDAccept: ioctl(I_RECVFD) failed, errno=%d\n", errno, 0,0 );
*status = TRANS_ACCEPT_MISC_ERROR;
return(-1);
}
newciptr->family=ciptr->family;
newciptr->addrlen=ciptr->addrlen;
if( (newciptr->addr=(char *)xalloc(newciptr->addrlen)) == NULL ) {
PRMSG(1,
"NAMEDAccept: failed to allocate memory for pipe addr\n",
0,0,0);
close(str.fd);
*status = TRANS_ACCEPT_BAD_MALLOC;
return -1;
}
memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen);
newciptr->peeraddrlen=newciptr->addrlen;
if( (newciptr->peeraddr=(char *)xalloc(newciptr->peeraddrlen)) == NULL ) {
PRMSG(1,
"NAMEDAccept: failed to allocate memory for peer addr\n",
0,0,0);
xfree(newciptr->addr);
close(str.fd);
*status = TRANS_ACCEPT_BAD_MALLOC;
return -1;
}
memcpy(newciptr->peeraddr,newciptr->addr,newciptr->peeraddrlen);
*status = 0;
return str.fd;
}
#endif
#endif
#if defined(LOCAL_TRANS_SCO)
static int
connect_spipe(int fd1, int fd2)
{
long temp;
struct strfdinsert sbuf;
sbuf.databuf.maxlen = -1;
sbuf.databuf.len = -1;
sbuf.databuf.buf = NULL;
sbuf.ctlbuf.maxlen = sizeof(long);
sbuf.ctlbuf.len = sizeof(long);
sbuf.ctlbuf.buf = (caddr_t)&temp;
sbuf.offset = 0;
sbuf.fildes = fd2;
sbuf.flags = 0;
if( ioctl(fd1, I_FDINSERT, &sbuf) < 0 )
return(-1);
return(0);
}
static int
named_spipe(int fd, char *path)
{
int oldUmask, ret;
struct stat sbuf;
oldUmask = umask(0);
(void) fstat(fd, &sbuf);
ret = mknod(path, 0020666, sbuf.st_rdev);
umask(oldUmask);
if (ret < 0) {
ret = -1;
} else {
ret = fd;
}
return(ret);
}
#endif
#ifdef LOCAL_TRANS_SCO
#ifdef TRANS_CLIENT
static int
TRANS(SCOOpenClient)(XtransConnInfo ciptr, char *port)
{
#ifdef SCORNODENAME
int fd, server, fl, ret;
char server_path[64];
struct strbuf ctlbuf;
unsigned long alarm_time;
void (*savef)();
long temp;
extern int getmsg(), putmsg();
#endif
PRMSG(2,"SCOOpenClient(%s)\n", port, 0,0 );
if (!port || !port[0])
port = "0";
#if !defined(SCORNODENAME)
PRMSG(2,"SCOOpenClient: Protocol is not supported by a SCO connection\n", 0,0,0);
return -1;
#else
(void) sprintf(server_path, SCORNODENAME, port);
if ((server = open(server_path, O_RDWR)) < 0) {
PRMSG(1,"SCOOpenClient: failed to open %s\n", server_path, 0,0 );
return -1;
}
if ((fd = open(DEV_SPX, O_RDWR)) < 0) {
PRMSG(1,"SCOOpenClient: failed to open %s\n", DEV_SPX, 0,0 );
close(server);
return -1;
}
(void) write(server, &server, 1);
ctlbuf.len = 0;
ctlbuf.maxlen = sizeof(long);
ctlbuf.buf = (caddr_t)&temp;
fl = 0;
savef = signal(SIGALRM, _dummy);
alarm_time = alarm(10);
ret = getmsg(server, &ctlbuf, 0, &fl);
(void) alarm(alarm_time);
(void) signal(SIGALRM, savef);
if (ret < 0) {
PRMSG(1,"SCOOpenClient: error from getmsg\n", 0,0,0 );
close(fd);
close(server);
return -1;
}
(void) putmsg(fd, &ctlbuf, 0, 0);
(void) fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,0)|O_NDELAY);
(void) close(server);
#if defined(X11_t) && defined(__SCO__)
ciptr->flags |= TRANS_NOUNLINK;
#endif
if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
{
PRMSG(1,"SCOOpenClient: failed to fill addr info\n", 0, 0, 0);
close(fd);
return -1;
}
return(fd);
#endif
}
#endif
#ifdef TRANS_SERVER
static int
TRANS(SCOOpenServer)(XtransConnInfo ciptr, char *port)
{
#ifdef SCORNODENAME
char serverR_path[64];
char serverS_path[64];
struct flock mylock;
int fdr = -1;
int fds = -1;
#endif
PRMSG(2,"SCOOpenServer(%s)\n", port, 0,0 );
if (!port || !port[0])
port = "0";
#if !defined(SCORNODENAME)
PRMSG(1,"SCOOpenServer: Protocol is not supported by a SCO connection\n", 0,0,0);
return -1;
#else
(void) sprintf(serverR_path, SCORNODENAME, port);
(void) sprintf(serverS_path, SCOSNODENAME, port);
#if !defined(X11_t) || !defined(__SCO__)
unlink(serverR_path);
unlink(serverS_path);
if ((fds = open(DEV_SPX, O_RDWR)) < 0 ||
(fdr = open(DEV_SPX, O_RDWR)) < 0 ) {
PRMSG(1,"SCOOpenServer: failed to open %s\n", DEV_SPX, 0,0 );
return -1;
}
if (named_spipe (fds, serverS_path) == -1) {
PRMSG(1,"SCOOpenServer: failed to create %s\n", serverS_path, 0, 0);
close (fdr);
close (fds);
return -1;
}
if (named_spipe (fdr, serverR_path) == -1) {
PRMSG(1,"SCOOpenServer: failed to create %s\n", serverR_path, 0, 0);
close (fdr);
close (fds);
return -1;
}
#else
fds = open (serverS_path, O_RDWR | O_NDELAY);
if (fds < 0) {
PRMSG(1,"SCOOpenServer: failed to open %s\n", serverS_path, 0, 0);
return -1;
}
mylock.l_type = F_WRLCK;
mylock.l_whence = 0;
mylock.l_start = 0;
mylock.l_len = 0;
if (fcntl (fds, F_SETLK, &mylock) < 0) {
PRMSG(1,"SCOOpenServer: failed to lock %s\n", serverS_path, 0, 0);
close (fds);
return -1;
}
fdr = open (serverR_path, O_RDWR | O_NDELAY);
if (fds < 0) {
PRMSG(1,"SCOOpenServer: failed to open %s\n", serverR_path, 0, 0);
close (fds);
return -1;
}
#endif
if (connect_spipe(fds, fdr)) {
PRMSG(1,"SCOOpenServer: ioctl(I_FDINSERT) failed on %s\n",
serverS_path, 0, 0);
close (fdr);
close (fds);
return -1;
}
#if defined(X11_t) && defined(__SCO__)
ciptr->flags |= TRANS_NOUNLINK;
#endif
if (TRANS(FillAddrInfo) (ciptr, serverS_path, serverR_path) == 0) {
PRMSG(1,"SCOOpenServer: failed to fill in addr info\n", 0,0,0);
close(fds);
close(fdr);
return -1;
}
return(fds);
#endif
}
static int
TRANS(SCOAccept)(XtransConnInfo ciptr, XtransConnInfo newciptr, int *status)
{
char c;
int fd;
PRMSG(2,"SCOAccept(%d)\n", ciptr->fd, 0,0 );
if (read(ciptr->fd, &c, 1) < 0) {
PRMSG(1,"SCOAccept: can't read from client\n",0,0,0);
*status = TRANS_ACCEPT_MISC_ERROR;
return(-1);
}
if( (fd = open(DEV_SPX, O_RDWR)) < 0 ) {
PRMSG(1,"SCOAccept: can't open \"%s\"\n",DEV_SPX, 0,0 );
*status = TRANS_ACCEPT_MISC_ERROR;
return(-1);
}
if (connect_spipe (ciptr->fd, fd) < 0) {
PRMSG(1,"SCOAccept: ioctl(I_FDINSERT) failed\n", 0, 0, 0);
close (fd);
*status = TRANS_ACCEPT_MISC_ERROR;
return -1;
}
newciptr->addrlen=ciptr->addrlen;
if( (newciptr->addr=(char *)xalloc(newciptr->addrlen)) == NULL ) {
PRMSG(1,
"SCOAccept: failed to allocate memory for peer addr\n",
0,0,0);
close(fd);
*status = TRANS_ACCEPT_BAD_MALLOC;
return -1;
}
memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen);
#if defined(__SCO__)
newciptr->flags |= TRANS_NOUNLINK;
#endif
newciptr->peeraddrlen=newciptr->addrlen;
if( (newciptr->peeraddr=(char *)xalloc(newciptr->peeraddrlen)) == NULL ) {
PRMSG(1,
"SCOAccept: failed to allocate memory for peer addr\n",
0,0,0);
xfree(newciptr->addr);
close(fd);
*status = TRANS_ACCEPT_BAD_MALLOC;
return -1;
}
memcpy(newciptr->peeraddr,newciptr->addr,newciptr->peeraddrlen);
*status = 0;
return(fd);
}
#endif
#endif
#ifdef TRANS_REOPEN
#ifdef LOCAL_TRANS_PTS
static int
TRANS(PTSReopenServer)(XtransConnInfo ciptr, int fd, char *port)
{
#ifdef PTSNODENAME
char server_path[64];
#endif
PRMSG(2,"PTSReopenServer(%d,%s)\n", fd, port, 0 );
#if !defined(PTSNODENAME)
PRMSG(1,"PTSReopenServer: Protocol is not supported by a pts connection\n", 0,0,0);
return 0;
#else
if (port && *port ) {
if( *port == '/' ) {
(void) sprintf(server_path, "%s", port);
} else {
(void) sprintf(server_path, "%s%s", PTSNODENAME, port);
}
} else {
(void) sprintf(server_path, "%s%ld", PTSNODENAME, (long)getpid());
}
if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
{
PRMSG(1,"PTSReopenServer: failed to fill in addr info\n",
0,0,0);
return 0;
}
return 1;
#endif
}
#endif
#ifdef LOCAL_TRANS_NAMED
static int
TRANS(NAMEDReopenServer)(XtransConnInfo ciptr, int fd, char *port)
{
#ifdef NAMEDNODENAME
char server_path[64];
#endif
PRMSG(2,"NAMEDReopenServer(%s)\n", port, 0,0 );
#if !defined(NAMEDNODENAME)
PRMSG(1,"NAMEDReopenServer: Protocol is not supported by a NAMED connection\n", 0,0,0);
return 0;
#else
if ( port && *port ) {
if( *port == '/' ) {
(void) sprintf(server_path, "%s", port);
} else {
(void) sprintf(server_path, "%s%s", NAMEDNODENAME, port);
}
} else {
(void) sprintf(server_path, "%s%ld", NAMEDNODENAME, (long)getpid());
}
if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
{
PRMSG(1,"NAMEDReopenServer: failed to fill in addr info\n",
0,0,0);
return 0;
}
return 1;
#endif
}
#endif
#ifdef LOCAL_TRANS_SCO
static int
TRANS(SCOReopenServer)(XtransConnInfo ciptr, int fd, char *port)
{
#ifdef SCORNODENAME
char serverR_path[64], serverS_path[64];
#endif
PRMSG(2,"SCOReopenServer(%s)\n", port, 0,0 );
if (!port || !port[0])
port = "0";
#if !defined(SCORNODENAME)
PRMSG(2,"SCOReopenServer: Protocol is not supported by a SCO connection\n", 0,0,0);
return 0;
#else
(void) sprintf(serverR_path, SCORNODENAME, port);
(void) sprintf(serverS_path, SCOSNODENAME, port);
#if defined(X11_t) && defined(__SCO__)
ciptr->flags |= TRANS_NOUNLINK;
#endif
if (TRANS(FillAddrInfo) (ciptr, serverS_path, serverR_path) == 0)
{
PRMSG(1, "SCOReopenServer: failed to fill in addr info\n", 0,0,0);
return 0;
}
return 1;
#endif
}
#endif
#endif
typedef struct _LOCALtrans2dev {
char *transname;
#ifdef TRANS_CLIENT
int (*devcotsopenclient)(
XtransConnInfo, char *
);
#endif
#ifdef TRANS_SERVER
int (*devcotsopenserver)(
XtransConnInfo, char *
);
#endif
#ifdef TRANS_CLIENT
int (*devcltsopenclient)(
XtransConnInfo, char *
);
#endif
#ifdef TRANS_SERVER
int (*devcltsopenserver)(
XtransConnInfo, char *
);
#endif
#ifdef TRANS_REOPEN
int (*devcotsreopenserver)(
XtransConnInfo,
int,
char *
);
int (*devcltsreopenserver)(
XtransConnInfo,
int,
char *
);
#endif
#ifdef TRANS_SERVER
int (*devreset)(
XtransConnInfo
);
int (*devaccept)(
XtransConnInfo, XtransConnInfo, int *
);
#endif
} LOCALtrans2dev;
static LOCALtrans2dev LOCALtrans2devtab[] = {
#ifdef LOCAL_TRANS_PTS
{"",
#ifdef TRANS_CLIENT
TRANS(PTSOpenClient),
#endif
#ifdef TRANS_SERVER
TRANS(PTSOpenServer),
#endif
#ifdef TRANS_CLIENT
TRANS(OpenFail),
#endif
#ifdef TRANS_SERVER
TRANS(OpenFail),
#endif
#ifdef TRANS_REOPEN
TRANS(PTSReopenServer),
TRANS(ReopenFail),
#endif
#ifdef TRANS_SERVER
NULL,
TRANS(PTSAccept)
#endif
},
{"local",
#ifdef TRANS_CLIENT
TRANS(PTSOpenClient),
#endif
#ifdef TRANS_SERVER
TRANS(PTSOpenServer),
#endif
#ifdef TRANS_CLIENT
TRANS(OpenFail),
#endif
#ifdef TRANS_SERVER
TRANS(OpenFail),
#endif
#ifdef TRANS_REOPEN
TRANS(PTSReopenServer),
TRANS(ReopenFail),
#endif
#ifdef TRANS_SERVER
NULL,
TRANS(PTSAccept)
#endif
},
{"pts",
#ifdef TRANS_CLIENT
TRANS(PTSOpenClient),
#endif
#ifdef TRANS_SERVER
TRANS(PTSOpenServer),
#endif
#ifdef TRANS_CLIENT
TRANS(OpenFail),
#endif
#ifdef TRANS_SERVER
TRANS(OpenFail),
#endif
#ifdef TRANS_REOPEN
TRANS(PTSReopenServer),
TRANS(ReopenFail),
#endif
#ifdef TRANS_SERVER
NULL,
TRANS(PTSAccept)
#endif
},
#else
{"",
#ifdef TRANS_CLIENT
TRANS(NAMEDOpenClient),
#endif
#ifdef TRANS_SERVER
TRANS(NAMEDOpenServer),
#endif
#ifdef TRANS_CLIENT
TRANS(OpenFail),
#endif
#ifdef TRANS_SERVER
TRANS(OpenFail),
#endif
#ifdef TRANS_REOPEN
TRANS(NAMEDReopenServer),
TRANS(ReopenFail),
#endif
#ifdef TRANS_SERVER
TRANS(NAMEDResetListener),
TRANS(NAMEDAccept)
#endif
},
{"local",
#ifdef TRANS_CLIENT
TRANS(NAMEDOpenClient),
#endif
#ifdef TRANS_SERVER
TRANS(NAMEDOpenServer),
#endif
#ifdef TRANS_CLIENT
TRANS(OpenFail),
#endif
#ifdef TRANS_SERVER
TRANS(OpenFail),
#endif
#ifdef TRANS_REOPEN
TRANS(NAMEDReopenServer),
TRANS(ReopenFail),
#endif
#ifdef TRANS_SERVER
TRANS(NAMEDResetListener),
TRANS(NAMEDAccept)
#endif
},
#endif
#ifdef LOCAL_TRANS_NAMED
{"named",
#ifdef TRANS_CLIENT
TRANS(NAMEDOpenClient),
#endif
#ifdef TRANS_SERVER
TRANS(NAMEDOpenServer),
#endif
#ifdef TRANS_CLIENT
TRANS(OpenFail),
#endif
#ifdef TRANS_SERVER
TRANS(OpenFail),
#endif
#ifdef TRANS_REOPEN
TRANS(NAMEDReopenServer),
TRANS(ReopenFail),
#endif
#ifdef TRANS_SERVER
TRANS(NAMEDResetListener),
TRANS(NAMEDAccept)
#endif
},
#ifdef sun
{"pipe",
#ifdef TRANS_CLIENT
TRANS(NAMEDOpenClient),
#endif
#ifdef TRANS_SERVER
TRANS(NAMEDOpenServer),
#endif
#ifdef TRANS_CLIENT
TRANS(OpenFail),
#endif
#ifdef TRANS_SERVER
TRANS(OpenFail),
#endif
#ifdef TRANS_REOPEN
TRANS(NAMEDReopenServer),
TRANS(ReopenFail),
#endif
#ifdef TRANS_SERVER
TRANS(NAMEDResetListener),
TRANS(NAMEDAccept)
#endif
},
#endif
#endif
#ifdef LOCAL_TRANS_SCO
{"sco",
#ifdef TRANS_CLIENT
TRANS(SCOOpenClient),
#endif
#ifdef TRANS_SERVER
TRANS(SCOOpenServer),
#endif
#ifdef TRANS_CLIENT
TRANS(OpenFail),
#endif
#ifdef TRANS_SERVER
TRANS(OpenFail),
#endif
#ifdef TRANS_REOPEN
TRANS(SCOReopenServer),
TRANS(ReopenFail),
#endif
#ifdef TRANS_SERVER
NULL,
TRANS(SCOAccept)
#endif
},
#endif
};
#define NUMTRANSPORTS (sizeof(LOCALtrans2devtab)/sizeof(LOCALtrans2dev))
static char *XLOCAL=NULL;
static char *workingXLOCAL=NULL;
static char *freeXLOCAL=NULL;
#if defined(__SCO__)
#define DEF_XLOCAL "SCO:UNIX:PTS"
#elif defined(__UNIXWARE__)
#define DEF_XLOCAL "UNIX:PTS:NAMED:SCO"
#elif defined(sun)
#define DEF_XLOCAL "UNIX:NAMED"
#else
#define DEF_XLOCAL "UNIX:PTS:NAMED:ISC:SCO"
#endif
static void
TRANS(LocalInitTransports)(char *protocol)
{
PRMSG(3,"LocalInitTransports(%s)\n", protocol, 0,0 );
if( strcmp(protocol,"local") && strcmp(protocol,"LOCAL") )
{
workingXLOCAL=freeXLOCAL=(char *)xalloc (strlen (protocol) + 1);
if (workingXLOCAL)
strcpy (workingXLOCAL, protocol);
}
else {
XLOCAL=(char *)getenv("XLOCAL");
if(XLOCAL==NULL)
XLOCAL=DEF_XLOCAL;
workingXLOCAL=freeXLOCAL=(char *)xalloc (strlen (XLOCAL) + 1);
if (workingXLOCAL)
strcpy (workingXLOCAL, XLOCAL);
}
}
static void
TRANS(LocalEndTransports)(void)
{
PRMSG(3,"LocalEndTransports()\n", 0,0,0 );
xfree(freeXLOCAL);
}
#define TYPEBUFSIZE 32
#ifdef TRANS_CLIENT
static LOCALtrans2dev *
TRANS(LocalGetNextTransport)(void)
{
int i,j;
char *typetocheck;
char typebuf[TYPEBUFSIZE];
PRMSG(3,"LocalGetNextTransport()\n", 0,0,0 );
while(1)
{
if( workingXLOCAL == NULL || *workingXLOCAL == '\0' )
return NULL;
typetocheck=workingXLOCAL;
workingXLOCAL=strchr(workingXLOCAL,':');
if(workingXLOCAL && *workingXLOCAL)
*workingXLOCAL++='\0';
for(i=0;i<NUMTRANSPORTS;i++)
{
strncpy(typebuf,typetocheck,TYPEBUFSIZE);
for(j=0;j<TYPEBUFSIZE;j++)
if (isupper(typebuf[j]))
typebuf[j]=tolower(typebuf[j]);
if(!strcmp(LOCALtrans2devtab[i].transname,typebuf))
return &LOCALtrans2devtab[i];
}
}
#if 0
return NULL;
#endif
}
#ifdef NEED_UTSNAME
#include <sys/utsname.h>
#endif
static int
HostReallyLocal (char *host)
{
#ifdef NEED_UTSNAME
struct utsname name;
#endif
char buf[256];
#ifdef NEED_UTSNAME
if (uname (&name) >= 0 && strcmp (host, name.nodename) == 0)
return (1);
#endif
buf[0] = '\0';
(void) gethostname (buf, 256);
buf[255] = '\0';
if (strcmp (host, buf) == 0)
return (1);
return (0);
}
static XtransConnInfo
TRANS(LocalOpenClient)(int type, char *protocol, char *host, char *port)
{
LOCALtrans2dev *transptr;
XtransConnInfo ciptr;
int index;
PRMSG(3,"LocalOpenClient()\n", 0,0,0 );
if (strcmp (host, "unix") != 0 && !HostReallyLocal (host))
{
PRMSG (1,
"LocalOpenClient: Cannot connect to non-local host %s\n",
host, 0, 0);
return NULL;
}
#if defined(X11_t)
#endif
if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL )
{
PRMSG(1,"LocalOpenClient: calloc(1,%d) failed\n",
sizeof(struct _XtransConnInfo),0,0 );
return NULL;
}
ciptr->fd = -1;
TRANS(LocalInitTransports)(protocol);
index = 0;
for(transptr=TRANS(LocalGetNextTransport)();
transptr!=NULL;transptr=TRANS(LocalGetNextTransport)(), index++)
{
switch( type )
{
case XTRANS_OPEN_COTS_CLIENT:
ciptr->fd=transptr->devcotsopenclient(ciptr,port);
break;
case XTRANS_OPEN_CLTS_CLIENT:
ciptr->fd=transptr->devcltsopenclient(ciptr,port);
break;
case XTRANS_OPEN_COTS_SERVER:
case XTRANS_OPEN_CLTS_SERVER:
PRMSG(1,
"LocalOpenClient: Should not be opening a server with this function\n",
0,0,0);
break;
default:
PRMSG(1,
"LocalOpenClient: Unknown Open type %d\n",
type, 0,0 );
}
if( ciptr->fd >= 0 )
break;
}
TRANS(LocalEndTransports)();
if( ciptr->fd < 0 )
{
xfree(ciptr);
return NULL;
}
ciptr->priv=(char *)transptr;
ciptr->index = index;
return ciptr;
}
#endif
#ifdef TRANS_SERVER
static XtransConnInfo
TRANS(LocalOpenServer)(int type, char *protocol, char *host, char *port)
{
int i;
XtransConnInfo ciptr;
PRMSG(2,"LocalOpenServer(%d,%s,%s)\n", type, protocol, port);
#if defined(X11_t)
#endif
if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL )
{
PRMSG(1,"LocalOpenServer: calloc(1,%d) failed\n",
sizeof(struct _XtransConnInfo),0,0 );
return NULL;
}
for(i=1;i<NUMTRANSPORTS;i++)
{
if( strcmp(protocol,LOCALtrans2devtab[i].transname) != 0 )
continue;
switch( type )
{
case XTRANS_OPEN_COTS_CLIENT:
case XTRANS_OPEN_CLTS_CLIENT:
PRMSG(1,
"LocalOpenServer: Should not be opening a client with this function\n",
0,0,0);
break;
case XTRANS_OPEN_COTS_SERVER:
ciptr->fd=LOCALtrans2devtab[i].devcotsopenserver(ciptr,port);
break;
case XTRANS_OPEN_CLTS_SERVER:
ciptr->fd=LOCALtrans2devtab[i].devcltsopenserver(ciptr,port);
break;
default:
PRMSG(1,"LocalOpenServer: Unknown Open type %d\n",
type ,0,0);
}
if( ciptr->fd >= 0 ) {
ciptr->priv=(char *)&LOCALtrans2devtab[i];
ciptr->index=i;
ciptr->flags = 1 | (ciptr->flags & TRANS_KEEPFLAGS);
return ciptr;
}
}
xfree(ciptr);
return NULL;
}
#endif
#ifdef TRANS_REOPEN
static XtransConnInfo
TRANS(LocalReopenServer)(int type, int index, int fd, char *port)
{
XtransConnInfo ciptr;
int stat = 0;
PRMSG(2,"LocalReopenServer(%d,%d,%d)\n", type, index, fd);
if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL )
{
PRMSG(1,"LocalReopenServer: calloc(1,%d) failed\n",
sizeof(struct _XtransConnInfo),0,0 );
return NULL;
}
ciptr->fd = fd;
switch( type )
{
case XTRANS_OPEN_COTS_SERVER:
stat = LOCALtrans2devtab[index].devcotsreopenserver(ciptr,fd,port);
break;
case XTRANS_OPEN_CLTS_SERVER:
stat = LOCALtrans2devtab[index].devcltsreopenserver(ciptr,fd,port);
break;
default:
PRMSG(1,"LocalReopenServer: Unknown Open type %d\n",
type ,0,0);
}
if( stat > 0 ) {
ciptr->priv=(char *)&LOCALtrans2devtab[index];
ciptr->index=index;
ciptr->flags = 1 | (ciptr->flags & TRANS_KEEPFLAGS);
return ciptr;
}
xfree(ciptr);
return NULL;
}
#endif
#ifdef TRANS_CLIENT
static XtransConnInfo
TRANS(LocalOpenCOTSClient)(Xtransport *thistrans, char *protocol,
char *host, char *port)
{
PRMSG(2,"LocalOpenCOTSClient(%s,%s,%s)\n",protocol,host,port);
return TRANS(LocalOpenClient)(XTRANS_OPEN_COTS_CLIENT, protocol, host, port);
}
#endif
#ifdef TRANS_SERVER
static XtransConnInfo
TRANS(LocalOpenCOTSServer)(Xtransport *thistrans, char *protocol,
char *host, char *port)
{
char *typetocheck = NULL;
int found = 0;
char typebuf[TYPEBUFSIZE];
PRMSG(2,"LocalOpenCOTSServer(%s,%s,%s)\n",protocol,host,port);
TRANS(LocalInitTransports)("local");
typetocheck = workingXLOCAL;
while (typetocheck && !found) {
int j;
workingXLOCAL = strchr(workingXLOCAL, ':');
if (workingXLOCAL && *workingXLOCAL)
*workingXLOCAL++ = '\0';
strncpy(typebuf, typetocheck, TYPEBUFSIZE);
for (j = 0; j < TYPEBUFSIZE; j++)
if (isupper(typebuf[j]))
typebuf[j] = tolower(typebuf[j]);
if (!strcmp(thistrans->TransName, typebuf))
found = 1;
typetocheck = workingXLOCAL;
}
TRANS(LocalEndTransports)();
if (!found) {
PRMSG(3,"LocalOpenCOTSServer: disabling %s\n",thistrans->TransName,0,0);
thistrans->flags |= TRANS_DISABLED;
return NULL;
}
return TRANS(LocalOpenServer)(XTRANS_OPEN_COTS_SERVER, protocol, host, port);
}
#endif
#ifdef TRANS_CLIENT
static XtransConnInfo
TRANS(LocalOpenCLTSClient)(Xtransport *thistrans, char *protocol,
char *host, char *port)
{
PRMSG(2,"LocalOpenCLTSClient(%s,%s,%s)\n",protocol,host,port);
return TRANS(LocalOpenClient)(XTRANS_OPEN_CLTS_CLIENT, protocol, host, port);
}
#endif
#ifdef TRANS_SERVER
static XtransConnInfo
TRANS(LocalOpenCLTSServer)(Xtransport *thistrans, char *protocol,
char *host, char *port)
{
PRMSG(2,"LocalOpenCLTSServer(%s,%s,%s)\n",protocol,host,port);
return TRANS(LocalOpenServer)(XTRANS_OPEN_CLTS_SERVER, protocol, host, port);
}
#endif
#ifdef TRANS_REOPEN
static XtransConnInfo
TRANS(LocalReopenCOTSServer)(Xtransport *thistrans, int fd, char *port)
{
int index;
PRMSG(2,"LocalReopenCOTSServer(%d,%s)\n", fd, port, 0);
for(index=1;index<NUMTRANSPORTS;index++)
{
if( strcmp(thistrans->TransName,
LOCALtrans2devtab[index].transname) == 0 )
break;
}
if (index >= NUMTRANSPORTS)
{
return (NULL);
}
return TRANS(LocalReopenServer)(XTRANS_OPEN_COTS_SERVER,
index, fd, port);
}
static XtransConnInfo
TRANS(LocalReopenCLTSServer)(Xtransport *thistrans, int fd, char *port)
{
int index;
PRMSG(2,"LocalReopenCLTSServer(%d,%s)\n", fd, port, 0);
for(index=1;index<NUMTRANSPORTS;index++)
{
if( strcmp(thistrans->TransName,
LOCALtrans2devtab[index].transname) == 0 )
break;
}
if (index >= NUMTRANSPORTS)
{
return (NULL);
}
return TRANS(LocalReopenServer)(XTRANS_OPEN_CLTS_SERVER,
index, fd, port);
}
#endif
static int
TRANS(LocalSetOption)(XtransConnInfo ciptr, int option, int arg)
{
PRMSG(2,"LocalSetOption(%d,%d,%d)\n",ciptr->fd,option,arg);
return -1;
}
#ifdef TRANS_SERVER
static int
TRANS(LocalCreateListener)(XtransConnInfo ciptr, char *port, unsigned int flags)
{
PRMSG(2,"LocalCreateListener(%x->%d,%s)\n",ciptr,ciptr->fd,port);
return 0;
}
static int
TRANS(LocalResetListener)(XtransConnInfo ciptr)
{
LOCALtrans2dev *transptr;
PRMSG(2,"LocalResetListener(%x)\n",ciptr,0,0);
transptr=(LOCALtrans2dev *)ciptr->priv;
if (transptr->devreset != NULL) {
return transptr->devreset(ciptr);
}
return TRANS_RESET_NOOP;
}
static XtransConnInfo
TRANS(LocalAccept)(XtransConnInfo ciptr, int *status)
{
XtransConnInfo newciptr;
LOCALtrans2dev *transptr;
PRMSG(2,"LocalAccept(%x->%d)\n", ciptr, ciptr->fd,0);
transptr=(LOCALtrans2dev *)ciptr->priv;
if( (newciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo)))==NULL )
{
PRMSG(1,"LocalAccept: calloc(1,%d) failed\n",
sizeof(struct _XtransConnInfo),0,0 );
*status = TRANS_ACCEPT_BAD_MALLOC;
return NULL;
}
newciptr->fd=transptr->devaccept(ciptr,newciptr,status);
if( newciptr->fd < 0 )
{
xfree(newciptr);
return NULL;
}
newciptr->priv=(char *)transptr;
newciptr->index = ciptr->index;
*status = 0;
return newciptr;
}
#endif
#ifdef TRANS_CLIENT
static int
TRANS(LocalConnect)(XtransConnInfo ciptr, char *host, char *port)
{
PRMSG(2,"LocalConnect(%x->%d,%s)\n", ciptr, ciptr->fd, port);
return 0;
}
#endif
static int
TRANS(LocalBytesReadable)(XtransConnInfo ciptr, BytesReadable_t *pend )
{
PRMSG(2,"LocalBytesReadable(%x->%d,%x)\n", ciptr, ciptr->fd, pend);
#if defined(SCO325)
return ioctl(ciptr->fd, I_NREAD, (char *)pend);
#else
return ioctl(ciptr->fd, FIONREAD, (char *)pend);
#endif
}
static int
TRANS(LocalRead)(XtransConnInfo ciptr, char *buf, int size)
{
PRMSG(2,"LocalRead(%d,%x,%d)\n", ciptr->fd, buf, size );
return read(ciptr->fd,buf,size);
}
static int
TRANS(LocalWrite)(XtransConnInfo ciptr, char *buf, int size)
{
PRMSG(2,"LocalWrite(%d,%x,%d)\n", ciptr->fd, buf, size );
return write(ciptr->fd,buf,size);
}
static int
TRANS(LocalReadv)(XtransConnInfo ciptr, struct iovec *buf, int size)
{
PRMSG(2,"LocalReadv(%d,%x,%d)\n", ciptr->fd, buf, size );
return READV(ciptr,buf,size);
}
static int
TRANS(LocalWritev)(XtransConnInfo ciptr, struct iovec *buf, int size)
{
PRMSG(2,"LocalWritev(%d,%x,%d)\n", ciptr->fd, buf, size );
return WRITEV(ciptr,buf,size);
}
static int
TRANS(LocalDisconnect)(XtransConnInfo ciptr)
{
PRMSG(2,"LocalDisconnect(%x->%d)\n", ciptr, ciptr->fd, 0);
return 0;
}
static int
TRANS(LocalClose)(XtransConnInfo ciptr)
{
struct sockaddr_un *sockname=(struct sockaddr_un *) ciptr->addr;
int ret;
PRMSG(2,"LocalClose(%x->%d)\n", ciptr, ciptr->fd ,0);
ret=close(ciptr->fd);
if(ciptr->flags
&& sockname
&& sockname->sun_family == AF_UNIX
&& sockname->sun_path[0] )
{
if (!(ciptr->flags & TRANS_NOUNLINK))
unlink(sockname->sun_path);
}
return ret;
}
static int
TRANS(LocalCloseForCloning)(XtransConnInfo ciptr)
{
int ret;
PRMSG(2,"LocalCloseForCloning(%x->%d)\n", ciptr, ciptr->fd ,0);
ret=close(ciptr->fd);
return ret;
}
#ifdef TRANS_SERVER
static char * local_aliases[] = {
# ifdef LOCAL_TRANS_PTS
"pts",
# endif
"named",
# ifdef sun
"pipe",
# endif
# ifdef LOCAL_TRANS_SCO
"sco",
# endif
NULL };
#endif
Xtransport TRANS(LocalFuncs) = {
"local",
TRANS_ALIAS | TRANS_LOCAL,
#ifdef TRANS_CLIENT
TRANS(LocalOpenCOTSClient),
#endif
#ifdef TRANS_SERVER
local_aliases,
TRANS(LocalOpenCOTSServer),
#endif
#ifdef TRANS_CLIENT
TRANS(LocalOpenCLTSClient),
#endif
#ifdef TRANS_SERVER
TRANS(LocalOpenCLTSServer),
#endif
#ifdef TRANS_REOPEN
TRANS(LocalReopenCOTSServer),
TRANS(LocalReopenCLTSServer),
#endif
TRANS(LocalSetOption),
#ifdef TRANS_SERVER
TRANS(LocalCreateListener),
TRANS(LocalResetListener),
TRANS(LocalAccept),
#endif
#ifdef TRANS_CLIENT
TRANS(LocalConnect),
#endif
TRANS(LocalBytesReadable),
TRANS(LocalRead),
TRANS(LocalWrite),
TRANS(LocalReadv),
TRANS(LocalWritev),
TRANS(LocalDisconnect),
TRANS(LocalClose),
TRANS(LocalCloseForCloning),
};
#ifdef LOCAL_TRANS_PTS
Xtransport TRANS(PTSFuncs) = {
"pts",
TRANS_LOCAL,
#ifdef TRANS_CLIENT
TRANS(LocalOpenCOTSClient),
#endif
#ifdef TRANS_SERVER
NULL,
TRANS(LocalOpenCOTSServer),
#endif
#ifdef TRANS_CLIENT
TRANS(LocalOpenCLTSClient),
#endif
#ifdef TRANS_SERVER
TRANS(LocalOpenCLTSServer),
#endif
#ifdef TRANS_REOPEN
TRANS(LocalReopenCOTSServer),
TRANS(LocalReopenCLTSServer),
#endif
TRANS(LocalSetOption),
#ifdef TRANS_SERVER
TRANS(LocalCreateListener),
TRANS(LocalResetListener),
TRANS(LocalAccept),
#endif
#ifdef TRANS_CLIENT
TRANS(LocalConnect),
#endif
TRANS(LocalBytesReadable),
TRANS(LocalRead),
TRANS(LocalWrite),
TRANS(LocalReadv),
TRANS(LocalWritev),
TRANS(LocalDisconnect),
TRANS(LocalClose),
TRANS(LocalCloseForCloning),
};
#endif
#ifdef LOCAL_TRANS_NAMED
Xtransport TRANS(NAMEDFuncs) = {
"named",
TRANS_LOCAL,
#ifdef TRANS_CLIENT
TRANS(LocalOpenCOTSClient),
#endif
#ifdef TRANS_SERVER
NULL,
TRANS(LocalOpenCOTSServer),
#endif
#ifdef TRANS_CLIENT
TRANS(LocalOpenCLTSClient),
#endif
#ifdef TRANS_SERVER
TRANS(LocalOpenCLTSServer),
#endif
#ifdef TRANS_REOPEN
TRANS(LocalReopenCOTSServer),
TRANS(LocalReopenCLTSServer),
#endif
TRANS(LocalSetOption),
#ifdef TRANS_SERVER
TRANS(LocalCreateListener),
TRANS(LocalResetListener),
TRANS(LocalAccept),
#endif
#ifdef TRANS_CLIENT
TRANS(LocalConnect),
#endif
TRANS(LocalBytesReadable),
TRANS(LocalRead),
TRANS(LocalWrite),
TRANS(LocalReadv),
TRANS(LocalWritev),
TRANS(LocalDisconnect),
TRANS(LocalClose),
TRANS(LocalCloseForCloning),
};
#ifdef sun
Xtransport TRANS(PIPEFuncs) = {
"pipe",
TRANS_ALIAS | TRANS_LOCAL,
#ifdef TRANS_CLIENT
TRANS(LocalOpenCOTSClient),
#endif
#ifdef TRANS_SERVER
NULL,
TRANS(LocalOpenCOTSServer),
#endif
#ifdef TRANS_CLIENT
TRANS(LocalOpenCLTSClient),
#endif
#ifdef TRANS_SERVER
TRANS(LocalOpenCLTSServer),
#endif
#ifdef TRANS_REOPEN
TRANS(LocalReopenCOTSServer),
TRANS(LocalReopenCLTSServer),
#endif
TRANS(LocalSetOption),
#ifdef TRANS_SERVER
TRANS(LocalCreateListener),
TRANS(LocalResetListener),
TRANS(LocalAccept),
#endif
#ifdef TRANS_CLIENT
TRANS(LocalConnect),
#endif
TRANS(LocalBytesReadable),
TRANS(LocalRead),
TRANS(LocalWrite),
TRANS(LocalReadv),
TRANS(LocalWritev),
TRANS(LocalDisconnect),
TRANS(LocalClose),
TRANS(LocalCloseForCloning),
};
#endif
#endif
#ifdef LOCAL_TRANS_SCO
Xtransport TRANS(SCOFuncs) = {
"sco",
TRANS_LOCAL,
#ifdef TRANS_CLIENT
TRANS(LocalOpenCOTSClient),
#endif
#ifdef TRANS_SERVER
NULL,
TRANS(LocalOpenCOTSServer),
#endif
#ifdef TRANS_CLIENT
TRANS(LocalOpenCLTSClient),
#endif
#ifdef TRANS_SERVER
TRANS(LocalOpenCLTSServer),
#endif
#ifdef TRANS_REOPEN
TRANS(LocalReopenCOTSServer),
TRANS(LocalReopenCLTSServer),
#endif
TRANS(LocalSetOption),
#ifdef TRANS_SERVER
TRANS(LocalCreateListener),
TRANS(LocalResetListener),
TRANS(LocalAccept),
#endif
#ifdef TRANS_CLIENT
TRANS(LocalConnect),
#endif
TRANS(LocalBytesReadable),
TRANS(LocalRead),
TRANS(LocalWrite),
TRANS(LocalReadv),
TRANS(LocalWritev),
TRANS(LocalDisconnect),
TRANS(LocalClose),
TRANS(LocalCloseForCloning),
};
#endif