3 Copyright 1993, 1994, 1998 The Open Group
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
11 The above copyright notice and this permission notice shall be included
12 in all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 OTHER DEALINGS IN THE SOFTWARE.
22 Except as contained in this notice, the name of The Open Group shall
23 not be used in advertising or otherwise to promote the sale, use or
24 other dealings in this Software without prior written authorization
27 * Copyright 1993, 1994 NCR Corporation - Dayton, Ohio, USA
31 * Permission to use, copy, modify, and distribute this software and its
32 * documentation for any purpose and without fee is hereby granted, provided
33 * that the above copyright notice appear in all copies and that both that
34 * copyright notice and this permission notice appear in supporting
35 * documentation, and that the name NCR not be used in advertising
36 * or publicity pertaining to distribution of the software without specific,
37 * written prior permission. NCR makes no representations about the
38 * suitability of this software for any purpose. It is provided "as is"
39 * without express or implied warranty.
41 * NCR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
42 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
43 * NO EVENT SHALL NCR BE LIABLE FOR ANY SPECIAL, INDIRECT OR
44 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
45 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
46 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
47 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
52 * The connection code/ideas in lib/X and server/os for SVR4/Intel
53 * environments was contributed by the following companies/groups:
57 * Pittsburgh Powercomputing Corporation (PPc)/Quarterdeck Office Systems
59 * Unix System Laboratories (USL) / Novell
62 * The goal is to have common connection code among all SVR4/Intel vendors.
64 * ALL THE ABOVE COMPANIES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
65 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
66 * IN NO EVENT SHALL THESE COMPANIES * BE LIABLE FOR ANY SPECIAL, INDIRECT
67 * OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
68 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
69 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
70 * OR PERFORMANCE OF THIS SOFTWARE.
75 #include <sys/signal.h>
76 #include <sys/ioctl.h>
78 #if defined(SVR4) || defined(__SVR4)
79 #include <sys/filio.h>
84 # include <sys/stropts.h>
87 #include <sys/types.h>
90 * The local transports should be treated the same as a UNIX domain socket
91 * wrt authentication, etc. Because of this, we will use struct sockaddr_un
92 * for the address format. This will simplify the code in other places like
96 #include <sys/socket.h>
102 /* Types of local connections supported:
108 # define LOCAL_TRANS_PTS
110 #if defined(SVR4) || defined(__SVR4)
111 # define LOCAL_TRANS_NAMED
113 #if defined(__SCO__) || defined(__UNIXWARE__)
114 # define LOCAL_TRANS_SCO
117 static int TRANS(LocalClose)(XtransConnInfo ciptr);
120 * These functions actually implement the local connection mechanisms.
123 /* Type Not Supported */
126 TRANS(OpenFail)(XtransConnInfo ciptr, char *port)
135 TRANS(ReopenFail)(XtransConnInfo ciptr, int fd, char *port)
141 #endif /* TRANS_REOPEN */
146 TRANS(FillAddrInfo)(XtransConnInfo ciptr, char *sun_path, char *peer_sun_path)
149 struct sockaddr_un *sunaddr;
150 struct sockaddr_un *p_sunaddr;
152 ciptr->family = AF_UNIX;
153 ciptr->addrlen = sizeof (struct sockaddr_un);
155 if ((sunaddr = (struct sockaddr_un *) xalloc (ciptr->addrlen)) == NULL)
157 PRMSG(1,"FillAddrInfo: failed to allocate memory for addr\n", 0, 0, 0);
161 sunaddr->sun_family = AF_UNIX;
163 if (strlen(sun_path) > sizeof(sunaddr->sun_path) - 1) {
164 PRMSG(1, "FillAddrInfo: path too long\n", 0, 0, 0);
165 xfree((char *) sunaddr);
168 strcpy (sunaddr->sun_path, sun_path);
169 #if defined(BSD44SOCKETS)
170 sunaddr->sun_len = strlen (sunaddr->sun_path);
173 ciptr->addr = (char *) sunaddr;
175 ciptr->peeraddrlen = sizeof (struct sockaddr_un);
177 if ((p_sunaddr = (struct sockaddr_un *) xalloc (
178 ciptr->peeraddrlen)) == NULL)
181 "FillAddrInfo: failed to allocate memory for peer addr\n",
183 xfree ((char *) sunaddr);
189 p_sunaddr->sun_family = AF_UNIX;
191 if (strlen(peer_sun_path) > sizeof(p_sunaddr->sun_path) - 1) {
192 PRMSG(1, "FillAddrInfo: peer path too long\n", 0, 0, 0);
193 xfree((char *) p_sunaddr);
196 strcpy (p_sunaddr->sun_path, peer_sun_path);
197 #if defined(BSD44SOCKETS)
198 p_sunaddr->sun_len = strlen (p_sunaddr->sun_path);
201 ciptr->peeraddr = (char *) p_sunaddr;
208 #ifdef LOCAL_TRANS_PTS
211 #if defined(SYSV) && !defined(__SCO__)
214 #define SIGNAL_T void
217 typedef SIGNAL_T (*PFV)();
221 extern char *ptsname(
225 static void _dummy(int sig)
229 #endif /* LOCAL_TRANS_PTS */
232 #define X_STREAMS_DIR "/dev/X"
233 #define DEV_SPX "/dev/spx"
236 #define X_STREAMS_DIR "/dev/X"
238 #define X_STREAMS_DIR "/tmp/.X11-pipe"
242 #define DEV_PTMX "/dev/ptmx"
246 #define PTSNODENAME "/dev/X/server."
248 #define NAMEDNODENAME "/tmp/.X11-pipe/X"
250 #define NAMEDNODENAME "/dev/X/Nserver."
252 #define SCORNODENAME "/dev/X%1sR"
253 #define SCOSNODENAME "/dev/X%1sS"
258 #define NAMEDNODENAME "/tmp/.XIM-pipe/XIM"
260 #define PTSNODENAME "/dev/X/XIM."
261 #define NAMEDNODENAME "/dev/X/NXIM."
262 #define SCORNODENAME "/dev/XIM.%sR"
263 #define SCOSNODENAME "/dev/XIM.%sS"
266 #if defined(FS_t) || defined (FONT_t)
268 #define NAMEDNODENAME "/tmp/.font-pipe/fs"
271 * USL has already defined something here. We need to check with them
272 * and see if their choice is usable here.
274 #define PTSNODENAME "/dev/X/fontserver."
275 #define NAMEDNODENAME "/dev/X/Nfontserver."
276 #define SCORNODENAME "/dev/fontserver.%sR"
277 #define SCOSNODENAME "/dev/fontserver.%sS"
282 #define NAMEDNODENAME "/tmp/.ICE-pipe/"
284 #define PTSNODENAME "/dev/X/ICE."
285 #define NAMEDNODENAME "/dev/X/NICE."
286 #define SCORNODENAME "/dev/ICE.%sR"
287 #define SCOSNODENAME "/dev/ICE.%sS"
292 #define NAMEDNODENAME "/tmp/.Test-unix/test"
294 #define PTSNODENAME "/dev/X/transtest."
295 #define NAMEDNODENAME "/dev/X/Ntranstest."
296 #define SCORNODENAME "/dev/transtest.%sR"
297 #define SCOSNODENAME "/dev/transtest.%sS"
302 #ifdef LOCAL_TRANS_PTS
306 TRANS(PTSOpenClient)(XtransConnInfo ciptr, char *port)
310 int fd,server,exitval,alarm_time,ret;
311 char server_path[64];
312 char *slave, namelen;
313 char buf[20]; /* MAX_PATH_LEN?? */
318 PRMSG(2,"PTSOpenClient(%s)\n", port, 0,0 );
320 #if !defined(PTSNODENAME)
321 PRMSG(1,"PTSOpenClient: Protocol is not supported by a pts connection\n", 0,0,0);
324 if (port && *port ) {
325 if( *port == '/' ) { /* A full pathname */
326 (void) sprintf(server_path, "%s", port);
328 (void) sprintf(server_path, "%s%s", PTSNODENAME, port);
331 (void) sprintf(server_path, "%s%d", PTSNODENAME, getpid());
336 * Open the node the on which the server is listening.
339 if ((server = open (server_path, O_RDWR)) < 0) {
340 PRMSG(1,"PTSOpenClient: failed to open %s\n", server_path, 0,0);
346 * Open the streams based pipe that will be this connection.
349 if ((fd = open(DEV_PTMX, O_RDWR)) < 0) {
350 PRMSG(1,"PTSOpenClient: failed to open %s\n", DEV_PTMX, 0,0);
358 slave = ptsname(fd); /* get name */
360 if( slave == NULL ) {
361 PRMSG(1,"PTSOpenClient: failed to get ptsname()\n", 0,0,0);
368 * This is neccesary for the case where a program is setuid to non-root.
369 * grantpt() calls /usr/lib/pt_chmod which is set-uid root. This program will
370 * set the owner of the pt device incorrectly if the uid is not restored
371 * before it is called. The problem is that once it gets restored, it
372 * cannot be changed back to its original condition, hence the fork().
375 if(!(saved_pid=fork())) {
378 saved_euid = geteuid();
379 /** sets the euid to the actual/real uid **/
380 if (setuid( getuid() ) == -1) {
383 if( chown( slave, saved_euid, -1 ) < 0 ) {
390 waitpid(saved_pid, &exitval, 0);
391 if (WIFEXITED(exitval) && WEXITSTATUS(exitval) != 0) {
394 PRMSG(1, "PTSOpenClient: cannot set the owner of %s\n",
398 if (chmod(slave, 0666) < 0) {
401 PRMSG(1,"PTSOpenClient: Cannot chmod %s\n", slave, 0,0);
406 * write slave name to server
409 namelen = strlen(slave);
411 (void) sprintf(&buf[1], slave);
412 (void) write(server, buf, namelen+1);
413 (void) close(server);
416 * wait for server to respond
419 savef = signal(SIGALRM, _dummy);
420 alarm_time = alarm (30); /* CONNECT_TIMEOUT */
422 ret = read(fd, buf, 1);
424 (void) alarm(alarm_time);
425 (void) signal(SIGALRM, savef);
429 "PTSOpenClient: failed to get acknoledgement from server\n", 0, 0, 0);
435 * Everything looks good: fill in the XtransConnInfo structure.
438 if (TRANS(FillAddrInfo) (ciptr, slave, server_path) == 0)
440 PRMSG(1,"PTSOpenClient: failed to fill in addr info\n", 0, 0, 0);
447 #endif /* !PTSNODENAME */
450 #endif /* TRANS_CLIENT */
456 TRANS(PTSOpenServer)(XtransConnInfo ciptr, char *port)
461 char server_path[64], *slave;
465 PRMSG(2,"PTSOpenServer(%s)\n", port, 0,0 );
467 #if !defined(PTSNODENAME)
468 PRMSG(1,"PTSOpenServer: Protocol is not supported by a pts connection\n", 0,0,0);
471 if (port && *port ) {
472 if( *port == '/' ) { /* A full pathname */
473 (void) sprintf(server_path, "%s", port);
475 (void) sprintf(server_path, "%s%s", PTSNODENAME, port);
478 (void) sprintf(server_path, "%s%d", PTSNODENAME, getpid());
481 #ifdef HAS_STICKY_DIR_BIT
486 if (trans_mkdir(X_STREAMS_DIR, mode) == -1) {
487 PRMSG (1, "PTSOpenServer: mkdir(%s) failed, errno = %d\n",
488 X_STREAMS_DIR, errno, 0);
493 if( (fd=open(server_path, O_RDWR)) >= 0 ) {
495 * This doesn't prevent the server from starting up, and doesn't
496 * prevent clients from trying to connect to the in-use PTS (which
497 * is often in use by something other than another server).
499 PRMSG(1, "PTSOpenServer: A server is already running on port %s\n", port, 0,0 );
500 PRMSG(1, "PTSOpenServer: Remove %s if this is incorrect.\n", server_path, 0,0 );
505 /* Just remove the old path (which is what happens with UNIXCONN) */
510 if( (fd=open(DEV_PTMX, O_RDWR)) < 0) {
511 PRMSG(1, "PTSOpenServer: Unable to open %s\n", DEV_PTMX, 0,0 );
518 if( (slave=ptsname(fd)) == NULL) {
519 PRMSG(1, "PTSOpenServer: Unable to get slave device name\n", 0,0,0 );
524 if( link(slave,server_path) < 0 ) {
525 PRMSG(1, "PTSOpenServer: Unable to link %s to %s\n", slave, server_path,0 );
530 if( chmod(server_path, 0666) < 0 ) {
531 PRMSG(1, "PTSOpenServer: Unable to chmod %s to 0666\n", server_path,0,0 );
536 if( (server=open(server_path, O_RDWR)) < 0 ) {
537 PRMSG(1, "PTSOpenServer: Unable to open server device %s\n", server_path,0,0 );
545 * Everything looks good: fill in the XtransConnInfo structure.
548 if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
550 PRMSG(1,"PTSOpenServer: failed to fill in addr info\n", 0, 0, 0);
557 #endif /* !PTSNODENAME */
561 TRANS(PTSAccept)(XtransConnInfo ciptr, XtransConnInfo newciptr, int *status)
566 unsigned char length;
568 struct sockaddr_un *sunaddr;
570 PRMSG(2,"PTSAccept(%x->%d)\n",ciptr,ciptr->fd,0);
572 if( (in=read(ciptr->fd,&length,1)) <= 0 ){
575 "PTSAccept: Incoming connection closed\n",0,0,0);
579 "PTSAccept: Error reading incoming connection. errno=%d \n",
582 *status = TRANS_ACCEPT_MISC_ERROR;
586 if( (in=read(ciptr->fd,buf,length)) <= 0 ){
589 "PTSAccept: Incoming connection closed\n",0,0,0);
593 "PTSAccept: Error reading device name for new connection. errno=%d \n",
596 *status = TRANS_ACCEPT_MISC_ERROR;
602 if( (newfd=open(buf,O_RDWR)) < 0 ) {
603 PRMSG(1, "PTSAccept: Failed to open %s\n",buf,0,0);
604 *status = TRANS_ACCEPT_MISC_ERROR;
611 * Everything looks good: fill in the XtransConnInfo structure.
614 newciptr->addrlen=ciptr->addrlen;
615 if( (newciptr->addr=(char *)xalloc(newciptr->addrlen)) == NULL ) {
616 PRMSG(1,"PTSAccept: failed to allocate memory for peer addr\n",
619 *status = TRANS_ACCEPT_BAD_MALLOC;
623 memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen);
625 newciptr->peeraddrlen=sizeof(struct sockaddr_un);
626 if( (sunaddr=(struct sockaddr_un *)xalloc(newciptr->peeraddrlen)) == NULL ) {
627 PRMSG(1,"PTSAccept: failed to allocate memory for peer addr\n",
629 xfree(newciptr->addr);
631 *status = TRANS_ACCEPT_BAD_MALLOC;
635 sunaddr->sun_family=AF_UNIX;
636 strcpy(sunaddr->sun_path,buf);
637 #if defined(BSD44SOCKETS)
638 sunaddr->sun_len=strlen(sunaddr->sun_path);
641 newciptr->peeraddr=(char *)sunaddr;
648 #endif /* TRANS_SERVER */
649 #endif /* LOCAL_TRANS_PTS */
652 #ifdef LOCAL_TRANS_NAMED
659 TRANS(NAMEDOpenClient)(XtransConnInfo ciptr, char *port)
664 char server_path[64];
665 struct stat filestat;
667 extern int isastream(int);
671 PRMSG(2,"NAMEDOpenClient(%s)\n", port, 0,0 );
673 #if !defined(NAMEDNODENAME)
674 PRMSG(1,"NAMEDOpenClient: Protocol is not supported by a NAMED connection\n", 0,0,0);
677 if ( port && *port ) {
678 if( *port == '/' ) { /* A full pathname */
679 (void) snprintf(server_path, sizeof(server_path), "%s", port);
681 (void) snprintf(server_path, sizeof(server_path), "%s%s", NAMEDNODENAME, port);
684 (void) snprintf(server_path, sizeof(server_path), "%s%ld", NAMEDNODENAME, (long)getpid());
687 if ((fd = open(server_path, O_RDWR)) < 0) {
688 PRMSG(1,"NAMEDOpenClient: Cannot open %s for NAMED connection\n", server_path, 0,0 );
692 if (fstat(fd, &filestat) < 0 ) {
693 PRMSG(1,"NAMEDOpenClient: Cannot stat %s for NAMED connection\n", server_path, 0,0 );
698 if ((filestat.st_mode & S_IFMT) != S_IFIFO) {
699 PRMSG(1,"NAMEDOpenClient: Device %s is not a FIFO\n", server_path, 0,0 );
700 /* Is this really a failure? */
706 if (isastream(fd) <= 0) {
707 PRMSG(1,"NAMEDOpenClient: %s is not a streams device\n", server_path, 0,0 );
713 * Everything looks good: fill in the XtransConnInfo structure.
716 if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
718 PRMSG(1,"NAMEDOpenClient: failed to fill in addr info\n",
726 #endif /* !NAMEDNODENAME */
729 #endif /* TRANS_CLIENT */
737 TRANS(NAMEDOpenPipe)(const char *server_path)
739 PRMSG(2,"NAMEDOpenPipe(%s)\n", server_path, 0,0 );
745 #if defined(sun) && defined(X11_t)
746 mode = 0775; /* Solaris requires uid or gid 0 to create X11 pipes */
748 #ifdef HAS_STICKY_DIR_BIT
754 if (trans_mkdir(X_STREAMS_DIR, mode) == -1) {
755 PRMSG (1, "NAMEDOpenPipe: mkdir(%s) failed, errno = %d\n",
756 X_STREAMS_DIR, errno, 0);
760 if(stat(server_path, &sbuf) != 0) {
761 if (errno == ENOENT) {
762 if ((fd = creat(server_path, (mode_t)0666)) == -1) {
763 PRMSG(1, "NAMEDOpenPipe: Can't open %s\n", server_path, 0,0 );
767 if (chmod(server_path, (mode_t)0666) < 0) {
768 PRMSG(1, "NAMEDOpenPipe: Can't open %s\n", server_path, 0,0 );
772 PRMSG(1, "NAMEDOpenPipe: stat on %s failed\n", server_path, 0,0 );
777 if( pipe(pipefd) != 0) {
778 PRMSG(1, "NAMEDOpenPipe: pipe() failed, errno=%d\n",errno, 0,0 );
782 if( ioctl(pipefd[0], I_PUSH, "connld") != 0) {
783 PRMSG(1, "NAMEDOpenPipe: ioctl(I_PUSH,\"connld\") failed, errno=%d\n",errno, 0,0 );
789 if( fattach(pipefd[0], server_path) != 0) {
790 PRMSG(1, "NAMEDOpenPipe: fattach(%s) failed, errno=%d\n", server_path,errno, 0 );
801 TRANS(NAMEDOpenServer)(XtransConnInfo ciptr, char *port)
805 char server_path[64];
808 PRMSG(2,"NAMEDOpenServer(%s)\n", port, 0,0 );
810 #if !defined(NAMEDNODENAME)
811 PRMSG(1,"NAMEDOpenServer: Protocol is not supported by a NAMED connection\n", 0,0,0);
814 if ( port && *port ) {
815 if( *port == '/' ) { /* A full pathname */
816 (void) snprintf(server_path, sizeof(server_path), "%s", port);
818 (void) snprintf(server_path, sizeof(server_path), "%s%s",
819 NAMEDNODENAME, port);
822 (void) snprintf(server_path, sizeof(server_path), "%s%ld",
823 NAMEDNODENAME, (long)getpid());
826 fd = TRANS(NAMEDOpenPipe)(server_path);
832 * Everything looks good: fill in the XtransConnInfo structure.
835 if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
837 PRMSG(1,"NAMEDOpenServer: failed to fill in addr info\n", 0,0,0);
838 TRANS(LocalClose)(ciptr);
844 #endif /* !NAMEDNODENAME */
848 TRANS(NAMEDResetListener) (XtransConnInfo ciptr)
851 int status = TRANS_RESET_NOOP;
852 struct sockaddr_un *sockname=(struct sockaddr_un *) ciptr->addr;
855 PRMSG(2,"NAMEDResetListener(%p, %d)\n", ciptr, ciptr->fd, 0 );
857 if (ciptr->fd != -1) {
859 * see if the pipe has disappeared
862 if (stat (sockname->sun_path, &statb) == -1 ||
863 (statb.st_mode & S_IFMT) != S_IFIFO) {
864 PRMSG(3, "Pipe %s trashed, recreating\n", sockname->sun_path, 0, 0);
865 TRANS(LocalClose)(ciptr);
866 ciptr->fd = TRANS(NAMEDOpenPipe)(sockname->sun_path);
868 return TRANS_RESET_NEW_FD;
870 return TRANS_CREATE_LISTENER_FAILED;
873 return TRANS_RESET_NOOP;
877 TRANS(NAMEDAccept)(XtransConnInfo ciptr, XtransConnInfo newciptr, int *status)
880 struct strrecvfd str;
882 PRMSG(2,"NAMEDAccept(%x->%d)\n", ciptr, ciptr->fd, 0 );
884 if( ioctl(ciptr->fd, I_RECVFD, &str ) < 0 ) {
885 PRMSG(1, "NAMEDAccept: ioctl(I_RECVFD) failed, errno=%d\n", errno, 0,0 );
886 *status = TRANS_ACCEPT_MISC_ERROR;
891 * Everything looks good: fill in the XtransConnInfo structure.
893 newciptr->family=ciptr->family;
894 newciptr->addrlen=ciptr->addrlen;
895 if( (newciptr->addr=(char *)xalloc(newciptr->addrlen)) == NULL ) {
897 "NAMEDAccept: failed to allocate memory for pipe addr\n",
900 *status = TRANS_ACCEPT_BAD_MALLOC;
904 memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen);
906 newciptr->peeraddrlen=newciptr->addrlen;
907 if( (newciptr->peeraddr=(char *)xalloc(newciptr->peeraddrlen)) == NULL ) {
909 "NAMEDAccept: failed to allocate memory for peer addr\n",
911 xfree(newciptr->addr);
913 *status = TRANS_ACCEPT_BAD_MALLOC;
917 memcpy(newciptr->peeraddr,newciptr->addr,newciptr->peeraddrlen);
924 #endif /* TRANS_SERVER */
926 #endif /* LOCAL_TRANS_NAMED */
930 #if defined(LOCAL_TRANS_SCO)
933 * connect_spipe is used by the SCO connection type.
936 connect_spipe(int fd1, int fd2)
939 struct strfdinsert sbuf;
941 sbuf.databuf.maxlen = -1;
942 sbuf.databuf.len = -1;
943 sbuf.databuf.buf = NULL;
944 sbuf.ctlbuf.maxlen = sizeof(long);
945 sbuf.ctlbuf.len = sizeof(long);
946 sbuf.ctlbuf.buf = (caddr_t)&temp;
951 if( ioctl(fd1, I_FDINSERT, &sbuf) < 0 )
958 * named_spipe is used by the SCO connection type.
962 named_spipe(int fd, char *path)
970 (void) fstat(fd, &sbuf);
971 ret = mknod(path, 0020666, sbuf.st_rdev);
984 #endif /* defined(LOCAL_TRANS_SCO) */
989 #ifdef LOCAL_TRANS_SCO
993 * 2002-11-09 (jkj@sco.com)
995 * This code has been modified to match what is in the actual SCO X server.
996 * This greatly helps inter-operability between X11R6 and X11R5 (the native
997 * SCO server). Mainly, it relies on streams nodes existing in /dev, not
998 * creating them or unlinking them, which breaks the native X server.
1000 * However, this is only for the X protocol. For all other protocols, we
1001 * do in fact create the nodes, as only X11R6 will use them, and this makes
1002 * it possible to have both types of clients running, otherwise we get all
1003 * kinds of nasty errors on startup for anything that doesnt use the X
1004 * protocol (like SM, when KDE starts up).
1010 TRANS(SCOOpenClient)(XtransConnInfo ciptr, char *port)
1013 int fd, server, fl, ret;
1014 char server_path[64];
1015 struct strbuf ctlbuf;
1016 unsigned long alarm_time;
1019 extern int getmsg(), putmsg();
1022 PRMSG(2,"SCOOpenClient(%s)\n", port, 0,0 );
1023 if (!port || !port[0])
1026 #if !defined(SCORNODENAME)
1027 PRMSG(2,"SCOOpenClient: Protocol is not supported by a SCO connection\n", 0,0,0);
1030 (void) sprintf(server_path, SCORNODENAME, port);
1032 if ((server = open(server_path, O_RDWR)) < 0) {
1033 PRMSG(1,"SCOOpenClient: failed to open %s\n", server_path, 0,0 );
1037 if ((fd = open(DEV_SPX, O_RDWR)) < 0) {
1038 PRMSG(1,"SCOOpenClient: failed to open %s\n", DEV_SPX, 0,0 );
1043 (void) write(server, &server, 1);
1045 ctlbuf.maxlen = sizeof(long);
1046 ctlbuf.buf = (caddr_t)&temp;
1049 savef = signal(SIGALRM, _dummy);
1050 alarm_time = alarm(10);
1052 ret = getmsg(server, &ctlbuf, 0, &fl);
1054 (void) alarm(alarm_time);
1055 (void) signal(SIGALRM, savef);
1058 PRMSG(1,"SCOOpenClient: error from getmsg\n", 0,0,0 );
1064 /* The msg we got via getmsg is the result of an
1065 * I_FDINSERT, so if we do a putmsg with whatever
1066 * we recieved, we're doing another I_FDINSERT ...
1068 (void) putmsg(fd, &ctlbuf, 0, 0);
1069 (void) fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,0)|O_NDELAY);
1071 (void) close(server);
1074 * Everything looks good: fill in the XtransConnInfo structure.
1077 #if defined(X11_t) && defined(__SCO__)
1078 ciptr->flags |= TRANS_NOUNLINK;
1080 if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
1082 PRMSG(1,"SCOOpenClient: failed to fill addr info\n", 0, 0, 0);
1089 #endif /* !SCORNODENAME */
1092 #endif /* TRANS_CLIENT */
1098 TRANS(SCOOpenServer)(XtransConnInfo ciptr, char *port)
1101 char serverR_path[64];
1102 char serverS_path[64];
1103 struct flock mylock;
1108 PRMSG(2,"SCOOpenServer(%s)\n", port, 0,0 );
1109 if (!port || !port[0])
1112 #if !defined(SCORNODENAME)
1113 PRMSG(1,"SCOOpenServer: Protocol is not supported by a SCO connection\n", 0,0,0);
1116 (void) sprintf(serverR_path, SCORNODENAME, port);
1117 (void) sprintf(serverS_path, SCOSNODENAME, port);
1119 #if !defined(X11_t) || !defined(__SCO__)
1120 unlink(serverR_path);
1121 unlink(serverS_path);
1123 if ((fds = open(DEV_SPX, O_RDWR)) < 0 ||
1124 (fdr = open(DEV_SPX, O_RDWR)) < 0 ) {
1125 PRMSG(1,"SCOOpenServer: failed to open %s\n", DEV_SPX, 0,0 );
1133 if (named_spipe (fds, serverS_path) == -1) {
1134 PRMSG(1,"SCOOpenServer: failed to create %s\n", serverS_path, 0, 0);
1140 if (named_spipe (fdr, serverR_path) == -1) {
1141 PRMSG(1,"SCOOpenServer: failed to create %s\n", serverR_path, 0, 0);
1148 fds = open (serverS_path, O_RDWR | O_NDELAY);
1150 PRMSG(1,"SCOOpenServer: failed to open %s\n", serverS_path, 0, 0);
1155 * Lock the connection device for the duration of the server.
1156 * This resolves multiple server starts especially on SMP machines.
1158 mylock.l_type = F_WRLCK;
1159 mylock.l_whence = 0;
1162 if (fcntl (fds, F_SETLK, &mylock) < 0) {
1163 PRMSG(1,"SCOOpenServer: failed to lock %s\n", serverS_path, 0, 0);
1168 fdr = open (serverR_path, O_RDWR | O_NDELAY);
1170 PRMSG(1,"SCOOpenServer: failed to open %s\n", serverR_path, 0, 0);
1176 if (connect_spipe(fds, fdr)) {
1177 PRMSG(1,"SCOOpenServer: ioctl(I_FDINSERT) failed on %s\n",
1178 serverS_path, 0, 0);
1185 * Everything looks good: fill in the XtransConnInfo structure.
1188 #if defined(X11_t) && defined(__SCO__)
1189 ciptr->flags |= TRANS_NOUNLINK;
1191 if (TRANS(FillAddrInfo) (ciptr, serverS_path, serverR_path) == 0) {
1192 PRMSG(1,"SCOOpenServer: failed to fill in addr info\n", 0,0,0);
1200 #endif /* !SCORNODENAME */
1204 TRANS(SCOAccept)(XtransConnInfo ciptr, XtransConnInfo newciptr, int *status)
1209 PRMSG(2,"SCOAccept(%d)\n", ciptr->fd, 0,0 );
1211 if (read(ciptr->fd, &c, 1) < 0) {
1212 PRMSG(1,"SCOAccept: can't read from client\n",0,0,0);
1213 *status = TRANS_ACCEPT_MISC_ERROR;
1217 if( (fd = open(DEV_SPX, O_RDWR)) < 0 ) {
1218 PRMSG(1,"SCOAccept: can't open \"%s\"\n",DEV_SPX, 0,0 );
1219 *status = TRANS_ACCEPT_MISC_ERROR;
1223 if (connect_spipe (ciptr->fd, fd) < 0) {
1224 PRMSG(1,"SCOAccept: ioctl(I_FDINSERT) failed\n", 0, 0, 0);
1226 *status = TRANS_ACCEPT_MISC_ERROR;
1231 * Everything looks good: fill in the XtransConnInfo structure.
1234 newciptr->addrlen=ciptr->addrlen;
1235 if( (newciptr->addr=(char *)xalloc(newciptr->addrlen)) == NULL ) {
1237 "SCOAccept: failed to allocate memory for peer addr\n",
1240 *status = TRANS_ACCEPT_BAD_MALLOC;
1244 memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen);
1245 #if defined(__SCO__)
1246 newciptr->flags |= TRANS_NOUNLINK;
1249 newciptr->peeraddrlen=newciptr->addrlen;
1250 if( (newciptr->peeraddr=(char *)xalloc(newciptr->peeraddrlen)) == NULL ) {
1252 "SCOAccept: failed to allocate memory for peer addr\n",
1254 xfree(newciptr->addr);
1256 *status = TRANS_ACCEPT_BAD_MALLOC;
1260 memcpy(newciptr->peeraddr,newciptr->addr,newciptr->peeraddrlen);
1267 #endif /* TRANS_SERVER */
1268 #endif /* LOCAL_TRANS_SCO */
1273 #ifdef LOCAL_TRANS_PTS
1276 TRANS(PTSReopenServer)(XtransConnInfo ciptr, int fd, char *port)
1280 char server_path[64];
1283 PRMSG(2,"PTSReopenServer(%d,%s)\n", fd, port, 0 );
1285 #if !defined(PTSNODENAME)
1286 PRMSG(1,"PTSReopenServer: Protocol is not supported by a pts connection\n", 0,0,0);
1289 if (port && *port ) {
1290 if( *port == '/' ) { /* A full pathname */
1291 (void) sprintf(server_path, "%s", port);
1293 (void) sprintf(server_path, "%s%s", PTSNODENAME, port);
1296 (void) sprintf(server_path, "%s%ld", PTSNODENAME, (long)getpid());
1299 if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
1301 PRMSG(1,"PTSReopenServer: failed to fill in addr info\n",
1308 #endif /* !PTSNODENAME */
1311 #endif /* LOCAL_TRANS_PTS */
1313 #ifdef LOCAL_TRANS_NAMED
1316 TRANS(NAMEDReopenServer)(XtransConnInfo ciptr, int fd, char *port)
1319 #ifdef NAMEDNODENAME
1320 char server_path[64];
1323 PRMSG(2,"NAMEDReopenServer(%s)\n", port, 0,0 );
1325 #if !defined(NAMEDNODENAME)
1326 PRMSG(1,"NAMEDReopenServer: Protocol is not supported by a NAMED connection\n", 0,0,0);
1329 if ( port && *port ) {
1330 if( *port == '/' ) { /* A full pathname */
1331 (void) sprintf(server_path, "%s", port);
1333 (void) sprintf(server_path, "%s%s", NAMEDNODENAME, port);
1336 (void) sprintf(server_path, "%s%ld", NAMEDNODENAME, (long)getpid());
1339 if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
1341 PRMSG(1,"NAMEDReopenServer: failed to fill in addr info\n",
1348 #endif /* !NAMEDNODENAME */
1351 #endif /* LOCAL_TRANS_NAMED */
1354 #ifdef LOCAL_TRANS_SCO
1356 TRANS(SCOReopenServer)(XtransConnInfo ciptr, int fd, char *port)
1360 char serverR_path[64], serverS_path[64];
1363 PRMSG(2,"SCOReopenServer(%s)\n", port, 0,0 );
1364 if (!port || !port[0])
1367 #if !defined(SCORNODENAME)
1368 PRMSG(2,"SCOReopenServer: Protocol is not supported by a SCO connection\n", 0,0,0);
1371 (void) sprintf(serverR_path, SCORNODENAME, port);
1372 (void) sprintf(serverS_path, SCOSNODENAME, port);
1374 #if defined(X11_t) && defined(__SCO__)
1375 ciptr->flags |= TRANS_NOUNLINK;
1377 if (TRANS(FillAddrInfo) (ciptr, serverS_path, serverR_path) == 0)
1379 PRMSG(1, "SCOReopenServer: failed to fill in addr info\n", 0,0,0);
1385 #endif /* SCORNODENAME */
1388 #endif /* LOCAL_TRANS_SCO */
1390 #endif /* TRANS_REOPEN */
1395 * This table contains all of the entry points for the different local
1396 * connection mechanisms.
1399 typedef struct _LOCALtrans2dev {
1404 int (*devcotsopenclient)(
1405 XtransConnInfo, char * /*port*/
1408 #endif /* TRANS_CLIENT */
1412 int (*devcotsopenserver)(
1413 XtransConnInfo, char * /*port*/
1416 #endif /* TRANS_SERVER */
1420 int (*devcltsopenclient)(
1421 XtransConnInfo, char * /*port*/
1424 #endif /* TRANS_CLIENT */
1428 int (*devcltsopenserver)(
1429 XtransConnInfo, char * /*port*/
1432 #endif /* TRANS_SERVER */
1436 int (*devcotsreopenserver)(
1442 int (*devcltsreopenserver)(
1448 #endif /* TRANS_REOPEN */
1453 XtransConnInfo /* ciptr */
1457 XtransConnInfo, XtransConnInfo, int *
1460 #endif /* TRANS_SERVER */
1464 static LOCALtrans2dev LOCALtrans2devtab[] = {
1465 #ifdef LOCAL_TRANS_PTS
1468 TRANS(PTSOpenClient),
1469 #endif /* TRANS_CLIENT */
1471 TRANS(PTSOpenServer),
1472 #endif /* TRANS_SERVER */
1475 #endif /* TRANS_CLIENT */
1478 #endif /* TRANS_SERVER */
1480 TRANS(PTSReopenServer),
1484 NULL, /* ResetListener */
1486 #endif /* TRANS_SERVER */
1491 TRANS(PTSOpenClient),
1492 #endif /* TRANS_CLIENT */
1494 TRANS(PTSOpenServer),
1495 #endif /* TRANS_SERVER */
1498 #endif /* TRANS_CLIENT */
1501 #endif /* TRANS_SERVER */
1503 TRANS(PTSReopenServer),
1507 NULL, /* ResetListener */
1509 #endif /* TRANS_SERVER */
1514 TRANS(PTSOpenClient),
1515 #endif /* TRANS_CLIENT */
1517 TRANS(PTSOpenServer),
1518 #endif /* TRANS_SERVER */
1521 #endif /* TRANS_CLIENT */
1524 #endif /* TRANS_SERVER */
1526 TRANS(PTSReopenServer),
1530 NULL, /* ResetListener */
1532 #endif /* TRANS_SERVER */
1534 #else /* !LOCAL_TRANS_PTS */
1537 TRANS(NAMEDOpenClient),
1538 #endif /* TRANS_CLIENT */
1540 TRANS(NAMEDOpenServer),
1541 #endif /* TRANS_SERVER */
1544 #endif /* TRANS_CLIENT */
1547 #endif /* TRANS_SERVER */
1549 TRANS(NAMEDReopenServer),
1553 TRANS(NAMEDResetListener),
1555 #endif /* TRANS_SERVER */
1560 TRANS(NAMEDOpenClient),
1561 #endif /* TRANS_CLIENT */
1563 TRANS(NAMEDOpenServer),
1564 #endif /* TRANS_SERVER */
1567 #endif /* TRANS_CLIENT */
1570 #endif /* TRANS_SERVER */
1572 TRANS(NAMEDReopenServer),
1576 TRANS(NAMEDResetListener),
1578 #endif /* TRANS_SERVER */
1580 #endif /* !LOCAL_TRANS_PTS */
1582 #ifdef LOCAL_TRANS_NAMED
1585 TRANS(NAMEDOpenClient),
1586 #endif /* TRANS_CLIENT */
1588 TRANS(NAMEDOpenServer),
1589 #endif /* TRANS_SERVER */
1592 #endif /* TRANS_CLIENT */
1595 #endif /* TRANS_SERVER */
1597 TRANS(NAMEDReopenServer),
1601 TRANS(NAMEDResetListener),
1603 #endif /* TRANS_SERVER */
1606 #ifdef sun /* Alias "pipe" to named, since that's what Solaris called it */
1609 TRANS(NAMEDOpenClient),
1610 #endif /* TRANS_CLIENT */
1612 TRANS(NAMEDOpenServer),
1613 #endif /* TRANS_SERVER */
1616 #endif /* TRANS_CLIENT */
1619 #endif /* TRANS_SERVER */
1621 TRANS(NAMEDReopenServer),
1625 TRANS(NAMEDResetListener),
1627 #endif /* TRANS_SERVER */
1630 #endif /* LOCAL_TRANS_NAMED */
1633 #ifdef LOCAL_TRANS_SCO
1636 TRANS(SCOOpenClient),
1637 #endif /* TRANS_CLIENT */
1639 TRANS(SCOOpenServer),
1640 #endif /* TRANS_SERVER */
1643 #endif /* TRANS_CLIENT */
1646 #endif /* TRANS_SERVER */
1648 TRANS(SCOReopenServer),
1652 NULL, /* ResetListener */
1654 #endif /* TRANS_SERVER */
1656 #endif /* LOCAL_TRANS_SCO */
1659 #define NUMTRANSPORTS (sizeof(LOCALtrans2devtab)/sizeof(LOCALtrans2dev))
1661 static char *XLOCAL=NULL;
1662 static char *workingXLOCAL=NULL;
1663 static char *freeXLOCAL=NULL;
1665 #if defined(__SCO__)
1666 #define DEF_XLOCAL "SCO:UNIX:PTS"
1667 #elif defined(__UNIXWARE__)
1668 #define DEF_XLOCAL "UNIX:PTS:NAMED:SCO"
1670 #define DEF_XLOCAL "UNIX:NAMED"
1672 #define DEF_XLOCAL "UNIX:PTS:NAMED:SCO"
1676 TRANS(LocalInitTransports)(char *protocol)
1679 PRMSG(3,"LocalInitTransports(%s)\n", protocol, 0,0 );
1681 if( strcmp(protocol,"local") && strcmp(protocol,"LOCAL") )
1683 workingXLOCAL=freeXLOCAL=(char *)xalloc (strlen (protocol) + 1);
1685 strcpy (workingXLOCAL, protocol);
1688 XLOCAL=(char *)getenv("XLOCAL");
1691 workingXLOCAL=freeXLOCAL=(char *)xalloc (strlen (XLOCAL) + 1);
1693 strcpy (workingXLOCAL, XLOCAL);
1698 TRANS(LocalEndTransports)(void)
1701 PRMSG(3,"LocalEndTransports()\n", 0,0,0 );
1705 #define TYPEBUFSIZE 32
1709 static LOCALtrans2dev *
1710 TRANS(LocalGetNextTransport)(void)
1715 char typebuf[TYPEBUFSIZE];
1716 PRMSG(3,"LocalGetNextTransport()\n", 0,0,0 );
1720 if( workingXLOCAL == NULL || *workingXLOCAL == '\0' )
1723 typetocheck=workingXLOCAL;
1724 workingXLOCAL=strchr(workingXLOCAL,':');
1725 if(workingXLOCAL && *workingXLOCAL)
1726 *workingXLOCAL++='\0';
1728 for(i=0;i<NUMTRANSPORTS;i++)
1731 * This is equivalent to a case insensitive strcmp(),
1732 * but should be more portable.
1734 strncpy(typebuf,typetocheck,TYPEBUFSIZE);
1735 for(j=0;j<TYPEBUFSIZE;j++)
1736 if (isupper(typebuf[j]))
1737 typebuf[j]=tolower(typebuf[j]);
1739 /* Now, see if they match */
1740 if(!strcmp(LOCALtrans2devtab[i].transname,typebuf))
1741 return &LOCALtrans2devtab[i];
1751 #include <sys/utsname.h>
1755 * Make sure 'host' is really local.
1759 HostReallyLocal (char *host)
1763 * The 'host' passed to this function may have been generated
1764 * by either uname() or gethostname(). We try both if possible.
1768 struct utsname name;
1773 if (uname (&name) >= 0 && strcmp (host, name.nodename) == 0)
1778 (void) gethostname (buf, 256);
1781 if (strcmp (host, buf) == 0)
1788 static XtransConnInfo
1789 TRANS(LocalOpenClient)(int type, char *protocol, char *host, char *port)
1792 LOCALtrans2dev *transptr;
1793 XtransConnInfo ciptr;
1796 PRMSG(3,"LocalOpenClient()\n", 0,0,0 );
1799 * Make sure 'host' is really local. If not, we return failure.
1800 * The reason we make this check is because a process may advertise
1801 * a "local" address for which it can accept connections, but if a
1802 * process on a remote machine tries to connect to this address,
1803 * we know for sure it will fail.
1806 if (strcmp (host, "unix") != 0 && !HostReallyLocal (host))
1809 "LocalOpenClient: Cannot connect to non-local host %s\n",
1817 * X has a well known port, that is transport dependant. It is easier
1818 * to handle it here, than try and come up with a transport independent
1819 * representation that can be passed in and resolved the usual way.
1821 * The port that is passed here is really a string containing the idisplay
1822 * from ConnectDisplay(). Since that is what we want for the local transports,
1823 * we don't have to do anything special.
1827 if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL )
1829 PRMSG(1,"LocalOpenClient: calloc(1,%d) failed\n",
1830 sizeof(struct _XtransConnInfo),0,0 );
1836 TRANS(LocalInitTransports)(protocol);
1839 for(transptr=TRANS(LocalGetNextTransport)();
1840 transptr!=NULL;transptr=TRANS(LocalGetNextTransport)(), index++)
1844 case XTRANS_OPEN_COTS_CLIENT:
1845 ciptr->fd=transptr->devcotsopenclient(ciptr,port);
1847 case XTRANS_OPEN_CLTS_CLIENT:
1848 ciptr->fd=transptr->devcltsopenclient(ciptr,port);
1850 case XTRANS_OPEN_COTS_SERVER:
1851 case XTRANS_OPEN_CLTS_SERVER:
1853 "LocalOpenClient: Should not be opening a server with this function\n",
1858 "LocalOpenClient: Unknown Open type %d\n",
1861 if( ciptr->fd >= 0 )
1865 TRANS(LocalEndTransports)();
1873 ciptr->priv=(char *)transptr;
1874 ciptr->index = index;
1879 #endif /* TRANS_CLIENT */
1884 static XtransConnInfo
1885 TRANS(LocalOpenServer)(int type, char *protocol, char *host, char *port)
1889 XtransConnInfo ciptr;
1891 PRMSG(2,"LocalOpenServer(%d,%s,%s)\n", type, protocol, port);
1895 * For X11, the port will be in the format xserverN where N is the
1896 * display number. All of the local connections just need to know
1897 * the display number because they don't do any name resolution on
1898 * the port. This just truncates port to the display portion.
1902 if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL )
1904 PRMSG(1,"LocalOpenServer: calloc(1,%d) failed\n",
1905 sizeof(struct _XtransConnInfo),0,0 );
1909 for(i=1;i<NUMTRANSPORTS;i++)
1911 if( strcmp(protocol,LOCALtrans2devtab[i].transname) != 0 )
1915 case XTRANS_OPEN_COTS_CLIENT:
1916 case XTRANS_OPEN_CLTS_CLIENT:
1918 "LocalOpenServer: Should not be opening a client with this function\n",
1921 case XTRANS_OPEN_COTS_SERVER:
1922 ciptr->fd=LOCALtrans2devtab[i].devcotsopenserver(ciptr,port);
1924 case XTRANS_OPEN_CLTS_SERVER:
1925 ciptr->fd=LOCALtrans2devtab[i].devcltsopenserver(ciptr,port);
1928 PRMSG(1,"LocalOpenServer: Unknown Open type %d\n",
1931 if( ciptr->fd >= 0 ) {
1932 ciptr->priv=(char *)&LOCALtrans2devtab[i];
1934 ciptr->flags = 1 | (ciptr->flags & TRANS_KEEPFLAGS);
1943 #endif /* TRANS_SERVER */
1948 static XtransConnInfo
1949 TRANS(LocalReopenServer)(int type, int index, int fd, char *port)
1952 XtransConnInfo ciptr;
1955 PRMSG(2,"LocalReopenServer(%d,%d,%d)\n", type, index, fd);
1957 if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL )
1959 PRMSG(1,"LocalReopenServer: calloc(1,%d) failed\n",
1960 sizeof(struct _XtransConnInfo),0,0 );
1968 case XTRANS_OPEN_COTS_SERVER:
1969 stat = LOCALtrans2devtab[index].devcotsreopenserver(ciptr,fd,port);
1971 case XTRANS_OPEN_CLTS_SERVER:
1972 stat = LOCALtrans2devtab[index].devcltsreopenserver(ciptr,fd,port);
1975 PRMSG(1,"LocalReopenServer: Unknown Open type %d\n",
1980 ciptr->priv=(char *)&LOCALtrans2devtab[index];
1982 ciptr->flags = 1 | (ciptr->flags & TRANS_KEEPFLAGS);
1990 #endif /* TRANS_REOPEN */
1995 * This is the Local implementation of the X Transport service layer
2000 static XtransConnInfo
2001 TRANS(LocalOpenCOTSClient)(Xtransport *thistrans, char *protocol,
2002 char *host, char *port)
2005 PRMSG(2,"LocalOpenCOTSClient(%s,%s,%s)\n",protocol,host,port);
2007 return TRANS(LocalOpenClient)(XTRANS_OPEN_COTS_CLIENT, protocol, host, port);
2010 #endif /* TRANS_CLIENT */
2015 static XtransConnInfo
2016 TRANS(LocalOpenCOTSServer)(Xtransport *thistrans, char *protocol,
2017 char *host, char *port)
2020 char *typetocheck = NULL;
2022 char typebuf[TYPEBUFSIZE];
2024 PRMSG(2,"LocalOpenCOTSServer(%s,%s,%s)\n",protocol,host,port);
2026 /* Check if this local type is in the XLOCAL list */
2027 TRANS(LocalInitTransports)("local");
2028 typetocheck = workingXLOCAL;
2029 while (typetocheck && !found) {
2032 workingXLOCAL = strchr(workingXLOCAL, ':');
2033 if (workingXLOCAL && *workingXLOCAL)
2034 *workingXLOCAL++ = '\0';
2035 strncpy(typebuf, typetocheck, TYPEBUFSIZE);
2036 for (j = 0; j < TYPEBUFSIZE; j++)
2037 if (isupper(typebuf[j]))
2038 typebuf[j] = tolower(typebuf[j]);
2039 if (!strcmp(thistrans->TransName, typebuf))
2041 typetocheck = workingXLOCAL;
2043 TRANS(LocalEndTransports)();
2046 PRMSG(3,"LocalOpenCOTSServer: disabling %s\n",thistrans->TransName,0,0);
2047 thistrans->flags |= TRANS_DISABLED;
2051 return TRANS(LocalOpenServer)(XTRANS_OPEN_COTS_SERVER, protocol, host, port);
2054 #endif /* TRANS_SERVER */
2059 static XtransConnInfo
2060 TRANS(LocalOpenCLTSClient)(Xtransport *thistrans, char *protocol,
2061 char *host, char *port)
2064 PRMSG(2,"LocalOpenCLTSClient(%s,%s,%s)\n",protocol,host,port);
2066 return TRANS(LocalOpenClient)(XTRANS_OPEN_CLTS_CLIENT, protocol, host, port);
2069 #endif /* TRANS_CLIENT */
2074 static XtransConnInfo
2075 TRANS(LocalOpenCLTSServer)(Xtransport *thistrans, char *protocol,
2076 char *host, char *port)
2079 PRMSG(2,"LocalOpenCLTSServer(%s,%s,%s)\n",protocol,host,port);
2081 return TRANS(LocalOpenServer)(XTRANS_OPEN_CLTS_SERVER, protocol, host, port);
2084 #endif /* TRANS_SERVER */
2089 static XtransConnInfo
2090 TRANS(LocalReopenCOTSServer)(Xtransport *thistrans, int fd, char *port)
2095 PRMSG(2,"LocalReopenCOTSServer(%d,%s)\n", fd, port, 0);
2097 for(index=1;index<NUMTRANSPORTS;index++)
2099 if( strcmp(thistrans->TransName,
2100 LOCALtrans2devtab[index].transname) == 0 )
2104 if (index >= NUMTRANSPORTS)
2109 return TRANS(LocalReopenServer)(XTRANS_OPEN_COTS_SERVER,
2113 static XtransConnInfo
2114 TRANS(LocalReopenCLTSServer)(Xtransport *thistrans, int fd, char *port)
2119 PRMSG(2,"LocalReopenCLTSServer(%d,%s)\n", fd, port, 0);
2121 for(index=1;index<NUMTRANSPORTS;index++)
2123 if( strcmp(thistrans->TransName,
2124 LOCALtrans2devtab[index].transname) == 0 )
2128 if (index >= NUMTRANSPORTS)
2133 return TRANS(LocalReopenServer)(XTRANS_OPEN_CLTS_SERVER,
2137 #endif /* TRANS_REOPEN */
2142 TRANS(LocalSetOption)(XtransConnInfo ciptr, int option, int arg)
2145 PRMSG(2,"LocalSetOption(%d,%d,%d)\n",ciptr->fd,option,arg);
2154 TRANS(LocalCreateListener)(XtransConnInfo ciptr, char *port, unsigned int flags)
2157 PRMSG(2,"LocalCreateListener(%x->%d,%s)\n",ciptr,ciptr->fd,port);
2163 TRANS(LocalResetListener)(XtransConnInfo ciptr)
2166 LOCALtrans2dev *transptr;
2168 PRMSG(2,"LocalResetListener(%x)\n",ciptr,0,0);
2170 transptr=(LOCALtrans2dev *)ciptr->priv;
2171 if (transptr->devreset != NULL) {
2172 return transptr->devreset(ciptr);
2174 return TRANS_RESET_NOOP;
2178 static XtransConnInfo
2179 TRANS(LocalAccept)(XtransConnInfo ciptr, int *status)
2182 XtransConnInfo newciptr;
2183 LOCALtrans2dev *transptr;
2185 PRMSG(2,"LocalAccept(%x->%d)\n", ciptr, ciptr->fd,0);
2187 transptr=(LOCALtrans2dev *)ciptr->priv;
2189 if( (newciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo)))==NULL )
2191 PRMSG(1,"LocalAccept: calloc(1,%d) failed\n",
2192 sizeof(struct _XtransConnInfo),0,0 );
2193 *status = TRANS_ACCEPT_BAD_MALLOC;
2197 newciptr->fd=transptr->devaccept(ciptr,newciptr,status);
2199 if( newciptr->fd < 0 )
2205 newciptr->priv=(char *)transptr;
2206 newciptr->index = ciptr->index;
2213 #endif /* TRANS_SERVER */
2219 TRANS(LocalConnect)(XtransConnInfo ciptr, char *host, char *port)
2222 PRMSG(2,"LocalConnect(%x->%d,%s)\n", ciptr, ciptr->fd, port);
2227 #endif /* TRANS_CLIENT */
2231 TRANS(LocalBytesReadable)(XtransConnInfo ciptr, BytesReadable_t *pend )
2234 PRMSG(2,"LocalBytesReadable(%x->%d,%x)\n", ciptr, ciptr->fd, pend);
2237 return ioctl(ciptr->fd, I_NREAD, (char *)pend);
2239 return ioctl(ciptr->fd, FIONREAD, (char *)pend);
2244 TRANS(LocalRead)(XtransConnInfo ciptr, char *buf, int size)
2247 PRMSG(2,"LocalRead(%d,%x,%d)\n", ciptr->fd, buf, size );
2249 return read(ciptr->fd,buf,size);
2253 TRANS(LocalWrite)(XtransConnInfo ciptr, char *buf, int size)
2256 PRMSG(2,"LocalWrite(%d,%x,%d)\n", ciptr->fd, buf, size );
2258 return write(ciptr->fd,buf,size);
2262 TRANS(LocalReadv)(XtransConnInfo ciptr, struct iovec *buf, int size)
2265 PRMSG(2,"LocalReadv(%d,%x,%d)\n", ciptr->fd, buf, size );
2267 return READV(ciptr,buf,size);
2271 TRANS(LocalWritev)(XtransConnInfo ciptr, struct iovec *buf, int size)
2274 PRMSG(2,"LocalWritev(%d,%x,%d)\n", ciptr->fd, buf, size );
2276 return WRITEV(ciptr,buf,size);
2280 TRANS(LocalDisconnect)(XtransConnInfo ciptr)
2283 PRMSG(2,"LocalDisconnect(%x->%d)\n", ciptr, ciptr->fd, 0);
2289 TRANS(LocalClose)(XtransConnInfo ciptr)
2292 struct sockaddr_un *sockname=(struct sockaddr_un *) ciptr->addr;
2295 PRMSG(2,"LocalClose(%x->%d)\n", ciptr, ciptr->fd ,0);
2297 ret=close(ciptr->fd);
2301 && sockname->sun_family == AF_UNIX
2302 && sockname->sun_path[0] )
2304 if (!(ciptr->flags & TRANS_NOUNLINK))
2305 unlink(sockname->sun_path);
2312 TRANS(LocalCloseForCloning)(XtransConnInfo ciptr)
2317 PRMSG(2,"LocalCloseForCloning(%x->%d)\n", ciptr, ciptr->fd ,0);
2319 /* Don't unlink path */
2321 ret=close(ciptr->fd);
2328 * MakeAllCOTSServerListeners() will go through the entire Xtransports[]
2329 * array defined in Xtrans.c and try to OpenCOTSServer() for each entry.
2330 * We will add duplicate entries to that table so that the OpenCOTSServer()
2331 * function will get called once for each type of local transport.
2333 * The TransName is in lowercase, so it will never match during a normal
2334 * call to SelectTransport() in Xtrans.c.
2338 static char * local_aliases[] = {
2339 # ifdef LOCAL_TRANS_PTS
2344 "pipe", /* compatibility with Solaris Xlib */
2346 # ifdef LOCAL_TRANS_SCO
2352 Xtransport TRANS(LocalFuncs) = {
2353 /* Local Interface */
2355 TRANS_ALIAS | TRANS_LOCAL,
2357 TRANS(LocalOpenCOTSClient),
2358 #endif /* TRANS_CLIENT */
2361 TRANS(LocalOpenCOTSServer),
2362 #endif /* TRANS_SERVER */
2364 TRANS(LocalOpenCLTSClient),
2365 #endif /* TRANS_CLIENT */
2367 TRANS(LocalOpenCLTSServer),
2368 #endif /* TRANS_SERVER */
2370 TRANS(LocalReopenCOTSServer),
2371 TRANS(LocalReopenCLTSServer),
2373 TRANS(LocalSetOption),
2375 TRANS(LocalCreateListener),
2376 TRANS(LocalResetListener),
2378 #endif /* TRANS_SERVER */
2380 TRANS(LocalConnect),
2381 #endif /* TRANS_CLIENT */
2382 TRANS(LocalBytesReadable),
2387 TRANS(LocalDisconnect),
2389 TRANS(LocalCloseForCloning),
2392 #ifdef LOCAL_TRANS_PTS
2394 Xtransport TRANS(PTSFuncs) = {
2395 /* Local Interface */
2399 TRANS(LocalOpenCOTSClient),
2400 #endif /* TRANS_CLIENT */
2403 TRANS(LocalOpenCOTSServer),
2404 #endif /* TRANS_SERVER */
2406 TRANS(LocalOpenCLTSClient),
2407 #endif /* TRANS_CLIENT */
2409 TRANS(LocalOpenCLTSServer),
2410 #endif /* TRANS_SERVER */
2412 TRANS(LocalReopenCOTSServer),
2413 TRANS(LocalReopenCLTSServer),
2415 TRANS(LocalSetOption),
2417 TRANS(LocalCreateListener),
2418 TRANS(LocalResetListener),
2420 #endif /* TRANS_SERVER */
2422 TRANS(LocalConnect),
2423 #endif /* TRANS_CLIENT */
2424 TRANS(LocalBytesReadable),
2429 TRANS(LocalDisconnect),
2431 TRANS(LocalCloseForCloning),
2434 #endif /* LOCAL_TRANS_PTS */
2436 #ifdef LOCAL_TRANS_NAMED
2438 Xtransport TRANS(NAMEDFuncs) = {
2439 /* Local Interface */
2443 TRANS(LocalOpenCOTSClient),
2444 #endif /* TRANS_CLIENT */
2447 TRANS(LocalOpenCOTSServer),
2448 #endif /* TRANS_SERVER */
2450 TRANS(LocalOpenCLTSClient),
2451 #endif /* TRANS_CLIENT */
2453 TRANS(LocalOpenCLTSServer),
2454 #endif /* TRANS_SERVER */
2456 TRANS(LocalReopenCOTSServer),
2457 TRANS(LocalReopenCLTSServer),
2459 TRANS(LocalSetOption),
2461 TRANS(LocalCreateListener),
2462 TRANS(LocalResetListener),
2464 #endif /* TRANS_SERVER */
2466 TRANS(LocalConnect),
2467 #endif /* TRANS_CLIENT */
2468 TRANS(LocalBytesReadable),
2473 TRANS(LocalDisconnect),
2475 TRANS(LocalCloseForCloning),
2479 Xtransport TRANS(PIPEFuncs) = {
2480 /* Local Interface */
2482 TRANS_ALIAS | TRANS_LOCAL,
2484 TRANS(LocalOpenCOTSClient),
2485 #endif /* TRANS_CLIENT */
2488 TRANS(LocalOpenCOTSServer),
2489 #endif /* TRANS_SERVER */
2491 TRANS(LocalOpenCLTSClient),
2492 #endif /* TRANS_CLIENT */
2494 TRANS(LocalOpenCLTSServer),
2495 #endif /* TRANS_SERVER */
2497 TRANS(LocalReopenCOTSServer),
2498 TRANS(LocalReopenCLTSServer),
2500 TRANS(LocalSetOption),
2502 TRANS(LocalCreateListener),
2503 TRANS(LocalResetListener),
2505 #endif /* TRANS_SERVER */
2507 TRANS(LocalConnect),
2508 #endif /* TRANS_CLIENT */
2509 TRANS(LocalBytesReadable),
2514 TRANS(LocalDisconnect),
2516 TRANS(LocalCloseForCloning),
2519 #endif /* LOCAL_TRANS_NAMED */
2522 #ifdef LOCAL_TRANS_SCO
2523 Xtransport TRANS(SCOFuncs) = {
2524 /* Local Interface */
2528 TRANS(LocalOpenCOTSClient),
2529 #endif /* TRANS_CLIENT */
2532 TRANS(LocalOpenCOTSServer),
2533 #endif /* TRANS_SERVER */
2535 TRANS(LocalOpenCLTSClient),
2536 #endif /* TRANS_CLIENT */
2538 TRANS(LocalOpenCLTSServer),
2539 #endif /* TRANS_SERVER */
2541 TRANS(LocalReopenCOTSServer),
2542 TRANS(LocalReopenCLTSServer),
2544 TRANS(LocalSetOption),
2546 TRANS(LocalCreateListener),
2547 TRANS(LocalResetListener),
2549 #endif /* TRANS_SERVER */
2551 TRANS(LocalConnect),
2552 #endif /* TRANS_CLIENT */
2553 TRANS(LocalBytesReadable),
2558 TRANS(LocalDisconnect),
2560 TRANS(LocalCloseForCloning),
2562 #endif /* LOCAL_TRANS_SCO */