1 /* $XConsortium: Xtranslcl.c /main/27 1996/09/28 16:50:14 rws $ */
2 /* $XFree86: xc/lib/xtrans/Xtranslcl.c,v 3.21.2.3 1998/02/01 16:04:34 robin Exp $ */
5 Copyright (c) 1993, 1994 X Consortium
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
15 The above copyright notice and this permission notice shall be included
16 in all copies or substantial portions of the Software.
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 OTHER DEALINGS IN THE SOFTWARE.
26 Except as contained in this notice, the name of the X Consortium shall
27 not be used in advertising or otherwise to promote the sale, use or
28 other dealings in this Software without prior written authorization
29 from the X Consortium.
33 /* Copyright (c) 1993, 1994 NCR Corporation - Dayton, Ohio, USA
37 * Permission to use, copy, modify, and distribute this software and its
38 * documentation for any purpose and without fee is hereby granted, provided
39 * that the above copyright notice appear in all copies and that both that
40 * copyright notice and this permission notice appear in supporting
41 * documentation, and that the name NCR not be used in advertising
42 * or publicity pertaining to distribution of the software without specific,
43 * written prior permission. NCR makes no representations about the
44 * suitability of this software for any purpose. It is provided "as is"
45 * without express or implied warranty.
47 * NCR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
48 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
49 * NO EVENT SHALL NCR BE LIABLE FOR ANY SPECIAL, INDIRECT OR
50 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
51 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
52 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
53 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
58 * The connection code/ideas in lib/X and server/os for SVR4/Intel
59 * environments was contributed by the following companies/groups:
63 * Pittsburgh Powercomputing Corporation (PPc)/Quarterdeck Office Systems
65 * Unix System Laboratories (USL) / Novell
68 * The goal is to have common connection code among all SVR4/Intel vendors.
70 * ALL THE ABOVE COMPANIES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
71 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
72 * IN NO EVENT SHALL THESE COMPANIES * BE LIABLE FOR ANY SPECIAL, INDIRECT
73 * OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
74 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
75 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
76 * OR PERFORMANCE OF THIS SOFTWARE.
81 #include <sys/signal.h>
82 #include <sys/ioctl.h>
85 #include <sys/filio.h>
87 #include <sys/stropts.h>
91 * The local transports should be treated the same as a UNIX domain socket
92 * wrt authentication, etc. Because of this, we will use struct sockaddr_un
93 * for the address format. This will simplify the code in other places like
97 #include <sys/socket.h>
102 #if defined(ISC) && !defined(_POSIX_SOURCE)
103 typedef unsigned short mode_t;
104 /* POSIX needed for mode_t define in sys/types.h */
108 * These functions actually implement the local connection mechanisms.
111 /* Type Not Supported */
114 TRANS(OpenFail)(ciptr, port)
116 XtransConnInfo ciptr;
126 TRANS(ReopenFail)(ciptr, fd, port)
128 XtransConnInfo ciptr;
136 #endif /* TRANS_REOPEN */
141 TRANS(FillAddrInfo)(ciptr, sun_path, peer_sun_path)
143 XtransConnInfo ciptr;
148 struct sockaddr_un *sunaddr;
149 struct sockaddr_un *p_sunaddr;
151 ciptr->family = AF_UNIX;
152 ciptr->addrlen = sizeof (struct sockaddr_un);
154 if ((sunaddr = (struct sockaddr_un *) xalloc (ciptr->addrlen)) == NULL)
156 PRMSG(1,"FillAddrInfo: failed to allocate memory for addr\n",
161 sunaddr->sun_family = AF_UNIX;
163 strcpy (sunaddr->sun_path, sun_path);
164 #if defined(BSD44SOCKETS) && !defined(Lynx)
165 sunaddr->sun_len = strlen (sunaddr->sun_path);
168 ciptr->addr = (char *) sunaddr;
170 ciptr->peeraddrlen = sizeof (struct sockaddr_un);
172 if ((p_sunaddr = (struct sockaddr_un *) xalloc (
173 ciptr->peeraddrlen)) == NULL)
176 "FillAddrInfo: failed to allocate memory for peer addr\n",
178 xfree ((char *) sunaddr);
184 p_sunaddr->sun_family = AF_UNIX;
186 strcpy (p_sunaddr->sun_path, peer_sun_path);
187 #if defined(BSD44SOCKETS) && !defined(Lynx)
188 p_sunaddr->sun_len = strlen (p_sunaddr->sun_path);
191 ciptr->peeraddr = (char *) p_sunaddr;
200 #if defined(SYSV) && !defined(sco) && !defined(SCO) && !defined(ISC)
203 #define SIGNAL_T void
206 typedef SIGNAL_T (*PFV)();
210 extern char *ptsname(
211 #if NeedFunctionPrototypes
216 static void _dummy(sig)
223 #define X_STREAMS_DIR "/dev/X"
224 #define DEV_PTMX "/dev/ptmx"
225 #define DEV_SPX "/dev/spx"
229 #define PTSNODENAME "/dev/X/server."
230 #define NAMEDNODENAME "/dev/X/Nserver."
233 * ISC and SCO are only defined for X11 since they are there for
234 * backwards binary compatability only.
237 #define X_ISC_DIR "/dev/X/ISCCONN"
238 #define ISCDEVNODENAME "/dev/X/ISCCONN/X%s"
239 #define ISCTMPNODENAME "/tmp/.X11-unix/X%s"
240 #define SCORNODENAME "/dev/X%1sR"
241 #define SCOSNODENAME "/dev/X%1sS"
244 #define PTSNODENAME "/dev/X/XIM."
245 #define NAMEDNODENAME "/dev/X/NXIM."
247 #if defined(FS_t) || defined (FONT_t)
249 * USL has already defined something here. We need to check with them
250 * and see if their choice is usable here.
252 #define PTSNODENAME "/dev/X/fontserver."
253 #define NAMEDNODENAME "/dev/X/Nfontserver."
256 #define PTSNODENAME "/dev/X/ICE."
257 #define NAMEDNODENAME "/dev/X/NICE."
260 #define PTSNODENAME "/dev/X/transtest."
261 #define NAMEDNODENAME "/dev/X/Ntranstest."
269 TRANS(PTSOpenClient)(ciptr, port)
271 XtransConnInfo ciptr;
275 int fd,server,exitval,alarm_time,ret;
276 char server_path[64];
277 char *slave, namelen;
278 char buf[20]; /* MAX_PATH_LEN?? */
281 PRMSG(2,"PTSOpenClient(%s)\n", port, 0,0 );
283 #if !defined(PTSNODENAME)
284 PRMSG(1,"PTSOpenClient: Protocol is not supported by a pts connection\n", 0,0,0);
287 if (port && *port ) {
288 if( *port == '/' ) { /* A full pathname */
289 (void) sprintf(server_path, "%s", port);
291 (void) sprintf(server_path, "%s%s", PTSNODENAME, port);
294 (void) sprintf(server_path, "%s%d", PTSNODENAME, getpid());
299 * Open the node the on which the server is listening.
302 if ((server = open (server_path, O_RDWR)) < 0) {
303 PRMSG(1,"PTSOpenClient: failed to open %s\n", server_path, 0,0);
309 * Open the streams based pipe that will be this connection.
312 if ((fd = open("/dev/ptmx", O_RDWR)) < 0) {
313 PRMSG(1,"PTSOpenClient: failed to open /dev/ptmx\n", 0,0,0);
320 slave = ptsname(fd); /* get name */
322 if( slave == NULL ) {
323 PRMSG(1,"PTSOpenClient: failed to get ptsname()\n", 0,0,0);
330 * This is neccesary for the case where a program is setuid to non-root.
331 * grantpt() calls /usr/lib/pt_chmod which is set-uid root. This program will
332 * set the owner of the pt device incorrectly if the uid is not restored
333 * before it is called. The problem is that once it gets restored, it
334 * cannot be changed back to its original condition, hence the fork().
340 saved_euid = geteuid();
341 setuid( getuid() ); /** sets the euid to the actual/real uid **/
342 if( chown( slave, saved_euid, -1 ) < 0 ) {
351 if (chmod(slave, 0666) < 0) {
354 PRMSG(1,"PTSOpenClient: Cannot chmod %s\n", slave, 0,0);
359 * write slave name to server
362 namelen = strlen(slave);
364 (void) sprintf(&buf[1], slave);
365 (void) write(server, buf, namelen+1);
366 (void) close(server);
369 * wait for server to respond
372 savef = signal(SIGALRM, _dummy);
373 alarm_time = alarm (30); /* CONNECT_TIMEOUT */
375 ret = read(fd, buf, 1);
377 (void) alarm(alarm_time);
378 (void) signal(SIGALRM, savef);
382 "PTSOpenClient: failed to get acknoledgement from server\n",
389 * Everything looks good: fill in the XtransConnInfo structure.
392 if (TRANS(FillAddrInfo) (ciptr, slave, server_path) == 0)
394 PRMSG(1,"PTSOpenClient: failed to fill in addr info\n",
402 #endif /* !PTSNODENAME */
405 #endif /* TRANS_CLIENT */
411 TRANS(PTSOpenServer)(ciptr, port)
413 XtransConnInfo ciptr;
418 char server_path[64], *slave;
420 PRMSG(2,"PTSOpenServer(%s)\n", port, 0,0 );
422 #if !defined(PTSNODENAME)
423 PRMSG(1,"PTSOpenServer: Protocol is not supported by a pts connection\n", 0,0,0);
426 if (port && *port ) {
427 if( *port == '/' ) { /* A full pathname */
428 (void) sprintf(server_path, "%s", port);
430 (void) sprintf(server_path, "%s%s", PTSNODENAME, port);
433 (void) sprintf(server_path, "%s%d", PTSNODENAME, getpid());
436 mkdir(X_STREAMS_DIR, 0777);
437 chmod(X_STREAMS_DIR, 0777);
439 if( (fd=open(server_path, O_RDWR)) >= 0 ) {
442 * This doesn't prevent the server from starting up, and doesn't
443 * prevent clients from trying to connect to the in-use PTS (which
444 * is often in use by something other than another server).
446 PRMSG(1, "PTSOpenServer: A server is already running on port %s\n", port, 0,0 );
447 PRMSG(1, "PTSOpenServer: Remove %s if this is incorrect.\n", server_path, 0,0 );
451 /* Just remove the old path (which is what happens with UNIXCONN) */
458 if( (fd=open(DEV_PTMX, O_RDWR)) < 0) {
459 PRMSG(1, "PTSOpenServer: Unable to open %s\n", DEV_PTMX, 0,0 );
466 if( (slave=ptsname(fd)) == NULL) {
467 PRMSG(1, "PTSOpenServer: Unable to get slave device name\n", 0,0,0 );
472 if( link(slave,server_path) < 0 ) {
473 PRMSG(1, "PTSOpenServer: Unable to link %s to %s\n", slave, server_path,0 );
478 if( chmod(server_path, 0666) < 0 ) {
479 PRMSG(1, "PTSOpenServer: Unable to chmod %s to 0666\n", server_path,0,0 );
484 if( (server=open(server_path, O_RDWR)) < 0 ) {
485 PRMSG(1, "PTSOpenServer: Unable to open server device %s\n", server_path,0,0 );
493 * Everything looks good: fill in the XtransConnInfo structure.
496 if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
498 PRMSG(1,"PTSOpenServer: failed to fill in addr info\n",
506 #endif /* !PTSNODENAME */
510 TRANS(PTSAccept)(ciptr, newciptr, status)
512 XtransConnInfo ciptr;
513 XtransConnInfo newciptr;
519 unsigned char length;
521 struct sockaddr_un *sunaddr;
523 PRMSG(2,"PTSAccept(%x->%d)\n",ciptr,ciptr->fd,0);
525 if( (in=read(ciptr->fd,&length,1)) <= 0 ){
528 "PTSAccept: Incoming connection closed\n",0,0,0);
532 "PTSAccept: Error reading incoming connection. errno=%d \n",
535 *status = TRANS_ACCEPT_MISC_ERROR;
539 if( (in=read(ciptr->fd,buf,length)) <= 0 ){
542 "PTSAccept: Incoming connection closed\n",0,0,0);
546 "PTSAccept: Error reading device name for new connection. errno=%d \n",
549 *status = TRANS_ACCEPT_MISC_ERROR;
555 if( (newfd=open(buf,O_RDWR)) < 0 ) {
556 PRMSG(1, "PTSAccept: Failed to open %s\n",buf,0,0);
557 *status = TRANS_ACCEPT_MISC_ERROR;
564 * Everything looks good: fill in the XtransConnInfo structure.
567 newciptr->addrlen=ciptr->addrlen;
568 if( (newciptr->addr=(char *)xalloc(newciptr->addrlen)) == NULL ) {
569 PRMSG(1,"PTSAccept: failed to allocate memory for peer addr\n",
572 *status = TRANS_ACCEPT_BAD_MALLOC;
576 memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen);
578 newciptr->peeraddrlen=sizeof(struct sockaddr_un);
579 if( (sunaddr=(struct sockaddr_un *)xalloc(newciptr->peeraddrlen)) == NULL ) {
580 PRMSG(1,"PTSAccept: failed to allocate memory for peer addr\n",
582 xfree(newciptr->addr);
584 *status = TRANS_ACCEPT_BAD_MALLOC;
588 sunaddr->sun_family=AF_UNIX;
589 strcpy(sunaddr->sun_path,buf);
590 #if defined(BSD44SOCKETS) && !defined(Lynx)
591 sunaddr->sun_len=strlen(sunaddr->sun_path);
594 newciptr->peeraddr=(char *)sunaddr;
601 #endif /* TRANS_SERVER */
611 TRANS(NAMEDOpenClient)(ciptr, port)
613 XtransConnInfo ciptr;
618 char server_path[64];
619 struct stat filestat;
620 extern int isastream();
622 PRMSG(2,"NAMEDOpenClient(%s)\n", port, 0,0 );
624 #if !defined(NAMEDNODENAME)
625 PRMSG(1,"NAMEDOpenClient: Protocol is not supported by a NAMED connection\n", 0,0,0);
628 if ( port && *port ) {
629 if( *port == '/' ) { /* A full pathname */
630 (void) sprintf(server_path, "%s", port);
632 (void) sprintf(server_path, "%s%s", NAMEDNODENAME, port);
635 (void) sprintf(server_path, "%s%d", NAMEDNODENAME, getpid());
638 if (stat(server_path, &filestat) < 0 ) {
639 PRMSG(1,"NAMEDOpenClient: No device %s for NAMED connection\n", server_path, 0,0 );
643 if ((filestat.st_mode & S_IFMT) != S_IFIFO) {
644 PRMSG(1,"NAMEDOpenClient: Device %s is not a FIFO\n", server_path, 0,0 );
645 /* Is this really a failure? */
649 if ((fd = open(server_path, O_RDWR)) < 0) {
650 PRMSG(1,"NAMEDOpenClient: Cannot open %s for NAMED connection\n", server_path, 0,0 );
654 if (isastream(fd) <= 0) {
655 PRMSG(1,"NAMEDOpenClient: %s is not a streams device\n", server_path, 0,0 );
661 * Everything looks good: fill in the XtransConnInfo structure.
664 if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
666 PRMSG(1,"NAMEDOpenClient: failed to fill in addr info\n",
674 #endif /* !NAMEDNODENAME */
677 #endif /* TRANS_CLIENT */
683 TRANS(NAMEDOpenServer)(ciptr, port)
685 XtransConnInfo ciptr;
690 char server_path[64];
693 PRMSG(2,"NAMEDOpenServer(%s)\n", port, 0,0 );
695 #if !defined(NAMEDNODENAME)
696 PRMSG(1,"NAMEDOpenServer: Protocol is not supported by a NAMED connection\n", 0,0,0);
699 if ( port && *port ) {
700 if( *port == '/' ) { /* A full pathname */
701 (void) sprintf(server_path, "%s", port);
703 (void) sprintf(server_path, "%s%s", NAMEDNODENAME, port);
706 (void) sprintf(server_path, "%s%d", NAMEDNODENAME, getpid());
709 mkdir(X_STREAMS_DIR, 0777);
710 chmod(X_STREAMS_DIR, 0777);
712 if(stat(server_path, &sbuf) != 0) {
713 if (errno == ENOENT) {
714 if ((fd = creat(server_path, (mode_t)0666)) == -1) {
715 PRMSG(1, "NAMEDOpenServer: Can't open %s\n", server_path, 0,0 );
719 if (chmod(server_path, (mode_t)0666) < 0) {
720 PRMSG(1, "NAMEDOpenServer: Can't open %s\n", server_path, 0,0 );
724 PRMSG(1, "NAMEDOpenServer: stat on %s failed\n", server_path, 0,0 );
729 if( pipe(pipefd) != 0) {
730 PRMSG(1, "NAMEDOpenServer: pipe() failed, errno=%d\n",errno, 0,0 );
734 if( ioctl(pipefd[0], I_PUSH, "connld") != 0) {
735 PRMSG(1, "NAMEDOpenServer: ioctl(I_PUSH,\"connld\") failed, errno=%d\n",errno, 0,0 );
741 if( fattach(pipefd[0], server_path) != 0) {
742 PRMSG(1, "NAMEDOpenServer: fattach(%s) failed, errno=%d\n", server_path,errno, 0 );
749 * Everything looks good: fill in the XtransConnInfo structure.
752 if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
754 PRMSG(1,"NAMEDOpenServer: failed to fill in addr info\n",
762 #endif /* !NAMEDNODENAME */
766 TRANS(NAMEDAccept)(ciptr, newciptr, status)
768 XtransConnInfo ciptr;
769 XtransConnInfo newciptr;
773 struct strrecvfd str;
775 PRMSG(2,"NAMEDAccept(%x->%d)\n", ciptr, ciptr->fd, 0 );
777 if( ioctl(ciptr->fd, I_RECVFD, &str ) < 0 ) {
778 PRMSG(1, "NAMEDAccept: ioctl(I_RECVFD) failed, errno=%d\n", errno, 0,0 );
779 *status = TRANS_ACCEPT_MISC_ERROR;
784 * Everything looks good: fill in the XtransConnInfo structure.
787 newciptr->addrlen=ciptr->addrlen;
788 if( (newciptr->addr=(char *)xalloc(newciptr->addrlen)) == NULL ) {
790 "NAMEDAccept: failed to allocate memory for peer addr\n",
793 *status = TRANS_ACCEPT_BAD_MALLOC;
797 memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen);
799 newciptr->peeraddrlen=newciptr->addrlen;
800 if( (newciptr->peeraddr=(char *)xalloc(newciptr->peeraddrlen)) == NULL ) {
802 "NAMEDAccept: failed to allocate memory for peer addr\n",
804 xfree(newciptr->addr);
806 *status = TRANS_ACCEPT_BAD_MALLOC;
810 memcpy(newciptr->peeraddr,newciptr->addr,newciptr->peeraddrlen);
817 #endif /* TRANS_SERVER */
824 * connect_spipe is used by both the SCO and ISC connection types.
827 connect_spipe(fd1, fd2)
833 struct strfdinsert sbuf;
835 sbuf.databuf.maxlen = -1;
836 sbuf.databuf.len = -1;
837 sbuf.databuf.buf = NULL;
838 sbuf.ctlbuf.maxlen = sizeof(long);
839 sbuf.ctlbuf.len = sizeof(long);
840 sbuf.ctlbuf.buf = (caddr_t)&temp;
845 if( ioctl(fd1, I_FDINSERT, &sbuf) < 0 )
852 * connect_spipe is used by both the SCO and ISC connection types.
856 named_spipe(fd, path)
867 (void) fstat(fd, &sbuf);
868 ret = mknod(path, 0020666, sbuf.st_rdev);
887 TRANS(ISCOpenClient)(ciptr, port)
889 XtransConnInfo ciptr;
894 char server_path[64];
895 char server_dev_path[64];
896 struct strfdinsert buf;
899 struct stat filestat;
901 PRMSG(2,"ISCOpenClient(%s)\n", port, 0,0 );
903 #if !defined(ISCDEVNODENAME)
904 PRMSG(1,"ISCOpenClient: Protocol is not supported by a ISC connection\n", 0,0,0);
907 (void) sprintf(server_path, ISCTMPNODENAME, port);
908 (void) sprintf(server_dev_path, ISCDEVNODENAME, port);
910 fd = fds = server = -1;
912 if (stat(DEV_SPX, &filestat) == -1) {
913 PRMSG(1, "ISCOpenClient: stat(%s) failed, errno=%d\n", DEV_SPX, errno, 0 );
917 spmode = (filestat.st_mode & S_IFMT);
919 if (stat(server_path, &filestat) != -1) {
920 if ((filestat.st_mode & S_IFMT) == spmode) {
921 if ((server = open(server_path, O_RDWR)) < 0) {
922 PRMSG(1,"ISCOpenClient: failed to open %s\n",
929 /* try the alternate path */
930 if (stat(server_dev_path, &filestat) != -1) {
931 if ((filestat.st_mode & S_IFMT) == spmode) {
932 if ((server = open(server_dev_path, O_RDWR)) < 0) {
933 PRMSG(1,"ISCOpenClient: failed to open %s\n",
934 server_dev_path, 0,0 );
941 PRMSG(1,"ISCOpenClient: can't open either device %s or %s\n",
942 server_path, server_dev_path, 0 );
946 if ((fds = open(DEV_SPX, O_RDWR)) < 0 ||
947 (fd = open(DEV_SPX, O_RDWR)) < 0) {
948 /* Failed to open all of the devices */
949 PRMSG(1,"ISCOpenClient: can't open %s\n", DEV_SPX, 0,0 );
950 (void) close(server);
958 /* make a STREAMS-pipe */
960 buf.databuf.maxlen = -1;
961 buf.databuf.len = -1;
962 buf.databuf.buf = NULL;
963 buf.ctlbuf.maxlen = sizeof(long);
964 buf.ctlbuf.len = sizeof(long);
965 buf.ctlbuf.buf = (caddr_t)&temp;
970 if (ioctl(fds, I_FDINSERT, &buf) < 0 ||
971 ioctl(server, I_SENDFD, fds) < 0) {
972 PRMSG(1,"ISCOpenClient: ioctl(I_FDINSERT or I_SENDFD) failed\n",
974 (void) close(server);
981 * Everything looks good: fill in the XtransConnInfo structure.
984 if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
986 PRMSG(1,"ISCOpenClient: failed to fill in addr info\n",
994 #endif /* !ISCDEVNODENAME */
997 #endif /* TRANS_CLIENT */
1003 TRANS(ISCOpenServer)(ciptr, port)
1005 XtransConnInfo ciptr;
1009 int fd = -1,fds = -1;
1010 char server_path[64],server_unix_path[64];
1012 PRMSG(2,"ISCOpenServer(%s)\n", port, 0,0 );
1014 #if !defined(ISCDEVNODENAME)
1015 PRMSG(1,"ISCOpenServer: Protocol is not supported by a ISC connection\n", 0,0,0);
1018 (void) sprintf(server_path, ISCDEVNODENAME, port);
1019 (void) sprintf(server_unix_path, ISCTMPNODENAME, port);
1021 mkdir(X_STREAMS_DIR, 0777); /* "/dev/X" */
1022 chmod(X_STREAMS_DIR, 0777);
1023 mkdir(X_ISC_DIR, 0777); /* "/dev/X/ISCCONN" */
1024 chmod(X_ISC_DIR, 0777);
1026 unlink(server_path);
1028 if( ((fds=open(DEV_SPX, O_RDWR)) < 0) ||
1029 ((fd =open(DEV_SPX, O_RDWR)) < 0)) {
1030 PRMSG(1,"ISCOpenServer: failed to open %s\n", DEV_SPX, 0,0 );
1034 if( (connect_spipe(fds, fd) < 0) ||
1035 (named_spipe(fds, server_path) < 0)) {
1036 PRMSG(1,"ISCOpenServer: failed connect pipes\n", 0,0,0 );
1042 #if !defined(UNIXCONN)
1044 * If the UNIX Domain socket transport is not being used, then link this
1045 * device to the path /tmp/.X11-unix/X path.
1047 #define X_UNIX_DIR "/tmp/.X11-unix"
1049 if (!mkdir(X_UNIX_DIR, 01777))
1050 chmod(X_UNIX_DIR, 01777);
1052 unlink(server_unix_path);
1055 /* we prefer symbolic links because hard links can't cross file systems */
1056 if( symlink(server_path, server_unix_path) < 0 )
1057 PRMSG(1,"ISCOpenServer: failed to link %s to %s\n",
1058 server_path, server_unix_path, 0 );
1060 * Don't make this failure fatal since the listener
1061 * is already established, and this just for compatability
1065 /* catch SIGSYS on symlink for ISC40 compiled binaries running on ISC30 */
1066 signal(SIGSYS,_dummy);
1068 if( link(server_path, server_unix_path) < 0 )
1070 if( symlink(server_path, server_unix_path) < 0 )
1072 PRMSG(1,"ISCOpenServer: failed to link %s to %s\n",
1073 server_path, server_unix_path, 0 );
1075 * Don't make this failure fatal since the listener
1076 * is already established, and this just for compatability
1079 #endif /* !UNIXCONN */
1082 * Everything looks good: fill in the XtransConnInfo structure.
1085 if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
1087 PRMSG(1,"ISCOpenServer: failed to fill in addr info\n",
1095 #endif /* !ISCDEVNODENAME */
1099 TRANS(ISCAccept)(ciptr, newciptr, status)
1101 XtransConnInfo ciptr;
1102 XtransConnInfo newciptr;
1106 struct strrecvfd str;
1108 PRMSG(2,"ISCAccept(%d)\n", ciptr->fd, 0,0 );
1110 while (ioctl(ciptr->fd, I_RECVFD, &str) < 0) {
1111 if (errno != EAGAIN) {
1112 PRMSG(1,"ISCAccept: Can't read fildes", 0,0,0 );
1113 *status = TRANS_ACCEPT_MISC_ERROR;
1119 * Everything looks good: fill in the XtransConnInfo structure.
1122 newciptr->addrlen=ciptr->addrlen;
1123 if( (newciptr->addr=(char *)xalloc(newciptr->addrlen)) == NULL ) {
1125 "ISCAccept: failed to allocate memory for peer addr\n",
1128 *status = TRANS_ACCEPT_BAD_MALLOC;
1132 memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen);
1134 newciptr->peeraddrlen=newciptr->addrlen;
1135 if( (newciptr->peeraddr=(char *)xalloc(newciptr->peeraddrlen)) == NULL ) {
1137 "ISCAccept: failed to allocate memory for peer addr\n",
1139 xfree(newciptr->addr);
1141 *status = TRANS_ACCEPT_BAD_MALLOC;
1145 memcpy(newciptr->peeraddr,newciptr->addr,newciptr->peeraddrlen);
1152 #endif /* TRANS_SERVER */
1162 TRANS(SCOOpenClient)(ciptr, port)
1164 XtransConnInfo ciptr;
1168 int fd, server, fl, ret;
1169 char server_path[64];
1170 struct strbuf ctlbuf;
1171 unsigned long alarm_time;
1174 extern int getmsg(), putmsg();
1176 PRMSG(2,"SCOOpenClient(%s)\n", port, 0,0 );
1178 #if !defined(SCORNODENAME)
1179 PRMSG(1,"SCOOpenClient: Protocol is not supported by a SCO connection\n", 0,0,0);
1182 (void) sprintf(server_path, SCORNODENAME, port);
1184 if ((server = open(server_path, O_RDWR)) < 0) {
1185 PRMSG(1,"SCOOpenClient: failed to open %s\n", server_path, 0,0 );
1189 if ((fd = open(DEV_SPX, O_RDWR)) < 0) {
1190 PRMSG(1,"SCOOpenClient: failed to open %s\n", DEV_SPX, 0,0 );
1195 (void) write(server, &server, 1);
1197 ctlbuf.maxlen = sizeof(long);
1198 ctlbuf.buf = (caddr_t)&temp;
1201 savef = signal(SIGALRM, _dummy);
1202 alarm_time = alarm(10);
1204 ret = getmsg(server, &ctlbuf, 0, &fl);
1206 (void) alarm(alarm_time);
1207 (void) signal(SIGALRM, savef);
1210 PRMSG(1,"SCOOpenClient: error from getmsg\n", 0,0,0 );
1216 /* The msg we got via getmsg is the result of an
1217 * I_FDINSERT, so if we do a putmsg with whatever
1218 * we recieved, we're doing another I_FDINSERT ...
1220 (void) putmsg(fd, &ctlbuf, 0, 0);
1221 (void) fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,0)|O_NDELAY);
1223 (void) close(server);
1226 * Everything looks good: fill in the XtransConnInfo structure.
1229 if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
1231 PRMSG(1,"SCOOpenClient: failed to fill addr info\n",
1239 #endif /* !SCORNODENAME */
1242 #endif /* TRANS_CLIENT */
1248 TRANS(SCOOpenServer)(ciptr, port)
1250 XtransConnInfo ciptr;
1254 char serverR_path[64];
1255 char serverS_path[64];
1259 PRMSG(2,"SCOOpenServer(%s)\n", port, 0,0 );
1261 #if !defined(SCORNODENAME)
1262 PRMSG(1,"SCOOpenServer: Protocol is not supported by a SCO connection\n", 0,0,0);
1265 (void) sprintf(serverR_path, SCORNODENAME, port);
1266 (void) sprintf(serverS_path, SCOSNODENAME, port);
1268 unlink(serverR_path);
1269 unlink(serverS_path);
1271 if ((fds = open(DEV_SPX, O_RDWR)) < 0 ||
1272 (fdr = open(DEV_SPX, O_RDWR)) < 0 ) {
1273 PRMSG(2,"SCOOpenServer: failed to open %s\n", DEV_SPX, 0,0 );
1277 if (connect_spipe(fds, fdr) != -1 &&
1278 named_spipe(fds, serverS_path) != -1 &&
1279 named_spipe(fdr, serverR_path) != -1) {
1280 PRMSG(2,"SCOOpenServer: connect pipes\n", 0,0,0 );
1282 PRMSG(2,"SCOOpenServer: failed to connect pipes\n", 0,0,0 );
1289 * Everything looks good: fill in the XtransConnInfo structure.
1292 if (TRANS(FillAddrInfo) (ciptr, serverS_path, serverR_path) == 0)
1294 PRMSG(1,"SCOOpenServer: failed to fill in addr info\n",
1303 #endif /* !SCORNODENAME */
1307 TRANS(SCOAccept)(ciptr, newciptr, status)
1309 XtransConnInfo ciptr;
1310 XtransConnInfo newciptr;
1317 PRMSG(2,"SCOAccept(%d)\n", ciptr->fd, 0,0 );
1319 if (read(ciptr->fd, &c, 1) < 0) {
1320 PRMSG(1,"SCOAccept: can't read from client",0,0,0);
1321 *status = TRANS_ACCEPT_MISC_ERROR;
1325 if( (fd = open(DEV_SPX, O_RDWR)) < 0 ) {
1326 PRMSG(1,"SCOAccept: can't open \"%s\"",DEV_SPX, 0,0 );
1327 *status = TRANS_ACCEPT_MISC_ERROR;
1331 if (connect_spipe(ciptr->fd, fd) < 0) {
1332 PRMSG(1,"SCOAccept: can't connect pipes", 0,0,0 );
1334 *status = TRANS_ACCEPT_MISC_ERROR;
1339 * Everything looks good: fill in the XtransConnInfo structure.
1342 newciptr->addrlen=ciptr->addrlen;
1343 if( (newciptr->addr=(char *)xalloc(newciptr->addrlen)) == NULL ) {
1345 "SCOAccept: failed to allocate memory for peer addr\n",
1348 *status = TRANS_ACCEPT_BAD_MALLOC;
1352 memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen);
1354 newciptr->peeraddrlen=newciptr->addrlen;
1355 if( (newciptr->peeraddr=(char *)xalloc(newciptr->peeraddrlen)) == NULL ) {
1357 "SCOAccept: failed to allocate memory for peer addr\n",
1359 xfree(newciptr->addr);
1361 *status = TRANS_ACCEPT_BAD_MALLOC;
1365 memcpy(newciptr->peeraddr,newciptr->addr,newciptr->peeraddrlen);
1372 #endif /* TRANS_SERVER */
1379 TRANS(PTSReopenServer)(ciptr, fd, port)
1381 XtransConnInfo ciptr;
1385 char server_path[64];
1387 PRMSG(2,"PTSReopenServer(%d,%s)\n", fd, port, 0 );
1389 #if !defined(PTSNODENAME)
1390 PRMSG(1,"PTSReopenServer: Protocol is not supported by a pts connection\n", 0,0,0);
1393 if (port && *port ) {
1394 if( *port == '/' ) { /* A full pathname */
1395 (void) sprintf(server_path, "%s", port);
1397 (void) sprintf(server_path, "%s%s", PTSNODENAME, port);
1400 (void) sprintf(server_path, "%s%d", PTSNODENAME, getpid());
1403 if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
1405 PRMSG(1,"PTSReopenServer: failed to fill in addr info\n",
1412 #endif /* !PTSNODENAME */
1417 TRANS(NAMEDReopenServer)(ciptr, fd, port)
1419 XtransConnInfo ciptr;
1424 char server_path[64];
1426 PRMSG(2,"NAMEDReopenServer(%s)\n", port, 0,0 );
1428 #if !defined(NAMEDNODENAME)
1429 PRMSG(1,"NAMEDReopenServer: Protocol is not supported by a NAMED connection\n", 0,0,0);
1432 if ( port && *port ) {
1433 if( *port == '/' ) { /* A full pathname */
1434 (void) sprintf(server_path, "%s", port);
1436 (void) sprintf(server_path, "%s%s", NAMEDNODENAME, port);
1439 (void) sprintf(server_path, "%s%d", NAMEDNODENAME, getpid());
1442 if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
1444 PRMSG(1,"NAMEDReopenServer: failed to fill in addr info\n",
1451 #endif /* !NAMEDNODENAME */
1456 TRANS(ISCReopenServer)(ciptr, fd, port)
1458 XtransConnInfo ciptr;
1463 char server_path[64],server_unix_path[64];
1465 PRMSG(2,"ISCReopenServer(%s)\n", port, 0,0 );
1467 #if !defined(ISCDEVNODENAME)
1468 PRMSG(1,"ISCReopenServer: Protocol is not supported by a ISC connection\n", 0,0,0);
1471 (void) sprintf(server_path, ISCDEVNODENAME, port);
1472 (void) sprintf(server_unix_path, ISCTMPNODENAME, port);
1474 if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
1476 PRMSG(1,"ISCReopenServer: failed to fill in addr info\n",
1483 #endif /* !ISCDEVNODENAME */
1488 TRANS(SCOReopenServer)(ciptr, fd, port)
1490 XtransConnInfo ciptr;
1495 char serverR_path[64];
1496 char serverS_path[64];
1498 PRMSG(2,"SCOReopenServer(%s)\n", port, 0,0 );
1500 #if !defined(SCORNODENAME)
1501 PRMSG(1,"SCOReopenServer: Protocol is not supported by a SCO connection\n", 0,0,0);
1504 (void) sprintf(serverR_path, SCORNODENAME, port);
1505 (void) sprintf(serverS_path, SCOSNODENAME, port);
1507 if (TRANS(FillAddrInfo) (ciptr, serverS_path, serverR_path) == 0)
1509 PRMSG(1,"SCOReopenServer: failed to fill in addr info\n",
1516 #endif /* SCORNODENAME */
1519 #endif /* TRANS_REOPEN */
1524 * This table contains all of the entry points for the different local
1525 * connection mechanisms.
1528 typedef struct _LOCALtrans2dev {
1533 int (*devcotsopenclient)(
1534 #if NeedFunctionPrototypes
1535 XtransConnInfo, char * /*port*/
1539 #endif /* TRANS_CLIENT */
1543 int (*devcotsopenserver)(
1544 #if NeedFunctionPrototypes
1545 XtransConnInfo, char * /*port*/
1549 #endif /* TRANS_SERVER */
1553 int (*devcltsopenclient)(
1554 #if NeedFunctionPrototypes
1555 XtransConnInfo, char * /*port*/
1559 #endif /* TRANS_CLIENT */
1563 int (*devcltsopenserver)(
1564 #if NeedFunctionPrototypes
1565 XtransConnInfo, char * /*port*/
1569 #endif /* TRANS_SERVER */
1573 int (*devcotsreopenserver)(
1574 #if NeedFunctionPrototypes
1581 int (*devcltsreopenserver)(
1582 #if NeedFunctionPrototypes
1589 #endif /* TRANS_REOPEN */
1594 #if NeedFunctionPrototypes
1595 XtransConnInfo, XtransConnInfo, int *
1600 #endif /* TRANS_SERVER */
1604 static LOCALtrans2dev LOCALtrans2devtab[] = {
1607 TRANS(PTSOpenClient),
1608 #endif /* TRANS_CLIENT */
1610 TRANS(PTSOpenServer),
1611 #endif /* TRANS_SERVER */
1614 #endif /* TRANS_CLIENT */
1617 #endif /* TRANS_SERVER */
1619 TRANS(PTSReopenServer),
1624 #endif /* TRANS_SERVER */
1629 TRANS(PTSOpenClient),
1630 #endif /* TRANS_CLIENT */
1632 TRANS(PTSOpenServer),
1633 #endif /* TRANS_SERVER */
1636 #endif /* TRANS_CLIENT */
1639 #endif /* TRANS_SERVER */
1641 TRANS(PTSReopenServer),
1646 #endif /* TRANS_SERVER */
1651 TRANS(PTSOpenClient),
1652 #endif /* TRANS_CLIENT */
1654 TRANS(PTSOpenServer),
1655 #endif /* TRANS_SERVER */
1658 #endif /* TRANS_CLIENT */
1661 #endif /* TRANS_SERVER */
1663 TRANS(PTSReopenServer),
1668 #endif /* TRANS_SERVER */
1674 TRANS(NAMEDOpenClient),
1675 #endif /* TRANS_CLIENT */
1677 TRANS(NAMEDOpenServer),
1678 #endif /* TRANS_SERVER */
1681 #endif /* TRANS_CLIENT */
1684 #endif /* TRANS_SERVER */
1686 TRANS(NAMEDReopenServer),
1691 #endif /* TRANS_SERVER */
1697 TRANS(ISCOpenClient),
1698 #endif /* TRANS_CLIENT */
1700 TRANS(ISCOpenServer),
1701 #endif /* TRANS_SERVER */
1704 #endif /* TRANS_CLIENT */
1707 #endif /* TRANS_SERVER */
1709 TRANS(ISCReopenServer),
1714 #endif /* TRANS_SERVER */
1719 TRANS(SCOOpenClient),
1720 #endif /* TRANS_CLIENT */
1722 TRANS(SCOOpenServer),
1723 #endif /* TRANS_SERVER */
1726 #endif /* TRANS_CLIENT */
1729 #endif /* TRANS_SERVER */
1731 TRANS(SCOReopenServer),
1736 #endif /* TRANS_SERVER */
1740 #define NUMTRANSPORTS (sizeof(LOCALtrans2devtab)/sizeof(LOCALtrans2dev))
1742 static char *XLOCAL=NULL;
1743 static char *workingXLOCAL=NULL;
1744 static char *freeXLOCAL=NULL;
1747 TRANS(LocalInitTransports)(protocol)
1752 PRMSG(3,"LocalInitTransports(%s)\n", protocol, 0,0 );
1754 if( strcmp(protocol,"local") && strcmp(protocol,"LOCAL") )
1756 workingXLOCAL=freeXLOCAL=(char *)xalloc (strlen (protocol) + 1);
1758 strcpy (workingXLOCAL, protocol);
1761 XLOCAL=(char *)getenv("XLOCAL");
1763 XLOCAL="UNIX:PTS:NAMED:ISC:SCO";
1764 workingXLOCAL=freeXLOCAL=(char *)xalloc (strlen (XLOCAL) + 1);
1766 strcpy (workingXLOCAL, XLOCAL);
1771 TRANS(LocalEndTransports)()
1774 PRMSG(3,"LocalEndTransports()\n", 0,0,0 );
1778 static LOCALtrans2dev *
1779 TRANS(LocalGetNextTransport)()
1784 #define TYPEBUFSIZE 32
1785 char typebuf[TYPEBUFSIZE];
1786 PRMSG(3,"LocalGetNextTransport()\n", 0,0,0 );
1790 if( workingXLOCAL == NULL || *workingXLOCAL == '\0' )
1793 typetocheck=workingXLOCAL;
1794 workingXLOCAL=strchr(workingXLOCAL,':');
1795 if(workingXLOCAL && *workingXLOCAL)
1796 *workingXLOCAL++='\0';
1798 for(i=0;i<NUMTRANSPORTS;i++)
1801 * This is equivilent to a case insensitive strcmp(),
1802 * but should be more portable.
1804 strncpy(typebuf,typetocheck,TYPEBUFSIZE);
1805 for(j=0;j<TYPEBUFSIZE;j++)
1806 if (isupper(typebuf[j]))
1807 typebuf[j]=tolower(typebuf[j]);
1809 /* Now, see if they match */
1810 if(!strcmp(LOCALtrans2devtab[i].transname,typebuf))
1811 return &LOCALtrans2devtab[i];
1821 #include <sys/utsname.h>
1825 * Make sure 'host' is really local.
1829 HostReallyLocal (host)
1835 * The 'host' passed to this function may have been generated
1836 * by either uname() or gethostname(). We try both if possible.
1840 struct utsname name;
1845 if (uname (&name) >= 0 && strcmp (host, name.nodename) == 0)
1850 (void) gethostname (buf, 256);
1853 if (strcmp (host, buf) == 0)
1860 static XtransConnInfo
1861 TRANS(LocalOpenClient)(type, protocol, host, port)
1870 LOCALtrans2dev *transptr;
1871 XtransConnInfo ciptr;
1874 PRMSG(3,"LocalOpenClient()\n", 0,0,0 );
1877 * Make sure 'host' is really local. If not, we return failure.
1878 * The reason we make this check is because a process may advertise
1879 * a "local" address for which it can accept connections, but if a
1880 * process on a remote machine tries to connect to this address,
1881 * we know for sure it will fail.
1884 if (strcmp (host, "unix") != 0 && !HostReallyLocal (host))
1887 "LocalOpenClient: Cannot connect to non-local host %s\n",
1895 * X has a well known port, that is transport dependant. It is easier
1896 * to handle it here, than try and come up with a transport independent
1897 * representation that can be passed in and resolved the usual way.
1899 * The port that is passed here is really a string containing the idisplay
1900 * from ConnectDisplay(). Since that is what we want for the local transports,
1901 * we don't have to do anything special.
1905 if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL )
1907 PRMSG(1,"LocalOpenClient: calloc(1,%d) failed\n",
1908 sizeof(struct _XtransConnInfo),0,0 );
1914 TRANS(LocalInitTransports)(protocol);
1917 for(transptr=TRANS(LocalGetNextTransport)();
1918 transptr!=NULL;transptr=TRANS(LocalGetNextTransport)(), index++)
1922 case XTRANS_OPEN_COTS_CLIENT:
1923 ciptr->fd=transptr->devcotsopenclient(ciptr,port);
1925 case XTRANS_OPEN_CLTS_CLIENT:
1926 ciptr->fd=transptr->devcltsopenclient(ciptr,port);
1928 case XTRANS_OPEN_COTS_SERVER:
1929 case XTRANS_OPEN_CLTS_SERVER:
1931 "LocalOpenClient: Should not be opening a server with this function\n",
1936 "LocalOpenClient: Unknown Open type %d\n",
1939 if( ciptr->fd >= 0 )
1943 TRANS(LocalEndTransports)();
1951 ciptr->priv=(char *)transptr;
1952 ciptr->index = index;
1957 #endif /* TRANS_CLIENT */
1962 static XtransConnInfo
1963 TRANS(LocalOpenServer)(type, protocol, host, port)
1972 XtransConnInfo ciptr;
1974 PRMSG(2,"LocalOpenServer(%d,%s,%s)\n", type, protocol, port);
1978 * For X11, the port will be in the format xserverN where N is the
1979 * display number. All of the local connections just need to know
1980 * the display number because they don't do any name resolution on
1981 * the port. This just truncates port to the display portion.
1985 if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL )
1987 PRMSG(1,"LocalOpenServer: calloc(1,%d) failed\n",
1988 sizeof(struct _XtransConnInfo),0,0 );
1992 for(i=1;i<NUMTRANSPORTS;i++)
1994 if( strcmp(protocol,LOCALtrans2devtab[i].transname) != 0 )
1998 case XTRANS_OPEN_COTS_CLIENT:
1999 case XTRANS_OPEN_CLTS_CLIENT:
2001 "LocalOpenServer: Should not be opening a client with this function\n",
2004 case XTRANS_OPEN_COTS_SERVER:
2005 ciptr->fd=LOCALtrans2devtab[i].devcotsopenserver(ciptr,port);
2007 case XTRANS_OPEN_CLTS_SERVER:
2008 ciptr->fd=LOCALtrans2devtab[i].devcltsopenserver(ciptr,port);
2011 PRMSG(1,"LocalOpenServer: Unknown Open type %d\n",
2014 if( ciptr->fd >= 0 ) {
2015 ciptr->priv=(char *)&LOCALtrans2devtab[i];
2026 #endif /* TRANS_SERVER */
2031 static XtransConnInfo
2032 TRANS(LocalReopenServer)(type, index, fd, port)
2040 XtransConnInfo ciptr;
2043 PRMSG(2,"LocalReopenServer(%d,%d,%d)\n", type, index, fd);
2045 if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL )
2047 PRMSG(1,"LocalReopenServer: calloc(1,%d) failed\n",
2048 sizeof(struct _XtransConnInfo),0,0 );
2056 case XTRANS_OPEN_COTS_SERVER:
2057 stat = LOCALtrans2devtab[index].devcotsreopenserver(ciptr,fd,port);
2059 case XTRANS_OPEN_CLTS_SERVER:
2060 stat = LOCALtrans2devtab[index].devcltsreopenserver(ciptr,fd,port);
2063 PRMSG(1,"LocalReopenServer: Unknown Open type %d\n",
2068 ciptr->priv=(char *)&LOCALtrans2devtab[index];
2078 #endif /* TRANS_REOPEN */
2083 * This is the Local implementation of the X Transport service layer
2088 static XtransConnInfo
2089 TRANS(LocalOpenCOTSClient)(thistrans, protocol, host, port)
2091 Xtransport *thistrans;
2097 PRMSG(2,"LocalOpenCOTSClient(%s,%s,%s)\n",protocol,host,port);
2099 return TRANS(LocalOpenClient)(XTRANS_OPEN_COTS_CLIENT, protocol, host, port);
2102 #endif /* TRANS_CLIENT */
2107 static XtransConnInfo
2108 TRANS(LocalOpenCOTSServer)(thistrans, protocol, host, port)
2110 Xtransport *thistrans;
2116 char *typetocheck = NULL;
2118 char typebuf[TYPEBUFSIZE];
2120 PRMSG(2,"LocalOpenCOTSServer(%s,%s,%s)\n",protocol,host,port);
2122 /* Check if this local type is in the XLOCAL list */
2123 TRANS(LocalInitTransports)("local");
2124 typetocheck = workingXLOCAL;
2125 while (typetocheck && !found) {
2128 workingXLOCAL = strchr(workingXLOCAL, ':');
2129 if (workingXLOCAL && *workingXLOCAL)
2130 *workingXLOCAL++ = '\0';
2131 strncpy(typebuf, typetocheck, TYPEBUFSIZE);
2132 for (j = 0; j < TYPEBUFSIZE; j++)
2133 if (isupper(typebuf[j]))
2134 typebuf[j] = tolower(typebuf[j]);
2135 if (!strcmp(thistrans->TransName, typebuf))
2137 typetocheck = workingXLOCAL;
2139 TRANS(LocalEndTransports)();
2142 PRMSG(3,"LocalOpenCOTSServer: disabling %s\n",thistrans->TransName,0,0);
2143 thistrans->flags |= TRANS_DISABLED;
2147 return TRANS(LocalOpenServer)(XTRANS_OPEN_COTS_SERVER, protocol, host, port);
2150 #endif /* TRANS_SERVER */
2155 static XtransConnInfo
2156 TRANS(LocalOpenCLTSClient)(thistrans, protocol, host, port)
2158 Xtransport *thistrans;
2164 PRMSG(2,"LocalOpenCLTSClient(%s,%s,%s)\n",protocol,host,port);
2166 return TRANS(LocalOpenClient)(XTRANS_OPEN_CLTS_CLIENT, protocol, host, port);
2169 #endif /* TRANS_CLIENT */
2174 static XtransConnInfo
2175 TRANS(LocalOpenCLTSServer)(thistrans, protocol, host, port)
2177 Xtransport *thistrans;
2183 PRMSG(2,"LocalOpenCLTSServer(%s,%s,%s)\n",protocol,host,port);
2185 return TRANS(LocalOpenServer)(XTRANS_OPEN_CLTS_SERVER, protocol, host, port);
2188 #endif /* TRANS_SERVER */
2193 static XtransConnInfo
2194 TRANS(LocalReopenCOTSServer)(thistrans, fd, port)
2196 Xtransport *thistrans;
2203 PRMSG(2,"LocalReopenCOTSServer(%d,%s)\n", fd, port, 0);
2205 for(index=1;index<NUMTRANSPORTS;index++)
2207 if( strcmp(thistrans->TransName,
2208 LOCALtrans2devtab[index].transname) == 0 )
2212 if (index >= NUMTRANSPORTS)
2217 return TRANS(LocalReopenServer)(XTRANS_OPEN_COTS_SERVER,
2221 static XtransConnInfo
2222 TRANS(LocalReopenCLTSServer)(thistrans, fd, port)
2224 Xtransport *thistrans;
2231 PRMSG(2,"LocalReopenCLTSServer(%d,%s)\n", fd, port, 0);
2233 for(index=1;index<NUMTRANSPORTS;index++)
2235 if( strcmp(thistrans->TransName,
2236 LOCALtrans2devtab[index].transname) == 0 )
2240 if (index >= NUMTRANSPORTS)
2245 return TRANS(LocalReopenServer)(XTRANS_OPEN_CLTS_SERVER,
2249 #endif /* TRANS_REOPEN */
2254 TRANS(LocalSetOption)(ciptr, option, arg)
2256 XtransConnInfo ciptr;
2261 PRMSG(2,"LocalSetOption(%d,%d,%d)\n",ciptr->fd,option,arg);
2270 TRANS(LocalCreateListener)(ciptr, port)
2272 XtransConnInfo ciptr;
2276 PRMSG(2,"LocalCreateListener(%x->%d,%s)\n",ciptr,ciptr->fd,port);
2281 static XtransConnInfo
2282 TRANS(LocalAccept)(ciptr, status)
2284 XtransConnInfo ciptr;
2288 XtransConnInfo newciptr;
2289 LOCALtrans2dev *transptr;
2291 PRMSG(2,"LocalAccept(%x->%d)\n", ciptr, ciptr->fd,0);
2293 transptr=(LOCALtrans2dev *)ciptr->priv;
2295 if( (newciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo)))==NULL )
2297 PRMSG(1,"LocalAccept: calloc(1,%d) failed\n",
2298 sizeof(struct _XtransConnInfo),0,0 );
2299 *status = TRANS_ACCEPT_BAD_MALLOC;
2303 newciptr->fd=transptr->devaccept(ciptr,newciptr,status);
2305 if( newciptr->fd < 0 )
2311 newciptr->priv=(char *)transptr;
2312 newciptr->index = ciptr->index;
2319 #endif /* TRANS_SERVER */
2325 TRANS(LocalConnect)(ciptr, host, port)
2327 XtransConnInfo ciptr;
2332 PRMSG(2,"LocalConnect(%x->%d,%s)\n", ciptr, ciptr->fd, port);
2337 #endif /* TRANS_CLIENT */
2341 TRANS(LocalBytesReadable)(ciptr, pend )
2343 XtransConnInfo ciptr;
2344 BytesReadable_t *pend;
2347 PRMSG(2,"LocalBytesReadable(%x->%d,%x)\n", ciptr, ciptr->fd, pend);
2349 #if defined(ISC) || defined(SCO)
2350 return ioctl(ciptr->fd, I_NREAD, (char *)pend);
2352 return ioctl(ciptr->fd, FIONREAD, (char *)pend);
2357 TRANS(LocalRead)(ciptr, buf, size)
2359 XtransConnInfo ciptr;
2364 PRMSG(2,"LocalRead(%d,%x,%d)\n", ciptr->fd, buf, size );
2366 return read(ciptr->fd,buf,size);
2370 TRANS(LocalWrite)(ciptr, buf, size)
2372 XtransConnInfo ciptr;
2377 PRMSG(2,"LocalWrite(%d,%x,%d)\n", ciptr->fd, buf, size );
2379 return write(ciptr->fd,buf,size);
2383 TRANS(LocalReadv)(ciptr, buf, size)
2385 XtransConnInfo ciptr;
2390 PRMSG(2,"LocalReadv(%d,%x,%d)\n", ciptr->fd, buf, size );
2392 return READV(ciptr,buf,size);
2396 TRANS(LocalWritev)(ciptr, buf, size)
2398 XtransConnInfo ciptr;
2403 PRMSG(2,"LocalWritev(%d,%x,%d)\n", ciptr->fd, buf, size );
2405 return WRITEV(ciptr,buf,size);
2409 TRANS(LocalDisconnect)(ciptr)
2411 XtransConnInfo ciptr;
2414 PRMSG(2,"LocalDisconnect(%x->%d)\n", ciptr, ciptr->fd, 0);
2420 TRANS(LocalClose)(ciptr)
2422 XtransConnInfo ciptr;
2425 struct sockaddr_un *sockname=(struct sockaddr_un *) ciptr->addr;
2426 char path[200]; /* > sizeof sun_path +1 */
2429 PRMSG(2,"LocalClose(%x->%d)\n", ciptr, ciptr->fd ,0);
2431 ret=close(ciptr->fd);
2435 && sockname->sun_family == AF_UNIX
2436 && sockname->sun_path[0] )
2438 strncpy(path,sockname->sun_path,
2439 ciptr->addrlen-sizeof(sockname->sun_family));
2447 TRANS(LocalCloseForCloning)(ciptr)
2449 XtransConnInfo ciptr;
2454 PRMSG(2,"LocalCloseForCloning(%x->%d)\n", ciptr, ciptr->fd ,0);
2456 /* Don't unlink path */
2458 ret=close(ciptr->fd);
2465 * MakeAllCOTSServerListeners() will go through the entire Xtransports[]
2466 * array defined in Xtrans.c and try to OpenCOTSServer() for each entry.
2467 * We will add duplicate entries to that table so that the OpenCOTSServer()
2468 * function will get called once for each type of local transport.
2470 * The TransName is in lowercase, so it will never match during a normal
2471 * call to SelectTransport() in Xtrans.c.
2474 Xtransport TRANS(LocalFuncs) = {
2475 /* Local Interface */
2477 TRANS_ALIAS | TRANS_LOCAL,
2479 TRANS(LocalOpenCOTSClient),
2480 #endif /* TRANS_CLIENT */
2482 TRANS(LocalOpenCOTSServer),
2483 #endif /* TRANS_SERVER */
2485 TRANS(LocalOpenCLTSClient),
2486 #endif /* TRANS_CLIENT */
2488 TRANS(LocalOpenCLTSServer),
2489 #endif /* TRANS_SERVER */
2491 TRANS(LocalReopenCOTSServer),
2492 TRANS(LocalReopenCLTSServer),
2494 TRANS(LocalSetOption),
2496 TRANS(LocalCreateListener),
2497 NULL, /* ResetListener */
2499 #endif /* TRANS_SERVER */
2501 TRANS(LocalConnect),
2502 #endif /* TRANS_CLIENT */
2503 TRANS(LocalBytesReadable),
2508 TRANS(LocalDisconnect),
2510 TRANS(LocalCloseForCloning),
2513 Xtransport TRANS(PTSFuncs) = {
2514 /* Local Interface */
2518 TRANS(LocalOpenCOTSClient),
2519 #endif /* TRANS_CLIENT */
2521 TRANS(LocalOpenCOTSServer),
2522 #endif /* TRANS_SERVER */
2524 TRANS(LocalOpenCLTSClient),
2525 #endif /* TRANS_CLIENT */
2527 TRANS(LocalOpenCLTSServer),
2528 #endif /* TRANS_SERVER */
2530 TRANS(LocalReopenCOTSServer),
2531 TRANS(LocalReopenCLTSServer),
2533 TRANS(LocalSetOption),
2535 TRANS(LocalCreateListener),
2536 NULL, /* ResetListener */
2538 #endif /* TRANS_SERVER */
2540 TRANS(LocalConnect),
2541 #endif /* TRANS_CLIENT */
2542 TRANS(LocalBytesReadable),
2547 TRANS(LocalDisconnect),
2549 TRANS(LocalCloseForCloning),
2552 Xtransport TRANS(NAMEDFuncs) = {
2553 /* Local Interface */
2557 TRANS(LocalOpenCOTSClient),
2558 #endif /* TRANS_CLIENT */
2560 TRANS(LocalOpenCOTSServer),
2561 #endif /* TRANS_SERVER */
2563 TRANS(LocalOpenCLTSClient),
2564 #endif /* TRANS_CLIENT */
2566 TRANS(LocalOpenCLTSServer),
2567 #endif /* TRANS_SERVER */
2569 TRANS(LocalReopenCOTSServer),
2570 TRANS(LocalReopenCLTSServer),
2572 TRANS(LocalSetOption),
2574 TRANS(LocalCreateListener),
2575 NULL, /* ResetListener */
2577 #endif /* TRANS_SERVER */
2579 TRANS(LocalConnect),
2580 #endif /* TRANS_CLIENT */
2581 TRANS(LocalBytesReadable),
2586 TRANS(LocalDisconnect),
2588 TRANS(LocalCloseForCloning),
2591 Xtransport TRANS(ISCFuncs) = {
2592 /* Local Interface */
2596 TRANS(LocalOpenCOTSClient),
2597 #endif /* TRANS_CLIENT */
2599 TRANS(LocalOpenCOTSServer),
2600 #endif /* TRANS_SERVER */
2602 TRANS(LocalOpenCLTSClient),
2603 #endif /* TRANS_CLIENT */
2605 TRANS(LocalOpenCLTSServer),
2606 #endif /* TRANS_SERVER */
2608 TRANS(LocalReopenCOTSServer),
2609 TRANS(LocalReopenCLTSServer),
2611 TRANS(LocalSetOption),
2613 TRANS(LocalCreateListener),
2614 NULL, /* ResetListener */
2616 #endif /* TRANS_SERVER */
2618 TRANS(LocalConnect),
2619 #endif /* TRANS_CLIENT */
2620 TRANS(LocalBytesReadable),
2625 TRANS(LocalDisconnect),
2627 TRANS(LocalCloseForCloning),
2629 Xtransport TRANS(SCOFuncs) = {
2630 /* Local Interface */
2634 TRANS(LocalOpenCOTSClient),
2635 #endif /* TRANS_CLIENT */
2637 TRANS(LocalOpenCOTSServer),
2638 #endif /* TRANS_SERVER */
2640 TRANS(LocalOpenCLTSClient),
2641 #endif /* TRANS_CLIENT */
2643 TRANS(LocalOpenCLTSServer),
2644 #endif /* TRANS_SERVER */
2646 TRANS(LocalReopenCOTSServer),
2647 TRANS(LocalReopenCLTSServer),
2649 TRANS(LocalSetOption),
2651 TRANS(LocalCreateListener),
2652 NULL, /* ResetListener */
2654 #endif /* TRANS_SERVER */
2656 TRANS(LocalConnect),
2657 #endif /* TRANS_CLIENT */
2658 TRANS(LocalBytesReadable),
2663 TRANS(LocalDisconnect),
2665 TRANS(LocalCloseForCloning),