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 _X_UNUSED, char *port _X_UNUSED)
135 TRANS(ReopenFail)(XtransConnInfo ciptr _X_UNUSED, int fd _X_UNUSED, char *port _X_UNUSED)
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 = malloc (ciptr->addrlen)) == NULL)
157 prmsg(1,"FillAddrInfo: failed to allocate memory for addr\n");
161 sunaddr->sun_family = AF_UNIX;
163 if (strlen(sun_path) > sizeof(sunaddr->sun_path) - 1) {
164 prmsg(1, "FillAddrInfo: path too long\n");
165 free((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 = malloc (ciptr->peeraddrlen)) == NULL)
180 "FillAddrInfo: failed to allocate memory for peer addr\n");
187 p_sunaddr->sun_family = AF_UNIX;
189 if (strlen(peer_sun_path) > sizeof(p_sunaddr->sun_path) - 1) {
190 prmsg(1, "FillAddrInfo: peer path too long\n");
191 free((char *) p_sunaddr);
194 strcpy (p_sunaddr->sun_path, peer_sun_path);
195 #if defined(BSD44SOCKETS)
196 p_sunaddr->sun_len = strlen (p_sunaddr->sun_path);
199 ciptr->peeraddr = (char *) p_sunaddr;
206 #ifdef LOCAL_TRANS_PTS
209 #if defined(SYSV) && !defined(__SCO__)
212 #define SIGNAL_T void
215 typedef SIGNAL_T (*PFV)();
219 extern char *ptsname(
223 static void _dummy(int sig _X_UNUSED)
227 #endif /* LOCAL_TRANS_PTS */
230 #define X_STREAMS_DIR "/dev/X"
231 #define DEV_SPX "/dev/spx"
234 #define X_STREAMS_DIR "/dev/X"
236 #define X_STREAMS_DIR "/tmp/.X11-pipe"
240 #define DEV_PTMX "/dev/ptmx"
244 #define PTSNODENAME "/dev/X/server."
246 #define NAMEDNODENAME "/tmp/.X11-pipe/X"
248 #define NAMEDNODENAME "/dev/X/Nserver."
250 #define SCORNODENAME "/dev/X%1sR"
251 #define SCOSNODENAME "/dev/X%1sS"
256 #define NAMEDNODENAME "/tmp/.XIM-pipe/XIM"
258 #define PTSNODENAME "/dev/X/XIM."
259 #define NAMEDNODENAME "/dev/X/NXIM."
260 #define SCORNODENAME "/dev/XIM.%sR"
261 #define SCOSNODENAME "/dev/XIM.%sS"
264 #if defined(FS_t) || defined (FONT_t)
266 #define NAMEDNODENAME "/tmp/.font-pipe/fs"
269 * USL has already defined something here. We need to check with them
270 * and see if their choice is usable here.
272 #define PTSNODENAME "/dev/X/fontserver."
273 #define NAMEDNODENAME "/dev/X/Nfontserver."
274 #define SCORNODENAME "/dev/fontserver.%sR"
275 #define SCOSNODENAME "/dev/fontserver.%sS"
280 #define NAMEDNODENAME "/tmp/.ICE-pipe/"
282 #define PTSNODENAME "/dev/X/ICE."
283 #define NAMEDNODENAME "/dev/X/NICE."
284 #define SCORNODENAME "/dev/ICE.%sR"
285 #define SCOSNODENAME "/dev/ICE.%sS"
290 #define NAMEDNODENAME "/tmp/.Test-unix/test"
292 #define PTSNODENAME "/dev/X/transtest."
293 #define NAMEDNODENAME "/dev/X/Ntranstest."
294 #define SCORNODENAME "/dev/transtest.%sR"
295 #define SCOSNODENAME "/dev/transtest.%sS"
300 #ifdef LOCAL_TRANS_PTS
304 TRANS(PTSOpenClient)(XtransConnInfo ciptr, char *port)
308 int fd,server,exitval,alarm_time,ret;
309 char server_path[64];
310 char *slave, namelen;
311 char buf[20]; /* MAX_PATH_LEN?? */
316 prmsg(2,"PTSOpenClient(%s)\n", port);
318 #if !defined(PTSNODENAME)
319 prmsg(1,"PTSOpenClient: Protocol is not supported by a pts connection\n");
322 if (port && *port ) {
323 if( *port == '/' ) { /* A full pathname */
324 snprintf(server_path, sizeof(server_path), "%s", port);
326 snprintf(server_path, sizeof(server_path), "%s%s",
330 snprintf(server_path, sizeof(server_path), "%s%d",
331 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);
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);
358 slave = ptsname(fd); /* get name */
360 if( slave == NULL ) {
361 prmsg(1,"PTSOpenClient: failed to get ptsname()\n");
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);
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");
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");
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);
467 #if !defined(PTSNODENAME)
468 prmsg(1,"PTSOpenServer: Protocol is not supported by a pts connection\n");
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);
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);
500 prmsg(1, "PTSOpenServer: Remove %s if this is incorrect.\n", server_path);
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);
518 if( (slave=ptsname(fd)) == NULL) {
519 prmsg(1, "PTSOpenServer: Unable to get slave device name\n");
524 if( link(slave,server_path) < 0 ) {
525 prmsg(1, "PTSOpenServer: Unable to link %s to %s\n", slave, server_path);
530 if( chmod(server_path, 0666) < 0 ) {
531 prmsg(1, "PTSOpenServer: Unable to chmod %s to 0666\n", server_path);
536 if( (server=open(server_path, O_RDWR)) < 0 ) {
537 prmsg(1, "PTSOpenServer: Unable to open server device %s\n", server_path);
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");
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);
572 if( (in=read(ciptr->fd,&length,1)) <= 0 ){
575 "PTSAccept: Incoming connection closed\n");
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");
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);
604 *status = TRANS_ACCEPT_MISC_ERROR;
611 * Everything looks good: fill in the XtransConnInfo structure.
614 newciptr->addrlen=ciptr->addrlen;
615 if( (newciptr->addr = malloc(newciptr->addrlen)) == NULL ) {
616 prmsg(1,"PTSAccept: failed to allocate memory for peer addr\n");
618 *status = TRANS_ACCEPT_BAD_MALLOC;
622 memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen);
624 newciptr->peeraddrlen=sizeof(struct sockaddr_un);
625 if( (sunaddr = malloc(newciptr->peeraddrlen)) == NULL ) {
626 prmsg(1,"PTSAccept: failed to allocate memory for peer addr\n");
627 free(newciptr->addr);
629 *status = TRANS_ACCEPT_BAD_MALLOC;
633 sunaddr->sun_family=AF_UNIX;
634 strcpy(sunaddr->sun_path,buf);
635 #if defined(BSD44SOCKETS)
636 sunaddr->sun_len=strlen(sunaddr->sun_path);
639 newciptr->peeraddr=(char *)sunaddr;
646 #endif /* TRANS_SERVER */
647 #endif /* LOCAL_TRANS_PTS */
650 #ifdef LOCAL_TRANS_NAMED
657 TRANS(NAMEDOpenClient)(XtransConnInfo ciptr, char *port)
662 char server_path[64];
663 struct stat filestat;
665 extern int isastream(int);
669 prmsg(2,"NAMEDOpenClient(%s)\n", port);
671 #if !defined(NAMEDNODENAME)
672 prmsg(1,"NAMEDOpenClient: Protocol is not supported by a NAMED connection\n");
675 if ( port && *port ) {
676 if( *port == '/' ) { /* A full pathname */
677 (void) snprintf(server_path, sizeof(server_path), "%s", port);
679 (void) snprintf(server_path, sizeof(server_path), "%s%s", NAMEDNODENAME, port);
682 (void) snprintf(server_path, sizeof(server_path), "%s%ld", NAMEDNODENAME, (long)getpid());
685 if ((fd = open(server_path, O_RDWR)) < 0) {
686 prmsg(1,"NAMEDOpenClient: Cannot open %s for NAMED connection\n", server_path);
690 if (fstat(fd, &filestat) < 0 ) {
691 prmsg(1,"NAMEDOpenClient: Cannot stat %s for NAMED connection\n", server_path);
696 if ((filestat.st_mode & S_IFMT) != S_IFIFO) {
697 prmsg(1,"NAMEDOpenClient: Device %s is not a FIFO\n", server_path);
698 /* Is this really a failure? */
704 if (isastream(fd) <= 0) {
705 prmsg(1,"NAMEDOpenClient: %s is not a streams device\n", server_path);
711 * Everything looks good: fill in the XtransConnInfo structure.
714 if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
716 prmsg(1,"NAMEDOpenClient: failed to fill in addr info\n");
723 #endif /* !NAMEDNODENAME */
726 #endif /* TRANS_CLIENT */
734 TRANS(NAMEDOpenPipe)(const char *server_path)
740 prmsg(2,"NAMEDOpenPipe(%s)\n", server_path);
742 #ifdef HAS_STICKY_DIR_BIT
747 if (trans_mkdir(X_STREAMS_DIR, mode) == -1) {
748 prmsg (1, "NAMEDOpenPipe: mkdir(%s) failed, errno = %d\n",
749 X_STREAMS_DIR, errno);
753 if(stat(server_path, &sbuf) != 0) {
754 if (errno == ENOENT) {
755 if ((fd = creat(server_path, (mode_t)0666)) == -1) {
756 prmsg(1, "NAMEDOpenPipe: Can't open %s\n", server_path);
760 if (chmod(server_path, (mode_t)0666) < 0) {
761 prmsg(1, "NAMEDOpenPipe: Can't open %s\n", server_path);
765 prmsg(1, "NAMEDOpenPipe: stat on %s failed\n", server_path);
770 if( pipe(pipefd) != 0) {
771 prmsg(1, "NAMEDOpenPipe: pipe() failed, errno=%d\n",errno);
775 if( ioctl(pipefd[0], I_PUSH, "connld") != 0) {
776 prmsg(1, "NAMEDOpenPipe: ioctl(I_PUSH,\"connld\") failed, errno=%d\n",errno);
782 if( fattach(pipefd[0], server_path) != 0) {
783 prmsg(1, "NAMEDOpenPipe: fattach(%s) failed, errno=%d\n", server_path,errno);
794 TRANS(NAMEDOpenServer)(XtransConnInfo ciptr, char *port)
798 char server_path[64];
801 prmsg(2,"NAMEDOpenServer(%s)\n", port);
803 #if !defined(NAMEDNODENAME)
804 prmsg(1,"NAMEDOpenServer: Protocol is not supported by a NAMED connection\n");
807 if ( port && *port ) {
808 if( *port == '/' ) { /* A full pathname */
809 (void) snprintf(server_path, sizeof(server_path), "%s", port);
811 (void) snprintf(server_path, sizeof(server_path), "%s%s",
812 NAMEDNODENAME, port);
815 (void) snprintf(server_path, sizeof(server_path), "%s%ld",
816 NAMEDNODENAME, (long)getpid());
819 fd = TRANS(NAMEDOpenPipe)(server_path);
825 * Everything looks good: fill in the XtransConnInfo structure.
828 if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
830 prmsg(1,"NAMEDOpenServer: failed to fill in addr info\n");
831 TRANS(LocalClose)(ciptr);
837 #endif /* !NAMEDNODENAME */
841 TRANS(NAMEDResetListener) (XtransConnInfo ciptr)
844 struct sockaddr_un *sockname=(struct sockaddr_un *) ciptr->addr;
847 prmsg(2,"NAMEDResetListener(%p, %d)\n", ciptr, ciptr->fd);
849 if (ciptr->fd != -1) {
851 * see if the pipe has disappeared
854 if (stat (sockname->sun_path, &statb) == -1 ||
855 (statb.st_mode & S_IFMT) != S_IFIFO) {
856 prmsg(3, "Pipe %s trashed, recreating\n", sockname->sun_path);
857 TRANS(LocalClose)(ciptr);
858 ciptr->fd = TRANS(NAMEDOpenPipe)(sockname->sun_path);
860 return TRANS_RESET_NEW_FD;
862 return TRANS_CREATE_LISTENER_FAILED;
865 return TRANS_RESET_NOOP;
869 TRANS(NAMEDAccept)(XtransConnInfo ciptr, XtransConnInfo newciptr, int *status)
872 struct strrecvfd str;
874 prmsg(2,"NAMEDAccept(%p->%d)\n", ciptr, ciptr->fd);
876 if( ioctl(ciptr->fd, I_RECVFD, &str ) < 0 ) {
877 prmsg(1, "NAMEDAccept: ioctl(I_RECVFD) failed, errno=%d\n", errno);
878 *status = TRANS_ACCEPT_MISC_ERROR;
883 * Everything looks good: fill in the XtransConnInfo structure.
885 newciptr->family=ciptr->family;
886 newciptr->addrlen=ciptr->addrlen;
887 if( (newciptr->addr = malloc(newciptr->addrlen)) == NULL ) {
889 "NAMEDAccept: failed to allocate memory for pipe addr\n");
891 *status = TRANS_ACCEPT_BAD_MALLOC;
895 memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen);
897 newciptr->peeraddrlen=newciptr->addrlen;
898 if( (newciptr->peeraddr = malloc(newciptr->peeraddrlen)) == NULL ) {
900 "NAMEDAccept: failed to allocate memory for peer addr\n");
901 free(newciptr->addr);
903 *status = TRANS_ACCEPT_BAD_MALLOC;
907 memcpy(newciptr->peeraddr,newciptr->addr,newciptr->peeraddrlen);
914 #endif /* TRANS_SERVER */
916 #endif /* LOCAL_TRANS_NAMED */
920 #if defined(LOCAL_TRANS_SCO)
923 * connect_spipe is used by the SCO connection type.
926 connect_spipe(int fd1, int fd2)
929 struct strfdinsert sbuf;
931 sbuf.databuf.maxlen = -1;
932 sbuf.databuf.len = -1;
933 sbuf.databuf.buf = NULL;
934 sbuf.ctlbuf.maxlen = sizeof(long);
935 sbuf.ctlbuf.len = sizeof(long);
936 sbuf.ctlbuf.buf = (caddr_t)&temp;
941 if( ioctl(fd1, I_FDINSERT, &sbuf) < 0 )
948 * named_spipe is used by the SCO connection type.
952 named_spipe(int fd, char *path)
960 (void) fstat(fd, &sbuf);
961 ret = mknod(path, 0020666, sbuf.st_rdev);
974 #endif /* defined(LOCAL_TRANS_SCO) */
979 #ifdef LOCAL_TRANS_SCO
983 * 2002-11-09 (jkj@sco.com)
985 * This code has been modified to match what is in the actual SCO X server.
986 * This greatly helps inter-operability between X11R6 and X11R5 (the native
987 * SCO server). Mainly, it relies on streams nodes existing in /dev, not
988 * creating them or unlinking them, which breaks the native X server.
990 * However, this is only for the X protocol. For all other protocols, we
991 * do in fact create the nodes, as only X11R6 will use them, and this makes
992 * it possible to have both types of clients running, otherwise we get all
993 * kinds of nasty errors on startup for anything that doesnt use the X
994 * protocol (like SM, when KDE starts up).
1000 TRANS(SCOOpenClient)(XtransConnInfo ciptr, char *port)
1003 int fd, server, fl, ret;
1004 char server_path[64];
1005 struct strbuf ctlbuf;
1006 unsigned long alarm_time;
1009 extern int getmsg(), putmsg();
1012 prmsg(2,"SCOOpenClient(%s)\n", port);
1013 if (!port || !port[0])
1016 #if !defined(SCORNODENAME)
1017 prmsg(2,"SCOOpenClient: Protocol is not supported by a SCO connection\n");
1020 (void) sprintf(server_path, SCORNODENAME, port);
1022 if ((server = open(server_path, O_RDWR)) < 0) {
1023 prmsg(1,"SCOOpenClient: failed to open %s\n", server_path);
1027 if ((fd = open(DEV_SPX, O_RDWR)) < 0) {
1028 prmsg(1,"SCOOpenClient: failed to open %s\n", DEV_SPX);
1033 (void) write(server, &server, 1);
1035 ctlbuf.maxlen = sizeof(long);
1036 ctlbuf.buf = (caddr_t)&temp;
1039 savef = signal(SIGALRM, _dummy);
1040 alarm_time = alarm(10);
1042 ret = getmsg(server, &ctlbuf, 0, &fl);
1044 (void) alarm(alarm_time);
1045 (void) signal(SIGALRM, savef);
1048 prmsg(1,"SCOOpenClient: error from getmsg\n");
1054 /* The msg we got via getmsg is the result of an
1055 * I_FDINSERT, so if we do a putmsg with whatever
1056 * we recieved, we're doing another I_FDINSERT ...
1058 (void) putmsg(fd, &ctlbuf, 0, 0);
1059 (void) fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,0)|O_NDELAY);
1061 (void) close(server);
1064 * Everything looks good: fill in the XtransConnInfo structure.
1067 #if defined(X11_t) && defined(__SCO__)
1068 ciptr->flags |= TRANS_NOUNLINK;
1070 if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
1072 prmsg(1,"SCOOpenClient: failed to fill addr info\n");
1079 #endif /* !SCORNODENAME */
1082 #endif /* TRANS_CLIENT */
1088 TRANS(SCOOpenServer)(XtransConnInfo ciptr, char *port)
1091 char serverR_path[64];
1092 char serverS_path[64];
1093 struct flock mylock;
1098 prmsg(2,"SCOOpenServer(%s)\n", port);
1099 if (!port || !port[0])
1102 #if !defined(SCORNODENAME)
1103 prmsg(1,"SCOOpenServer: Protocol is not supported by a SCO connection\n");
1106 (void) sprintf(serverR_path, SCORNODENAME, port);
1107 (void) sprintf(serverS_path, SCOSNODENAME, port);
1109 #if !defined(X11_t) || !defined(__SCO__)
1110 unlink(serverR_path);
1111 unlink(serverS_path);
1113 if ((fds = open(DEV_SPX, O_RDWR)) < 0 ||
1114 (fdr = open(DEV_SPX, O_RDWR)) < 0 ) {
1115 prmsg(1,"SCOOpenServer: failed to open %s\n", DEV_SPX);
1123 if (named_spipe (fds, serverS_path) == -1) {
1124 prmsg(1,"SCOOpenServer: failed to create %s\n", serverS_path);
1130 if (named_spipe (fdr, serverR_path) == -1) {
1131 prmsg(1,"SCOOpenServer: failed to create %s\n", serverR_path);
1138 fds = open (serverS_path, O_RDWR | O_NDELAY);
1140 prmsg(1,"SCOOpenServer: failed to open %s\n", serverS_path);
1145 * Lock the connection device for the duration of the server.
1146 * This resolves multiple server starts especially on SMP machines.
1148 mylock.l_type = F_WRLCK;
1149 mylock.l_whence = 0;
1152 if (fcntl (fds, F_SETLK, &mylock) < 0) {
1153 prmsg(1,"SCOOpenServer: failed to lock %s\n", serverS_path);
1158 fdr = open (serverR_path, O_RDWR | O_NDELAY);
1160 prmsg(1,"SCOOpenServer: failed to open %s\n", serverR_path);
1166 if (connect_spipe(fds, fdr)) {
1167 prmsg(1,"SCOOpenServer: ioctl(I_FDINSERT) failed on %s\n",
1175 * Everything looks good: fill in the XtransConnInfo structure.
1178 #if defined(X11_t) && defined(__SCO__)
1179 ciptr->flags |= TRANS_NOUNLINK;
1181 if (TRANS(FillAddrInfo) (ciptr, serverS_path, serverR_path) == 0) {
1182 prmsg(1,"SCOOpenServer: failed to fill in addr info\n");
1190 #endif /* !SCORNODENAME */
1194 TRANS(SCOAccept)(XtransConnInfo ciptr, XtransConnInfo newciptr, int *status)
1199 prmsg(2,"SCOAccept(%d)\n", ciptr->fd);
1201 if (read(ciptr->fd, &c, 1) < 0) {
1202 prmsg(1,"SCOAccept: can't read from client\n");
1203 *status = TRANS_ACCEPT_MISC_ERROR;
1207 if( (fd = open(DEV_SPX, O_RDWR)) < 0 ) {
1208 prmsg(1,"SCOAccept: can't open \"%s\"\n",DEV_SPX);
1209 *status = TRANS_ACCEPT_MISC_ERROR;
1213 if (connect_spipe (ciptr->fd, fd) < 0) {
1214 prmsg(1,"SCOAccept: ioctl(I_FDINSERT) failed\n");
1216 *status = TRANS_ACCEPT_MISC_ERROR;
1221 * Everything looks good: fill in the XtransConnInfo structure.
1224 newciptr->addrlen=ciptr->addrlen;
1225 if( (newciptr->addr = malloc(newciptr->addrlen)) == NULL ) {
1227 "SCOAccept: failed to allocate memory for peer addr\n");
1229 *status = TRANS_ACCEPT_BAD_MALLOC;
1233 memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen);
1234 #if defined(__SCO__)
1235 newciptr->flags |= TRANS_NOUNLINK;
1238 newciptr->peeraddrlen=newciptr->addrlen;
1239 if( (newciptr->peeraddr = malloc(newciptr->peeraddrlen)) == NULL ) {
1241 "SCOAccept: failed to allocate memory for peer addr\n");
1242 free(newciptr->addr);
1244 *status = TRANS_ACCEPT_BAD_MALLOC;
1248 memcpy(newciptr->peeraddr,newciptr->addr,newciptr->peeraddrlen);
1255 #endif /* TRANS_SERVER */
1256 #endif /* LOCAL_TRANS_SCO */
1261 #ifdef LOCAL_TRANS_PTS
1264 TRANS(PTSReopenServer)(XtransConnInfo ciptr, int fd, char *port)
1268 char server_path[64];
1271 prmsg(2,"PTSReopenServer(%d,%s)\n", fd, port);
1273 #if !defined(PTSNODENAME)
1274 prmsg(1,"PTSReopenServer: Protocol is not supported by a pts connection\n");
1277 if (port && *port ) {
1278 if( *port == '/' ) { /* A full pathname */
1279 snprintf(server_path, sizeof(server_path), "%s", port);
1281 snprintf(server_path, sizeof(server_path), "%s%s",
1285 snprintf(server_path, sizeof(server_path), "%s%ld",
1286 PTSNODENAME, (long)getpid());
1289 if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
1291 prmsg(1,"PTSReopenServer: failed to fill in addr info\n");
1297 #endif /* !PTSNODENAME */
1300 #endif /* LOCAL_TRANS_PTS */
1302 #ifdef LOCAL_TRANS_NAMED
1305 TRANS(NAMEDReopenServer)(XtransConnInfo ciptr, int fd _X_UNUSED, char *port)
1308 #ifdef NAMEDNODENAME
1309 char server_path[64];
1312 prmsg(2,"NAMEDReopenServer(%s)\n", port);
1314 #if !defined(NAMEDNODENAME)
1315 prmsg(1,"NAMEDReopenServer: Protocol is not supported by a NAMED connection\n");
1318 if ( port && *port ) {
1319 if( *port == '/' ) { /* A full pathname */
1320 snprintf(server_path, sizeof(server_path),"%s", port);
1322 snprintf(server_path, sizeof(server_path), "%s%s",
1323 NAMEDNODENAME, port);
1326 snprintf(server_path, sizeof(server_path), "%s%ld",
1327 NAMEDNODENAME, (long)getpid());
1330 if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
1332 prmsg(1,"NAMEDReopenServer: failed to fill in addr info\n");
1338 #endif /* !NAMEDNODENAME */
1341 #endif /* LOCAL_TRANS_NAMED */
1344 #ifdef LOCAL_TRANS_SCO
1346 TRANS(SCOReopenServer)(XtransConnInfo ciptr, int fd, char *port)
1350 char serverR_path[64], serverS_path[64];
1353 prmsg(2,"SCOReopenServer(%s)\n", port);
1354 if (!port || !port[0])
1357 #if !defined(SCORNODENAME)
1358 prmsg(2,"SCOReopenServer: Protocol is not supported by a SCO connection\n");
1361 (void) sprintf(serverR_path, SCORNODENAME, port);
1362 (void) sprintf(serverS_path, SCOSNODENAME, port);
1364 #if defined(X11_t) && defined(__SCO__)
1365 ciptr->flags |= TRANS_NOUNLINK;
1367 if (TRANS(FillAddrInfo) (ciptr, serverS_path, serverR_path) == 0)
1369 prmsg(1, "SCOReopenServer: failed to fill in addr info\n");
1375 #endif /* SCORNODENAME */
1378 #endif /* LOCAL_TRANS_SCO */
1380 #endif /* TRANS_REOPEN */
1385 * This table contains all of the entry points for the different local
1386 * connection mechanisms.
1389 typedef struct _LOCALtrans2dev {
1390 const char *transname;
1394 int (*devcotsopenclient)(
1395 XtransConnInfo, char * /*port*/
1398 #endif /* TRANS_CLIENT */
1402 int (*devcotsopenserver)(
1403 XtransConnInfo, char * /*port*/
1406 #endif /* TRANS_SERVER */
1410 int (*devcltsopenclient)(
1411 XtransConnInfo, char * /*port*/
1414 #endif /* TRANS_CLIENT */
1418 int (*devcltsopenserver)(
1419 XtransConnInfo, char * /*port*/
1422 #endif /* TRANS_SERVER */
1426 int (*devcotsreopenserver)(
1432 int (*devcltsreopenserver)(
1438 #endif /* TRANS_REOPEN */
1443 XtransConnInfo /* ciptr */
1447 XtransConnInfo, XtransConnInfo, int *
1450 #endif /* TRANS_SERVER */
1454 static LOCALtrans2dev LOCALtrans2devtab[] = {
1455 #ifdef LOCAL_TRANS_PTS
1458 TRANS(PTSOpenClient),
1459 #endif /* TRANS_CLIENT */
1461 TRANS(PTSOpenServer),
1462 #endif /* TRANS_SERVER */
1465 #endif /* TRANS_CLIENT */
1468 #endif /* TRANS_SERVER */
1470 TRANS(PTSReopenServer),
1474 NULL, /* ResetListener */
1476 #endif /* TRANS_SERVER */
1481 TRANS(PTSOpenClient),
1482 #endif /* TRANS_CLIENT */
1484 TRANS(PTSOpenServer),
1485 #endif /* TRANS_SERVER */
1488 #endif /* TRANS_CLIENT */
1491 #endif /* TRANS_SERVER */
1493 TRANS(PTSReopenServer),
1497 NULL, /* ResetListener */
1499 #endif /* TRANS_SERVER */
1504 TRANS(PTSOpenClient),
1505 #endif /* TRANS_CLIENT */
1507 TRANS(PTSOpenServer),
1508 #endif /* TRANS_SERVER */
1511 #endif /* TRANS_CLIENT */
1514 #endif /* TRANS_SERVER */
1516 TRANS(PTSReopenServer),
1520 NULL, /* ResetListener */
1522 #endif /* TRANS_SERVER */
1524 #else /* !LOCAL_TRANS_PTS */
1527 TRANS(NAMEDOpenClient),
1528 #endif /* TRANS_CLIENT */
1530 TRANS(NAMEDOpenServer),
1531 #endif /* TRANS_SERVER */
1534 #endif /* TRANS_CLIENT */
1537 #endif /* TRANS_SERVER */
1539 TRANS(NAMEDReopenServer),
1543 TRANS(NAMEDResetListener),
1545 #endif /* TRANS_SERVER */
1550 TRANS(NAMEDOpenClient),
1551 #endif /* TRANS_CLIENT */
1553 TRANS(NAMEDOpenServer),
1554 #endif /* TRANS_SERVER */
1557 #endif /* TRANS_CLIENT */
1560 #endif /* TRANS_SERVER */
1562 TRANS(NAMEDReopenServer),
1566 TRANS(NAMEDResetListener),
1568 #endif /* TRANS_SERVER */
1570 #endif /* !LOCAL_TRANS_PTS */
1572 #ifdef LOCAL_TRANS_NAMED
1575 TRANS(NAMEDOpenClient),
1576 #endif /* TRANS_CLIENT */
1578 TRANS(NAMEDOpenServer),
1579 #endif /* TRANS_SERVER */
1582 #endif /* TRANS_CLIENT */
1585 #endif /* TRANS_SERVER */
1587 TRANS(NAMEDReopenServer),
1591 TRANS(NAMEDResetListener),
1593 #endif /* TRANS_SERVER */
1596 #ifdef sun /* Alias "pipe" to named, since that's what Solaris called it */
1599 TRANS(NAMEDOpenClient),
1600 #endif /* TRANS_CLIENT */
1602 TRANS(NAMEDOpenServer),
1603 #endif /* TRANS_SERVER */
1606 #endif /* TRANS_CLIENT */
1609 #endif /* TRANS_SERVER */
1611 TRANS(NAMEDReopenServer),
1615 TRANS(NAMEDResetListener),
1617 #endif /* TRANS_SERVER */
1620 #endif /* LOCAL_TRANS_NAMED */
1623 #ifdef LOCAL_TRANS_SCO
1626 TRANS(SCOOpenClient),
1627 #endif /* TRANS_CLIENT */
1629 TRANS(SCOOpenServer),
1630 #endif /* TRANS_SERVER */
1633 #endif /* TRANS_CLIENT */
1636 #endif /* TRANS_SERVER */
1638 TRANS(SCOReopenServer),
1642 NULL, /* ResetListener */
1644 #endif /* TRANS_SERVER */
1646 #endif /* LOCAL_TRANS_SCO */
1649 #define NUMTRANSPORTS (sizeof(LOCALtrans2devtab)/sizeof(LOCALtrans2dev))
1651 static const char *XLOCAL=NULL;
1652 static char *workingXLOCAL=NULL;
1653 static char *freeXLOCAL=NULL;
1655 #if defined(__SCO__)
1656 #define DEF_XLOCAL "SCO:UNIX:PTS"
1657 #elif defined(__UNIXWARE__)
1658 #define DEF_XLOCAL "UNIX:PTS:NAMED:SCO"
1660 #define DEF_XLOCAL "UNIX:NAMED"
1662 #define DEF_XLOCAL "UNIX:PTS:NAMED:SCO"
1666 TRANS(LocalInitTransports)(const char *protocol)
1669 prmsg(3,"LocalInitTransports(%s)\n", protocol);
1671 if( strcmp(protocol,"local") && strcmp(protocol,"LOCAL") )
1673 workingXLOCAL = freeXLOCAL = strdup (protocol);
1676 XLOCAL=(char *)getenv("XLOCAL");
1679 workingXLOCAL = freeXLOCAL = strdup (XLOCAL);
1684 TRANS(LocalEndTransports)(void)
1687 prmsg(3,"LocalEndTransports()\n");
1691 #define TYPEBUFSIZE 32
1695 static LOCALtrans2dev *
1696 TRANS(LocalGetNextTransport)(void)
1701 char typebuf[TYPEBUFSIZE];
1702 prmsg(3,"LocalGetNextTransport()\n");
1706 if( workingXLOCAL == NULL || *workingXLOCAL == '\0' )
1709 typetocheck=workingXLOCAL;
1710 workingXLOCAL=strchr(workingXLOCAL,':');
1711 if(workingXLOCAL && *workingXLOCAL)
1712 *workingXLOCAL++='\0';
1714 for(i=0;i<NUMTRANSPORTS;i++)
1717 * This is equivalent to a case insensitive strcmp(),
1718 * but should be more portable.
1720 strncpy(typebuf,typetocheck,TYPEBUFSIZE);
1721 for(j=0;j<TYPEBUFSIZE;j++)
1722 if (isupper(typebuf[j]))
1723 typebuf[j]=tolower(typebuf[j]);
1725 /* Now, see if they match */
1726 if(!strcmp(LOCALtrans2devtab[i].transname,typebuf))
1727 return &LOCALtrans2devtab[i];
1737 #include <sys/utsname.h>
1741 * Make sure 'host' is really local.
1745 HostReallyLocal (char *host)
1749 * The 'host' passed to this function may have been generated
1750 * by either uname() or gethostname(). We try both if possible.
1754 struct utsname name;
1759 if (uname (&name) >= 0 && strcmp (host, name.nodename) == 0)
1764 (void) gethostname (buf, 256);
1767 if (strcmp (host, buf) == 0)
1774 static XtransConnInfo
1775 TRANS(LocalOpenClient)(int type, char *protocol, char *host, char *port)
1778 LOCALtrans2dev *transptr;
1779 XtransConnInfo ciptr;
1782 prmsg(3,"LocalOpenClient()\n");
1785 * Make sure 'host' is really local. If not, we return failure.
1786 * The reason we make this check is because a process may advertise
1787 * a "local" address for which it can accept connections, but if a
1788 * process on a remote machine tries to connect to this address,
1789 * we know for sure it will fail.
1792 if (strcmp (host, "unix") != 0 && !HostReallyLocal (host))
1795 "LocalOpenClient: Cannot connect to non-local host %s\n",
1803 * X has a well known port, that is transport dependant. It is easier
1804 * to handle it here, than try and come up with a transport independent
1805 * representation that can be passed in and resolved the usual way.
1807 * The port that is passed here is really a string containing the idisplay
1808 * from ConnectDisplay(). Since that is what we want for the local transports,
1809 * we don't have to do anything special.
1813 if( (ciptr = calloc(1,sizeof(struct _XtransConnInfo))) == NULL )
1815 prmsg(1,"LocalOpenClient: calloc(1,%lu) failed\n",
1816 sizeof(struct _XtransConnInfo));
1822 TRANS(LocalInitTransports)(protocol);
1825 for(transptr=TRANS(LocalGetNextTransport)();
1826 transptr!=NULL;transptr=TRANS(LocalGetNextTransport)(), index++)
1830 case XTRANS_OPEN_COTS_CLIENT:
1831 ciptr->fd=transptr->devcotsopenclient(ciptr,port);
1833 case XTRANS_OPEN_CLTS_CLIENT:
1834 ciptr->fd=transptr->devcltsopenclient(ciptr,port);
1836 case XTRANS_OPEN_COTS_SERVER:
1837 case XTRANS_OPEN_CLTS_SERVER:
1839 "LocalOpenClient: Should not be opening a server with this function\n");
1843 "LocalOpenClient: Unknown Open type %d\n",
1846 if( ciptr->fd >= 0 )
1850 TRANS(LocalEndTransports)();
1858 ciptr->priv=(char *)transptr;
1859 ciptr->index = index;
1864 #endif /* TRANS_CLIENT */
1869 static XtransConnInfo
1870 TRANS(LocalOpenServer)(int type, char *protocol, char *host _X_UNUSED, char *port)
1874 XtransConnInfo ciptr;
1876 prmsg(2,"LocalOpenServer(%d,%s,%s)\n", type, protocol, port);
1880 * For X11, the port will be in the format xserverN where N is the
1881 * display number. All of the local connections just need to know
1882 * the display number because they don't do any name resolution on
1883 * the port. This just truncates port to the display portion.
1887 if( (ciptr = calloc(1,sizeof(struct _XtransConnInfo))) == NULL )
1889 prmsg(1,"LocalOpenServer: calloc(1,%lu) failed\n",
1890 sizeof(struct _XtransConnInfo));
1894 for(i=1;i<NUMTRANSPORTS;i++)
1896 if( strcmp(protocol,LOCALtrans2devtab[i].transname) != 0 )
1900 case XTRANS_OPEN_COTS_CLIENT:
1901 case XTRANS_OPEN_CLTS_CLIENT:
1903 "LocalOpenServer: Should not be opening a client with this function\n");
1905 case XTRANS_OPEN_COTS_SERVER:
1906 ciptr->fd=LOCALtrans2devtab[i].devcotsopenserver(ciptr,port);
1908 case XTRANS_OPEN_CLTS_SERVER:
1909 ciptr->fd=LOCALtrans2devtab[i].devcltsopenserver(ciptr,port);
1912 prmsg(1,"LocalOpenServer: Unknown Open type %d\n",
1915 if( ciptr->fd >= 0 ) {
1916 ciptr->priv=(char *)&LOCALtrans2devtab[i];
1918 ciptr->flags = 1 | (ciptr->flags & TRANS_KEEPFLAGS);
1927 #endif /* TRANS_SERVER */
1932 static XtransConnInfo
1933 TRANS(LocalReopenServer)(int type, int index, int fd, char *port)
1936 XtransConnInfo ciptr;
1939 prmsg(2,"LocalReopenServer(%d,%d,%d)\n", type, index, fd);
1941 if( (ciptr = calloc(1,sizeof(struct _XtransConnInfo))) == NULL )
1943 prmsg(1,"LocalReopenServer: calloc(1,%lu) failed\n",
1944 sizeof(struct _XtransConnInfo));
1952 case XTRANS_OPEN_COTS_SERVER:
1953 stat = LOCALtrans2devtab[index].devcotsreopenserver(ciptr,fd,port);
1955 case XTRANS_OPEN_CLTS_SERVER:
1956 stat = LOCALtrans2devtab[index].devcltsreopenserver(ciptr,fd,port);
1959 prmsg(1,"LocalReopenServer: Unknown Open type %d\n",
1964 ciptr->priv=(char *)&LOCALtrans2devtab[index];
1966 ciptr->flags = 1 | (ciptr->flags & TRANS_KEEPFLAGS);
1974 #endif /* TRANS_REOPEN */
1979 * This is the Local implementation of the X Transport service layer
1984 static XtransConnInfo
1985 TRANS(LocalOpenCOTSClient)(Xtransport *thistrans _X_UNUSED, char *protocol,
1986 char *host, char *port)
1989 prmsg(2,"LocalOpenCOTSClient(%s,%s,%s)\n",protocol,host,port);
1991 return TRANS(LocalOpenClient)(XTRANS_OPEN_COTS_CLIENT, protocol, host, port);
1994 #endif /* TRANS_CLIENT */
1999 static XtransConnInfo
2000 TRANS(LocalOpenCOTSServer)(Xtransport *thistrans, char *protocol,
2001 char *host, char *port)
2004 char *typetocheck = NULL;
2006 char typebuf[TYPEBUFSIZE];
2008 prmsg(2,"LocalOpenCOTSServer(%s,%s,%s)\n",protocol,host,port);
2010 /* Check if this local type is in the XLOCAL list */
2011 TRANS(LocalInitTransports)("local");
2012 typetocheck = workingXLOCAL;
2013 while (typetocheck && !found) {
2016 workingXLOCAL = strchr(workingXLOCAL, ':');
2017 if (workingXLOCAL && *workingXLOCAL)
2018 *workingXLOCAL++ = '\0';
2019 strncpy(typebuf, typetocheck, TYPEBUFSIZE);
2020 for (j = 0; j < TYPEBUFSIZE; j++)
2021 if (isupper(typebuf[j]))
2022 typebuf[j] = tolower(typebuf[j]);
2023 if (!strcmp(thistrans->TransName, typebuf))
2025 typetocheck = workingXLOCAL;
2027 TRANS(LocalEndTransports)();
2030 prmsg(3,"LocalOpenCOTSServer: disabling %s\n",thistrans->TransName);
2031 thistrans->flags |= TRANS_DISABLED;
2035 return TRANS(LocalOpenServer)(XTRANS_OPEN_COTS_SERVER, protocol, host, port);
2038 #endif /* TRANS_SERVER */
2043 static XtransConnInfo
2044 TRANS(LocalOpenCLTSClient)(Xtransport *thistrans _X_UNUSED, char *protocol,
2045 char *host, char *port)
2048 prmsg(2,"LocalOpenCLTSClient(%s,%s,%s)\n",protocol,host,port);
2050 return TRANS(LocalOpenClient)(XTRANS_OPEN_CLTS_CLIENT, protocol, host, port);
2053 #endif /* TRANS_CLIENT */
2058 static XtransConnInfo
2059 TRANS(LocalOpenCLTSServer)(Xtransport *thistrans _X_UNUSED, char *protocol,
2060 char *host, char *port)
2063 prmsg(2,"LocalOpenCLTSServer(%s,%s,%s)\n",protocol,host,port);
2065 return TRANS(LocalOpenServer)(XTRANS_OPEN_CLTS_SERVER, protocol, host, port);
2068 #endif /* TRANS_SERVER */
2073 static XtransConnInfo
2074 TRANS(LocalReopenCOTSServer)(Xtransport *thistrans, int fd, char *port)
2079 prmsg(2,"LocalReopenCOTSServer(%d,%s)\n", fd, port);
2081 for(index=1;index<NUMTRANSPORTS;index++)
2083 if( strcmp(thistrans->TransName,
2084 LOCALtrans2devtab[index].transname) == 0 )
2088 if (index >= NUMTRANSPORTS)
2093 return TRANS(LocalReopenServer)(XTRANS_OPEN_COTS_SERVER,
2097 static XtransConnInfo
2098 TRANS(LocalReopenCLTSServer)(Xtransport *thistrans, int fd, char *port)
2103 prmsg(2,"LocalReopenCLTSServer(%d,%s)\n", fd, port);
2105 for(index=1;index<NUMTRANSPORTS;index++)
2107 if( strcmp(thistrans->TransName,
2108 LOCALtrans2devtab[index].transname) == 0 )
2112 if (index >= NUMTRANSPORTS)
2117 return TRANS(LocalReopenServer)(XTRANS_OPEN_CLTS_SERVER,
2121 #endif /* TRANS_REOPEN */
2126 TRANS(LocalSetOption)(XtransConnInfo ciptr, int option, int arg)
2129 prmsg(2,"LocalSetOption(%d,%d,%d)\n",ciptr->fd,option,arg);
2138 TRANS(LocalCreateListener)(XtransConnInfo ciptr, char *port, unsigned int flags _X_UNUSED)
2141 prmsg(2,"LocalCreateListener(%p->%d,%s)\n",ciptr,ciptr->fd,port);
2147 TRANS(LocalResetListener)(XtransConnInfo ciptr)
2150 LOCALtrans2dev *transptr;
2152 prmsg(2,"LocalResetListener(%p)\n",ciptr);
2154 transptr=(LOCALtrans2dev *)ciptr->priv;
2155 if (transptr->devreset != NULL) {
2156 return transptr->devreset(ciptr);
2158 return TRANS_RESET_NOOP;
2162 static XtransConnInfo
2163 TRANS(LocalAccept)(XtransConnInfo ciptr, int *status)
2166 XtransConnInfo newciptr;
2167 LOCALtrans2dev *transptr;
2169 prmsg(2,"LocalAccept(%p->%d)\n", ciptr, ciptr->fd);
2171 transptr=(LOCALtrans2dev *)ciptr->priv;
2173 if( (newciptr = calloc(1,sizeof(struct _XtransConnInfo)))==NULL )
2175 prmsg(1,"LocalAccept: calloc(1,%lu) failed\n",
2176 sizeof(struct _XtransConnInfo));
2177 *status = TRANS_ACCEPT_BAD_MALLOC;
2181 newciptr->fd=transptr->devaccept(ciptr,newciptr,status);
2183 if( newciptr->fd < 0 )
2189 newciptr->priv=(char *)transptr;
2190 newciptr->index = ciptr->index;
2197 #endif /* TRANS_SERVER */
2203 TRANS(LocalConnect)(XtransConnInfo ciptr, char *host _X_UNUSED, char *port)
2206 prmsg(2,"LocalConnect(%p->%d,%s)\n", ciptr, ciptr->fd, port);
2211 #endif /* TRANS_CLIENT */
2215 TRANS(LocalBytesReadable)(XtransConnInfo ciptr, BytesReadable_t *pend )
2218 prmsg(2,"LocalBytesReadable(%p->%d,%p)\n", ciptr, ciptr->fd, pend);
2221 return ioctl(ciptr->fd, I_NREAD, (char *)pend);
2223 return ioctl(ciptr->fd, FIONREAD, (char *)pend);
2228 TRANS(LocalRead)(XtransConnInfo ciptr, char *buf, int size)
2231 prmsg(2,"LocalRead(%d,%p,%d)\n", ciptr->fd, buf, size );
2233 return read(ciptr->fd,buf,size);
2237 TRANS(LocalWrite)(XtransConnInfo ciptr, char *buf, int size)
2240 prmsg(2,"LocalWrite(%d,%p,%d)\n", ciptr->fd, buf, size );
2242 return write(ciptr->fd,buf,size);
2246 TRANS(LocalReadv)(XtransConnInfo ciptr, struct iovec *buf, int size)
2249 prmsg(2,"LocalReadv(%d,%p,%d)\n", ciptr->fd, buf, size );
2251 return READV(ciptr,buf,size);
2255 TRANS(LocalWritev)(XtransConnInfo ciptr, struct iovec *buf, int size)
2258 prmsg(2,"LocalWritev(%d,%p,%d)\n", ciptr->fd, buf, size );
2260 return WRITEV(ciptr,buf,size);
2264 TRANS(LocalDisconnect)(XtransConnInfo ciptr)
2267 prmsg(2,"LocalDisconnect(%p->%d)\n", ciptr, ciptr->fd);
2273 TRANS(LocalClose)(XtransConnInfo ciptr)
2276 struct sockaddr_un *sockname=(struct sockaddr_un *) ciptr->addr;
2279 prmsg(2,"LocalClose(%p->%d)\n", ciptr, ciptr->fd );
2281 ret=close(ciptr->fd);
2285 && sockname->sun_family == AF_UNIX
2286 && sockname->sun_path[0] )
2288 if (!(ciptr->flags & TRANS_NOUNLINK))
2289 unlink(sockname->sun_path);
2296 TRANS(LocalCloseForCloning)(XtransConnInfo ciptr)
2301 prmsg(2,"LocalCloseForCloning(%p->%d)\n", ciptr, ciptr->fd );
2303 /* Don't unlink path */
2305 ret=close(ciptr->fd);
2312 * MakeAllCOTSServerListeners() will go through the entire Xtransports[]
2313 * array defined in Xtrans.c and try to OpenCOTSServer() for each entry.
2314 * We will add duplicate entries to that table so that the OpenCOTSServer()
2315 * function will get called once for each type of local transport.
2317 * The TransName is in lowercase, so it will never match during a normal
2318 * call to SelectTransport() in Xtrans.c.
2322 static const char * local_aliases[] = {
2323 # ifdef LOCAL_TRANS_PTS
2328 "pipe", /* compatibility with Solaris Xlib */
2330 # ifdef LOCAL_TRANS_SCO
2336 Xtransport TRANS(LocalFuncs) = {
2337 /* Local Interface */
2339 TRANS_ALIAS | TRANS_LOCAL,
2341 TRANS(LocalOpenCOTSClient),
2342 #endif /* TRANS_CLIENT */
2345 TRANS(LocalOpenCOTSServer),
2346 #endif /* TRANS_SERVER */
2348 TRANS(LocalOpenCLTSClient),
2349 #endif /* TRANS_CLIENT */
2351 TRANS(LocalOpenCLTSServer),
2352 #endif /* TRANS_SERVER */
2354 TRANS(LocalReopenCOTSServer),
2355 TRANS(LocalReopenCLTSServer),
2357 TRANS(LocalSetOption),
2359 TRANS(LocalCreateListener),
2360 TRANS(LocalResetListener),
2362 #endif /* TRANS_SERVER */
2364 TRANS(LocalConnect),
2365 #endif /* TRANS_CLIENT */
2366 TRANS(LocalBytesReadable),
2371 TRANS(LocalDisconnect),
2373 TRANS(LocalCloseForCloning),
2376 #ifdef LOCAL_TRANS_PTS
2378 Xtransport TRANS(PTSFuncs) = {
2379 /* Local Interface */
2383 TRANS(LocalOpenCOTSClient),
2384 #endif /* TRANS_CLIENT */
2387 TRANS(LocalOpenCOTSServer),
2388 #endif /* TRANS_SERVER */
2390 TRANS(LocalOpenCLTSClient),
2391 #endif /* TRANS_CLIENT */
2393 TRANS(LocalOpenCLTSServer),
2394 #endif /* TRANS_SERVER */
2396 TRANS(LocalReopenCOTSServer),
2397 TRANS(LocalReopenCLTSServer),
2399 TRANS(LocalSetOption),
2401 TRANS(LocalCreateListener),
2402 TRANS(LocalResetListener),
2404 #endif /* TRANS_SERVER */
2406 TRANS(LocalConnect),
2407 #endif /* TRANS_CLIENT */
2408 TRANS(LocalBytesReadable),
2413 TRANS(LocalDisconnect),
2415 TRANS(LocalCloseForCloning),
2418 #endif /* LOCAL_TRANS_PTS */
2420 #ifdef LOCAL_TRANS_NAMED
2422 Xtransport TRANS(NAMEDFuncs) = {
2423 /* Local Interface */
2427 TRANS(LocalOpenCOTSClient),
2428 #endif /* TRANS_CLIENT */
2431 TRANS(LocalOpenCOTSServer),
2432 #endif /* TRANS_SERVER */
2434 TRANS(LocalOpenCLTSClient),
2435 #endif /* TRANS_CLIENT */
2437 TRANS(LocalOpenCLTSServer),
2438 #endif /* TRANS_SERVER */
2440 TRANS(LocalReopenCOTSServer),
2441 TRANS(LocalReopenCLTSServer),
2443 TRANS(LocalSetOption),
2445 TRANS(LocalCreateListener),
2446 TRANS(LocalResetListener),
2448 #endif /* TRANS_SERVER */
2450 TRANS(LocalConnect),
2451 #endif /* TRANS_CLIENT */
2452 TRANS(LocalBytesReadable),
2457 TRANS(LocalDisconnect),
2459 TRANS(LocalCloseForCloning),
2463 Xtransport TRANS(PIPEFuncs) = {
2464 /* Local Interface */
2466 TRANS_ALIAS | TRANS_LOCAL,
2468 TRANS(LocalOpenCOTSClient),
2469 #endif /* TRANS_CLIENT */
2472 TRANS(LocalOpenCOTSServer),
2473 #endif /* TRANS_SERVER */
2475 TRANS(LocalOpenCLTSClient),
2476 #endif /* TRANS_CLIENT */
2478 TRANS(LocalOpenCLTSServer),
2479 #endif /* TRANS_SERVER */
2481 TRANS(LocalReopenCOTSServer),
2482 TRANS(LocalReopenCLTSServer),
2484 TRANS(LocalSetOption),
2486 TRANS(LocalCreateListener),
2487 TRANS(LocalResetListener),
2489 #endif /* TRANS_SERVER */
2491 TRANS(LocalConnect),
2492 #endif /* TRANS_CLIENT */
2493 TRANS(LocalBytesReadable),
2498 TRANS(LocalDisconnect),
2500 TRANS(LocalCloseForCloning),
2503 #endif /* LOCAL_TRANS_NAMED */
2506 #ifdef LOCAL_TRANS_SCO
2507 Xtransport TRANS(SCOFuncs) = {
2508 /* Local Interface */
2512 TRANS(LocalOpenCOTSClient),
2513 #endif /* TRANS_CLIENT */
2516 TRANS(LocalOpenCOTSServer),
2517 #endif /* TRANS_SERVER */
2519 TRANS(LocalOpenCLTSClient),
2520 #endif /* TRANS_CLIENT */
2522 TRANS(LocalOpenCLTSServer),
2523 #endif /* TRANS_SERVER */
2525 TRANS(LocalReopenCOTSServer),
2526 TRANS(LocalReopenCLTSServer),
2528 TRANS(LocalSetOption),
2530 TRANS(LocalCreateListener),
2531 TRANS(LocalResetListener),
2533 #endif /* TRANS_SERVER */
2535 TRANS(LocalConnect),
2536 #endif /* TRANS_CLIENT */
2537 TRANS(LocalBytesReadable),
2542 TRANS(LocalDisconnect),
2544 TRANS(LocalCloseForCloning),
2546 #endif /* LOCAL_TRANS_SCO */