Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:26:38

0001 /*
0002 
0003 Copyright 1993, 1994, 1998  The Open Group
0004 
0005 Permission to use, copy, modify, distribute, and sell this software and its
0006 documentation for any purpose is hereby granted without fee, provided that
0007 the above copyright notice appear in all copies and that both that
0008 copyright notice and this permission notice appear in supporting
0009 documentation.
0010 
0011 The above copyright notice and this permission notice shall be included
0012 in all copies or substantial portions of the Software.
0013 
0014 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
0015 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
0016 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
0017 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020 OTHER DEALINGS IN THE SOFTWARE.
0021 
0022 Except as contained in this notice, the name of The Open Group shall
0023 not be used in advertising or otherwise to promote the sale, use or
0024 other dealings in this Software without prior written authorization
0025 from The Open Group.
0026 
0027  * Copyright 1993, 1994 NCR Corporation - Dayton, Ohio, USA
0028  *
0029  * All Rights Reserved
0030  *
0031  * Permission to use, copy, modify, and distribute this software and its
0032  * documentation for any purpose and without fee is hereby granted, provided
0033  * that the above copyright notice appear in all copies and that both that
0034  * copyright notice and this permission notice appear in supporting
0035  * documentation, and that the name NCR not be used in advertising
0036  * or publicity pertaining to distribution of the software without specific,
0037  * written prior permission.  NCR makes no representations about the
0038  * suitability of this software for any purpose.  It is provided "as is"
0039  * without express or implied warranty.
0040  *
0041  * NCR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
0042  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
0043  * NO EVENT SHALL NCR BE LIABLE FOR ANY SPECIAL, INDIRECT OR
0044  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
0045  * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
0046  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
0047  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
0048  */
0049 
0050 /*
0051  *
0052  * The connection code/ideas in lib/X and server/os for SVR4/Intel
0053  * environments was contributed by the following companies/groups:
0054  *
0055  *  MetroLink Inc
0056  *  NCR
0057  *  Pittsburgh Powercomputing Corporation (PPc)/Quarterdeck Office Systems
0058  *  SGCS
0059  *  Unix System Laboratories (USL) / Novell
0060  *  XFree86
0061  *
0062  * The goal is to have common connection code among all SVR4/Intel vendors.
0063  *
0064  * ALL THE ABOVE COMPANIES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
0065  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
0066  * IN NO EVENT SHALL THESE COMPANIES * BE LIABLE FOR ANY SPECIAL, INDIRECT
0067  * OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
0068  * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
0069  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
0070  * OR PERFORMANCE OF THIS SOFTWARE.
0071  */
0072 
0073 #include <errno.h>
0074 #include <ctype.h>
0075 #include <sys/signal.h>
0076 #include <sys/ioctl.h>
0077 #include <sys/stat.h>
0078 #if defined(SVR4) || defined(__SVR4)
0079 #include <sys/filio.h>
0080 #endif
0081 # include <stropts.h>
0082 #include <sys/wait.h>
0083 #include <sys/types.h>
0084 
0085 /*
0086  * The local transports should be treated the same as a UNIX domain socket
0087  * wrt authentication, etc. Because of this, we will use struct sockaddr_un
0088  * for the address format. This will simplify the code in other places like
0089  * The X Server.
0090  */
0091 
0092 #include <sys/socket.h>
0093 #ifndef X_NO_SYS_UN
0094 #include <sys/un.h>
0095 #endif
0096 
0097 
0098 /* Types of local connections supported:
0099  *  - PTS
0100  *  - named pipes
0101  */
0102 #if defined(SVR4) || defined(__SVR4)
0103 # define LOCAL_TRANS_NAMED
0104 #endif
0105 
0106 static int TRANS(LocalClose)(XtransConnInfo ciptr);
0107 
0108 /*
0109  * These functions actually implement the local connection mechanisms.
0110  */
0111 
0112 /* Type Not Supported */
0113 
0114 static int
0115 TRANS(OpenFail)(XtransConnInfo ciptr _X_UNUSED, const char *port _X_UNUSED)
0116 
0117 {
0118     return -1;
0119 }
0120 
0121 #ifdef TRANS_REOPEN
0122 
0123 static int
0124 TRANS(ReopenFail)(XtransConnInfo ciptr _X_UNUSED, int fd _X_UNUSED,
0125                   const char *port _X_UNUSED)
0126 
0127 {
0128     return 0;
0129 }
0130 
0131 #endif /* TRANS_REOPEN */
0132 
0133 #if XTRANS_SEND_FDS
0134 static int
0135 TRANS(LocalRecvFdInvalid)(XtransConnInfo ciptr)
0136 {
0137     errno = EINVAL;
0138     return -1;
0139 }
0140 
0141 static int
0142 TRANS(LocalSendFdInvalid)(XtransConnInfo ciptr, int fd, int do_close)
0143 {
0144     errno = EINVAL;
0145     return -1;
0146 }
0147 #endif
0148 
0149 
0150 static int
0151 TRANS(FillAddrInfo)(XtransConnInfo ciptr,
0152                     const char *sun_path, const char *peer_sun_path)
0153 
0154 {
0155     struct sockaddr_un  *sunaddr;
0156     struct sockaddr_un  *p_sunaddr;
0157 
0158     ciptr->family = AF_UNIX;
0159     ciptr->addrlen = sizeof (struct sockaddr_un);
0160 
0161     if ((sunaddr = malloc (ciptr->addrlen)) == NULL)
0162     {
0163     prmsg(1,"FillAddrInfo: failed to allocate memory for addr\n");
0164     return 0;
0165     }
0166 
0167     sunaddr->sun_family = AF_UNIX;
0168 
0169     if (strlen(sun_path) > sizeof(sunaddr->sun_path) - 1) {
0170     prmsg(1, "FillAddrInfo: path too long\n");
0171     free((char *) sunaddr);
0172     return 0;
0173     }
0174     strcpy (sunaddr->sun_path, sun_path);
0175 #if defined(BSD44SOCKETS)
0176     sunaddr->sun_len = strlen (sunaddr->sun_path);
0177 #endif
0178 
0179     ciptr->addr = (char *) sunaddr;
0180 
0181     ciptr->peeraddrlen = sizeof (struct sockaddr_un);
0182 
0183     if ((p_sunaddr = malloc (ciptr->peeraddrlen)) == NULL)
0184     {
0185     prmsg(1,
0186        "FillAddrInfo: failed to allocate memory for peer addr\n");
0187     free (sunaddr);
0188     ciptr->addr = NULL;
0189 
0190     return 0;
0191     }
0192 
0193     p_sunaddr->sun_family = AF_UNIX;
0194 
0195     if (strlen(peer_sun_path) > sizeof(p_sunaddr->sun_path) - 1) {
0196     prmsg(1, "FillAddrInfo: peer path too long\n");
0197     free((char *) p_sunaddr);
0198     return 0;
0199     }
0200     strcpy (p_sunaddr->sun_path, peer_sun_path);
0201 #if defined(BSD44SOCKETS)
0202     p_sunaddr->sun_len = strlen (p_sunaddr->sun_path);
0203 #endif
0204 
0205     ciptr->peeraddr = (char *) p_sunaddr;
0206 
0207     return 1;
0208 }
0209 
0210 
0211 
0212 
0213 #ifndef X11_t
0214 #define X_STREAMS_DIR   "/dev/X"
0215 #else
0216 #define X_STREAMS_DIR   "/tmp/.X11-pipe"
0217 #endif
0218 
0219 #define DEV_PTMX    "/dev/ptmx"
0220 
0221 #if defined(X11_t)
0222 
0223 #define NAMEDNODENAME "/tmp/.X11-pipe/X"
0224 #endif
0225 #if defined(XIM_t)
0226 #define NAMEDNODENAME "/tmp/.XIM-pipe/XIM"
0227 #endif
0228 #if defined(FS_t) || defined (FONT_t)
0229 #define NAMEDNODENAME   "/tmp/.font-pipe/fs"
0230 #endif
0231 #if defined(ICE_t)
0232 #define NAMEDNODENAME   "/tmp/.ICE-pipe/"
0233 #endif
0234 
0235 
0236 
0237 
0238 
0239 #ifdef LOCAL_TRANS_NAMED
0240 
0241 /* NAMED */
0242 
0243 #ifdef TRANS_CLIENT
0244 
0245 static int
0246 TRANS(NAMEDOpenClient)(XtransConnInfo ciptr, const char *port)
0247 
0248 {
0249 #ifdef NAMEDNODENAME
0250     int         fd;
0251     char        server_path[64];
0252     struct stat     filestat;
0253 #endif
0254 
0255     prmsg(2,"NAMEDOpenClient(%s)\n", port);
0256 
0257 #if !defined(NAMEDNODENAME)
0258     prmsg(1,"NAMEDOpenClient: Protocol is not supported by a NAMED connection\n");
0259     return -1;
0260 #else
0261     if ( port && *port ) {
0262     if( *port == '/' ) { /* A full pathname */
0263         (void) snprintf(server_path, sizeof(server_path), "%s", port);
0264         } else {
0265         (void) snprintf(server_path, sizeof(server_path), "%s%s", NAMEDNODENAME, port);
0266         }
0267     } else {
0268     (void) snprintf(server_path, sizeof(server_path), "%s%ld", NAMEDNODENAME, (long)getpid());
0269     }
0270 
0271     if ((fd = open(server_path, O_RDWR)) < 0) {
0272     prmsg(1,"NAMEDOpenClient: Cannot open %s for NAMED connection\n", server_path);
0273     return -1;
0274     }
0275 
0276     if (fstat(fd, &filestat) < 0 ) {
0277     prmsg(1,"NAMEDOpenClient: Cannot stat %s for NAMED connection\n", server_path);
0278     (void) close(fd);
0279     return -1;
0280     }
0281 
0282     if ((filestat.st_mode & S_IFMT) != S_IFIFO) {
0283     prmsg(1,"NAMEDOpenClient: Device %s is not a FIFO\n", server_path);
0284     /* Is this really a failure? */
0285     (void) close(fd);
0286     return -1;
0287     }
0288 
0289 
0290     if (isastream(fd) <= 0) {
0291     prmsg(1,"NAMEDOpenClient: %s is not a streams device\n", server_path);
0292     (void) close(fd);
0293     return -1;
0294     }
0295 
0296     /*
0297      * Everything looks good: fill in the XtransConnInfo structure.
0298      */
0299 
0300     if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
0301     {
0302     prmsg(1,"NAMEDOpenClient: failed to fill in addr info\n");
0303     close(fd);
0304     return -1;
0305     }
0306 
0307     return(fd);
0308 
0309 #endif /* !NAMEDNODENAME */
0310 }
0311 
0312 #endif /* TRANS_CLIENT */
0313 
0314 
0315 #ifdef TRANS_SERVER
0316 
0317 
0318 #ifdef NAMEDNODENAME
0319 static int
0320 TRANS(NAMEDOpenPipe)(const char *server_path)
0321 {
0322     int         fd, pipefd[2];
0323     struct stat     sbuf;
0324     int         mode;
0325 
0326     prmsg(2,"NAMEDOpenPipe(%s)\n", server_path);
0327 
0328 #ifdef HAS_STICKY_DIR_BIT
0329     mode = 01777;
0330 #else
0331     mode = 0777;
0332 #endif
0333     if (trans_mkdir(X_STREAMS_DIR, mode) == -1) {
0334     prmsg (1, "NAMEDOpenPipe: mkdir(%s) failed, errno = %d\n",
0335            X_STREAMS_DIR, errno);
0336     return(-1);
0337     }
0338 
0339     if(stat(server_path, &sbuf) != 0) {
0340     if (errno == ENOENT) {
0341         if ((fd = creat(server_path, (mode_t)0666)) == -1) {
0342         prmsg(1, "NAMEDOpenPipe: Can't open %s\n", server_path);
0343         return(-1);
0344         }
0345         if (fchmod(fd, (mode_t)0666) < 0) {
0346         prmsg(1, "NAMEDOpenPipe: Can't chmod %s\n", server_path);
0347         close(fd);
0348         return(-1);
0349         }
0350         close(fd);
0351     } else {
0352         prmsg(1, "NAMEDOpenPipe: stat on %s failed\n", server_path);
0353         return(-1);
0354     }
0355     }
0356 
0357     if( pipe(pipefd) != 0) {
0358     prmsg(1, "NAMEDOpenPipe: pipe() failed, errno=%d\n",errno);
0359     return(-1);
0360     }
0361 
0362     if( ioctl(pipefd[0], I_PUSH, "connld") != 0) {
0363     prmsg(1, "NAMEDOpenPipe: ioctl(I_PUSH,\"connld\") failed, errno=%d\n",errno);
0364     close(pipefd[0]);
0365     close(pipefd[1]);
0366     return(-1);
0367     }
0368 
0369     if( fattach(pipefd[0], server_path) != 0) {
0370     prmsg(1, "NAMEDOpenPipe: fattach(%s) failed, errno=%d\n", server_path,errno);
0371     close(pipefd[0]);
0372     close(pipefd[1]);
0373     return(-1);
0374     }
0375 
0376     return(pipefd[1]);
0377 }
0378 #endif
0379 
0380 static int
0381 TRANS(NAMEDOpenServer)(XtransConnInfo ciptr, const char *port)
0382 {
0383 #ifdef NAMEDNODENAME
0384     int         fd;
0385     char        server_path[64];
0386 #endif
0387 
0388     prmsg(2,"NAMEDOpenServer(%s)\n", port);
0389 
0390 #if !defined(NAMEDNODENAME)
0391     prmsg(1,"NAMEDOpenServer: Protocol is not supported by a NAMED connection\n");
0392     return -1;
0393 #else
0394     if ( port && *port ) {
0395     if( *port == '/' ) { /* A full pathname */
0396         (void) snprintf(server_path, sizeof(server_path), "%s", port);
0397     } else {
0398         (void) snprintf(server_path, sizeof(server_path), "%s%s",
0399                 NAMEDNODENAME, port);
0400     }
0401     } else {
0402     (void) snprintf(server_path, sizeof(server_path), "%s%ld",
0403                NAMEDNODENAME, (long)getpid());
0404     }
0405 
0406     fd = TRANS(NAMEDOpenPipe)(server_path);
0407     if (fd < 0) {
0408     return -1;
0409     }
0410 
0411     /*
0412      * Everything looks good: fill in the XtransConnInfo structure.
0413      */
0414 
0415     if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
0416     {
0417     prmsg(1,"NAMEDOpenServer: failed to fill in addr info\n");
0418     TRANS(LocalClose)(ciptr);
0419     return -1;
0420     }
0421 
0422     return fd;
0423 
0424 #endif /* !NAMEDNODENAME */
0425 }
0426 
0427 static int
0428 TRANS(NAMEDResetListener) (XtransConnInfo ciptr)
0429 
0430 {
0431   struct sockaddr_un      *sockname=(struct sockaddr_un *) ciptr->addr;
0432   struct stat     statb;
0433 
0434   prmsg(2,"NAMEDResetListener(%p, %d)\n", ciptr, ciptr->fd);
0435 
0436   if (ciptr->fd != -1) {
0437     /*
0438      * see if the pipe has disappeared
0439      */
0440 
0441     if (stat (sockname->sun_path, &statb) == -1 ||
0442     (statb.st_mode & S_IFMT) != S_IFIFO) {
0443       prmsg(3, "Pipe %s trashed, recreating\n", sockname->sun_path);
0444       TRANS(LocalClose)(ciptr);
0445       ciptr->fd = TRANS(NAMEDOpenPipe)(sockname->sun_path);
0446       if (ciptr->fd >= 0)
0447       return TRANS_RESET_NEW_FD;
0448       else
0449       return TRANS_CREATE_LISTENER_FAILED;
0450     }
0451   }
0452   return TRANS_RESET_NOOP;
0453 }
0454 
0455 static int
0456 TRANS(NAMEDAccept)(XtransConnInfo ciptr, XtransConnInfo newciptr, int *status)
0457 
0458 {
0459     struct strrecvfd str;
0460 
0461     prmsg(2,"NAMEDAccept(%p->%d)\n", ciptr, ciptr->fd);
0462 
0463     if( ioctl(ciptr->fd, I_RECVFD, &str ) < 0 ) {
0464     prmsg(1, "NAMEDAccept: ioctl(I_RECVFD) failed, errno=%d\n", errno);
0465     *status = TRANS_ACCEPT_MISC_ERROR;
0466     return(-1);
0467     }
0468 
0469     /*
0470      * Everything looks good: fill in the XtransConnInfo structure.
0471      */
0472     newciptr->family=ciptr->family;
0473     newciptr->addrlen=ciptr->addrlen;
0474     if( (newciptr->addr = malloc(newciptr->addrlen)) == NULL ) {
0475     prmsg(1,
0476           "NAMEDAccept: failed to allocate memory for pipe addr\n");
0477     close(str.fd);
0478     *status = TRANS_ACCEPT_BAD_MALLOC;
0479     return -1;
0480     }
0481 
0482     memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen);
0483 
0484     newciptr->peeraddrlen=newciptr->addrlen;
0485     if( (newciptr->peeraddr = malloc(newciptr->peeraddrlen)) == NULL ) {
0486     prmsg(1,
0487     "NAMEDAccept: failed to allocate memory for peer addr\n");
0488     free(newciptr->addr);
0489     close(str.fd);
0490     *status = TRANS_ACCEPT_BAD_MALLOC;
0491     return -1;
0492     }
0493 
0494     memcpy(newciptr->peeraddr,newciptr->addr,newciptr->peeraddrlen);
0495 
0496     *status = 0;
0497 
0498     return str.fd;
0499 }
0500 
0501 #endif /* TRANS_SERVER */
0502 
0503 #endif /* LOCAL_TRANS_NAMED */
0504 
0505 
0506 
0507 
0508 
0509 
0510 
0511 
0512 
0513 
0514 #ifdef TRANS_REOPEN
0515 
0516 #ifdef LOCAL_TRANS_NAMED
0517 
0518 static int
0519 TRANS(NAMEDReopenServer)(XtransConnInfo ciptr, int fd _X_UNUSED, const char *port)
0520 
0521 {
0522 #ifdef NAMEDNODENAME
0523     char server_path[64];
0524 #endif
0525 
0526     prmsg(2,"NAMEDReopenServer(%s)\n", port);
0527 
0528 #if !defined(NAMEDNODENAME)
0529     prmsg(1,"NAMEDReopenServer: Protocol is not supported by a NAMED connection\n");
0530     return 0;
0531 #else
0532     if ( port && *port ) {
0533     if( *port == '/' ) { /* A full pathname */
0534         snprintf(server_path, sizeof(server_path),"%s", port);
0535     } else {
0536         snprintf(server_path, sizeof(server_path), "%s%s",
0537              NAMEDNODENAME, port);
0538     }
0539     } else {
0540     snprintf(server_path, sizeof(server_path), "%s%ld",
0541         NAMEDNODENAME, (long)getpid());
0542     }
0543 
0544     if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
0545     {
0546     prmsg(1,"NAMEDReopenServer: failed to fill in addr info\n");
0547     return 0;
0548     }
0549 
0550     return 1;
0551 
0552 #endif /* !NAMEDNODENAME */
0553 }
0554 
0555 #endif /* LOCAL_TRANS_NAMED */
0556 
0557 
0558 
0559 #endif /* TRANS_REOPEN */
0560 
0561 
0562 
0563 /*
0564  * This table contains all of the entry points for the different local
0565  * connection mechanisms.
0566  */
0567 
0568 typedef struct _LOCALtrans2dev {
0569     const char  *transname;
0570 
0571 #ifdef TRANS_CLIENT
0572 
0573     int (*devcotsopenclient)(
0574     XtransConnInfo, const char * /*port*/
0575 );
0576 
0577 #endif /* TRANS_CLIENT */
0578 
0579 #ifdef TRANS_SERVER
0580 
0581     int (*devcotsopenserver)(
0582     XtransConnInfo, const char * /*port*/
0583 );
0584 
0585 #endif /* TRANS_SERVER */
0586 
0587 #ifdef TRANS_CLIENT
0588 
0589     int (*devcltsopenclient)(
0590     XtransConnInfo, const char * /*port*/
0591 );
0592 
0593 #endif /* TRANS_CLIENT */
0594 
0595 #ifdef TRANS_SERVER
0596 
0597     int (*devcltsopenserver)(
0598     XtransConnInfo, const char * /*port*/
0599 );
0600 
0601 #endif /* TRANS_SERVER */
0602 
0603 #ifdef TRANS_REOPEN
0604 
0605     int (*devcotsreopenserver)(
0606     XtransConnInfo,
0607     int,    /* fd */
0608     const char *    /* port */
0609 );
0610 
0611     int (*devcltsreopenserver)(
0612     XtransConnInfo,
0613     int,    /* fd */
0614     const char *    /* port */
0615 );
0616 
0617 #endif /* TRANS_REOPEN */
0618 
0619 #ifdef TRANS_SERVER
0620 
0621     int (*devreset)(
0622     XtransConnInfo /* ciptr */
0623 );
0624 
0625     int (*devaccept)(
0626     XtransConnInfo, XtransConnInfo, int *
0627 );
0628 
0629 #endif /* TRANS_SERVER */
0630 
0631 } LOCALtrans2dev;
0632 
0633 static LOCALtrans2dev LOCALtrans2devtab[] = {
0634 {"",
0635 #ifdef TRANS_CLIENT
0636      TRANS(NAMEDOpenClient),
0637 #endif /* TRANS_CLIENT */
0638 #ifdef TRANS_SERVER
0639      TRANS(NAMEDOpenServer),
0640 #endif /* TRANS_SERVER */
0641 #ifdef TRANS_CLIENT
0642      TRANS(OpenFail),
0643 #endif /* TRANS_CLIENT */
0644 #ifdef TRANS_SERVER
0645      TRANS(OpenFail),
0646 #endif /* TRANS_SERVER */
0647 #ifdef TRANS_REOPEN
0648      TRANS(NAMEDReopenServer),
0649      TRANS(ReopenFail),
0650 #endif
0651 #ifdef TRANS_SERVER
0652      TRANS(NAMEDResetListener),
0653      TRANS(NAMEDAccept)
0654 #endif /* TRANS_SERVER */
0655 },
0656 
0657 {"local",
0658 #ifdef TRANS_CLIENT
0659      TRANS(NAMEDOpenClient),
0660 #endif /* TRANS_CLIENT */
0661 #ifdef TRANS_SERVER
0662      TRANS(NAMEDOpenServer),
0663 #endif /* TRANS_SERVER */
0664 #ifdef TRANS_CLIENT
0665      TRANS(OpenFail),
0666 #endif /* TRANS_CLIENT */
0667 #ifdef TRANS_SERVER
0668      TRANS(OpenFail),
0669 #endif /* TRANS_SERVER */
0670 #ifdef TRANS_REOPEN
0671      TRANS(NAMEDReopenServer),
0672      TRANS(ReopenFail),
0673 #endif
0674 #ifdef TRANS_SERVER
0675      TRANS(NAMEDResetListener),
0676      TRANS(NAMEDAccept)
0677 #endif /* TRANS_SERVER */
0678 },
0679 
0680 #ifdef LOCAL_TRANS_NAMED
0681 {"named",
0682 #ifdef TRANS_CLIENT
0683      TRANS(NAMEDOpenClient),
0684 #endif /* TRANS_CLIENT */
0685 #ifdef TRANS_SERVER
0686      TRANS(NAMEDOpenServer),
0687 #endif /* TRANS_SERVER */
0688 #ifdef TRANS_CLIENT
0689      TRANS(OpenFail),
0690 #endif /* TRANS_CLIENT */
0691 #ifdef TRANS_SERVER
0692      TRANS(OpenFail),
0693 #endif /* TRANS_SERVER */
0694 #ifdef TRANS_REOPEN
0695      TRANS(NAMEDReopenServer),
0696      TRANS(ReopenFail),
0697 #endif
0698 #ifdef TRANS_SERVER
0699      TRANS(NAMEDResetListener),
0700      TRANS(NAMEDAccept)
0701 #endif /* TRANS_SERVER */
0702 },
0703 
0704 {"pipe",
0705 #ifdef TRANS_CLIENT
0706      TRANS(NAMEDOpenClient),
0707 #endif /* TRANS_CLIENT */
0708 #ifdef TRANS_SERVER
0709      TRANS(NAMEDOpenServer),
0710 #endif /* TRANS_SERVER */
0711 #ifdef TRANS_CLIENT
0712      TRANS(OpenFail),
0713 #endif /* TRANS_CLIENT */
0714 #ifdef TRANS_SERVER
0715      TRANS(OpenFail),
0716 #endif /* TRANS_SERVER */
0717 #ifdef TRANS_REOPEN
0718      TRANS(NAMEDReopenServer),
0719      TRANS(ReopenFail),
0720 #endif
0721 #ifdef TRANS_SERVER
0722      TRANS(NAMEDResetListener),
0723      TRANS(NAMEDAccept)
0724 #endif /* TRANS_SERVER */
0725 },
0726 #endif /* LOCAL_TRANS_NAMED */
0727 
0728 
0729 };
0730 
0731 #define NUMTRANSPORTS   (sizeof(LOCALtrans2devtab)/sizeof(LOCALtrans2dev))
0732 
0733 static const char   *XLOCAL=NULL;
0734 static  char    *workingXLOCAL=NULL;
0735 static  char    *freeXLOCAL=NULL;
0736 
0737 #define DEF_XLOCAL "UNIX:NAMED"
0738 
0739 static void
0740 TRANS(LocalInitTransports)(const char *protocol)
0741 
0742 {
0743     prmsg(3,"LocalInitTransports(%s)\n", protocol);
0744 
0745     if( strcmp(protocol,"local") && strcmp(protocol,"LOCAL") )
0746     {
0747     workingXLOCAL = freeXLOCAL = strdup (protocol);
0748     }
0749     else {
0750     XLOCAL = getenv("XLOCAL");
0751     if(XLOCAL==NULL)
0752         XLOCAL=DEF_XLOCAL;
0753     workingXLOCAL = freeXLOCAL = strdup (XLOCAL);
0754     }
0755 }
0756 
0757 static void
0758 TRANS(LocalEndTransports)(void)
0759 
0760 {
0761     prmsg(3,"LocalEndTransports()\n");
0762     free(freeXLOCAL);
0763     freeXLOCAL = NULL;
0764 }
0765 
0766 #define TYPEBUFSIZE 32
0767 
0768 #ifdef TRANS_CLIENT
0769 
0770 static LOCALtrans2dev *
0771 TRANS(LocalGetNextTransport)(void)
0772 
0773 {
0774     char    *typetocheck;
0775     prmsg(3,"LocalGetNextTransport()\n");
0776 
0777     while(1)
0778     {
0779     if( workingXLOCAL == NULL || *workingXLOCAL == '\0' )
0780         return NULL;
0781 
0782     typetocheck=workingXLOCAL;
0783     workingXLOCAL=strchr(workingXLOCAL,':');
0784     if(workingXLOCAL && *workingXLOCAL)
0785         *workingXLOCAL++='\0';
0786 
0787     for (unsigned int i = 0; i < NUMTRANSPORTS; i++)
0788     {
0789 #ifndef HAVE_STRCASECMP
0790         int     j;
0791         char    typebuf[TYPEBUFSIZE];
0792         /*
0793          * This is equivalent to a case insensitive strcmp(),
0794          * but should be more portable.
0795          */
0796         strncpy(typebuf,typetocheck,TYPEBUFSIZE);
0797         for(j=0;j<TYPEBUFSIZE;j++)
0798         if (isupper(typebuf[j]))
0799             typebuf[j]=tolower(typebuf[j]);
0800 
0801         /* Now, see if they match */
0802         if(!strcmp(LOCALtrans2devtab[i].transname,typebuf))
0803 #else
0804         if(!strcasecmp(LOCALtrans2devtab[i].transname,typetocheck))
0805 #endif
0806         return &LOCALtrans2devtab[i];
0807     }
0808     }
0809 #if 0
0810     /*NOTREACHED*/
0811     return NULL;
0812 #endif
0813 }
0814 
0815 #ifdef NEED_UTSNAME
0816 #include <sys/utsname.h>
0817 #endif
0818 
0819 /*
0820  * Make sure 'host' is really local.
0821  */
0822 
0823 static int
0824 HostReallyLocal (const char *host)
0825 
0826 {
0827     /*
0828      * The 'host' passed to this function may have been generated
0829      * by either uname() or gethostname().  We try both if possible.
0830      */
0831 
0832 #ifdef NEED_UTSNAME
0833     struct utsname name;
0834 #endif
0835     char buf[256];
0836 
0837 #ifdef NEED_UTSNAME
0838     if (uname (&name) >= 0 && strcmp (host, name.nodename) == 0)
0839     return (1);
0840 #endif
0841 
0842     buf[0] = '\0';
0843     (void) gethostname (buf, 256);
0844     buf[255] = '\0';
0845 
0846     if (strcmp (host, buf) == 0)
0847     return (1);
0848 
0849     return (0);
0850 }
0851 
0852 
0853 static XtransConnInfo
0854 TRANS(LocalOpenClient)(int type, const char *protocol,
0855                        const char *host, const char *port)
0856 
0857 {
0858     LOCALtrans2dev *transptr;
0859     XtransConnInfo ciptr;
0860     int index;
0861 
0862     prmsg(3,"LocalOpenClient()\n");
0863 
0864     /*
0865      * Make sure 'host' is really local.  If not, we return failure.
0866      * The reason we make this check is because a process may advertise
0867      * a "local" address for which it can accept connections, but if a
0868      * process on a remote machine tries to connect to this address,
0869      * we know for sure it will fail.
0870      */
0871 
0872     if (strcmp (host, "unix") != 0 && !HostReallyLocal (host))
0873     {
0874     prmsg (1,
0875        "LocalOpenClient: Cannot connect to non-local host %s\n",
0876            host);
0877     return NULL;
0878     }
0879 
0880 
0881 #if defined(X11_t)
0882     /*
0883      * X has a well known port, that is transport dependent. It is easier
0884      * to handle it here, than try and come up with a transport independent
0885      * representation that can be passed in and resolved the usual way.
0886      *
0887      * The port that is passed here is really a string containing the idisplay
0888      * from ConnectDisplay(). Since that is what we want for the local transports,
0889      * we don't have to do anything special.
0890      */
0891 #endif /* X11_t */
0892 
0893     if( (ciptr = calloc(1,sizeof(struct _XtransConnInfo))) == NULL )
0894     {
0895     prmsg(1,"LocalOpenClient: calloc(1,%lu) failed\n",
0896           sizeof(struct _XtransConnInfo));
0897     return NULL;
0898     }
0899 
0900     ciptr->fd = -1;
0901 
0902     TRANS(LocalInitTransports)(protocol);
0903 
0904     index = 0;
0905     for(transptr=TRANS(LocalGetNextTransport)();
0906     transptr!=NULL;transptr=TRANS(LocalGetNextTransport)(), index++)
0907     {
0908     switch( type )
0909     {
0910     case XTRANS_OPEN_COTS_CLIENT:
0911         ciptr->fd=transptr->devcotsopenclient(ciptr,port);
0912         break;
0913     case XTRANS_OPEN_COTS_SERVER:
0914         prmsg(1,
0915           "LocalOpenClient: Should not be opening a server with this function\n");
0916         break;
0917     default:
0918         prmsg(1,
0919           "LocalOpenClient: Unknown Open type %d\n",
0920           type);
0921     }
0922     if( ciptr->fd >= 0 )
0923         break;
0924     }
0925 
0926     TRANS(LocalEndTransports)();
0927 
0928     if( ciptr->fd < 0 )
0929     {
0930     free(ciptr);
0931     return NULL;
0932     }
0933 
0934     ciptr->priv=(char *)transptr;
0935     ciptr->index = index;
0936 
0937     return ciptr;
0938 }
0939 
0940 #endif /* TRANS_CLIENT */
0941 
0942 
0943 #ifdef TRANS_SERVER
0944 
0945 static XtransConnInfo
0946 TRANS(LocalOpenServer)(int type, const char *protocol,
0947                        const char *host _X_UNUSED, const char *port)
0948 
0949 {
0950     XtransConnInfo ciptr;
0951 
0952     prmsg(2,"LocalOpenServer(%d,%s,%s)\n", type, protocol, port);
0953 
0954 #if defined(X11_t)
0955     /*
0956      * For X11, the port will be in the format xserverN where N is the
0957      * display number. All of the local connections just need to know
0958      * the display number because they don't do any name resolution on
0959      * the port. This just truncates port to the display portion.
0960      */
0961 #endif /* X11_t */
0962 
0963     if( (ciptr = calloc(1,sizeof(struct _XtransConnInfo))) == NULL )
0964     {
0965     prmsg(1,"LocalOpenServer: calloc(1,%lu) failed\n",
0966           sizeof(struct _XtransConnInfo));
0967     return NULL;
0968     }
0969 
0970     for (unsigned int i = 1; i < NUMTRANSPORTS; i++)
0971     {
0972     if( strcmp(protocol,LOCALtrans2devtab[i].transname) != 0 )
0973         continue;
0974     switch( type )
0975     {
0976     case XTRANS_OPEN_COTS_CLIENT:
0977         prmsg(1,
0978           "LocalOpenServer: Should not be opening a client with this function\n");
0979         break;
0980     case XTRANS_OPEN_COTS_SERVER:
0981         ciptr->fd=LOCALtrans2devtab[i].devcotsopenserver(ciptr,port);
0982         break;
0983     default:
0984         prmsg(1,"LocalOpenServer: Unknown Open type %d\n",
0985           type );
0986     }
0987     if( ciptr->fd >= 0 ) {
0988         ciptr->priv=(char *)&LOCALtrans2devtab[i];
0989         ciptr->index=i;
0990         ciptr->flags = 1 | (ciptr->flags & TRANS_KEEPFLAGS);
0991         return ciptr;
0992     }
0993     }
0994 
0995     free(ciptr);
0996     return NULL;
0997 }
0998 
0999 #endif /* TRANS_SERVER */
1000 
1001 
1002 #ifdef TRANS_REOPEN
1003 
1004 static XtransConnInfo
1005 TRANS(LocalReopenServer)(int type, int index, int fd, const char *port)
1006 
1007 {
1008     XtransConnInfo ciptr;
1009     int stat = 0;
1010 
1011     prmsg(2,"LocalReopenServer(%d,%d,%d)\n", type, index, fd);
1012 
1013     if( (ciptr = calloc(1,sizeof(struct _XtransConnInfo))) == NULL )
1014     {
1015     prmsg(1,"LocalReopenServer: calloc(1,%lu) failed\n",
1016           sizeof(struct _XtransConnInfo));
1017     return NULL;
1018     }
1019 
1020     ciptr->fd = fd;
1021 
1022     switch( type )
1023     {
1024     case XTRANS_OPEN_COTS_SERVER:
1025     stat = LOCALtrans2devtab[index].devcotsreopenserver(ciptr,fd,port);
1026     break;
1027     default:
1028     prmsg(1,"LocalReopenServer: Unknown Open type %d\n",
1029       type );
1030     }
1031 
1032     if( stat > 0 ) {
1033     ciptr->priv=(char *)&LOCALtrans2devtab[index];
1034     ciptr->index=index;
1035     ciptr->flags = 1 | (ciptr->flags & TRANS_KEEPFLAGS);
1036     return ciptr;
1037     }
1038 
1039     free(ciptr);
1040     return NULL;
1041 }
1042 
1043 #endif /* TRANS_REOPEN */
1044 
1045 
1046 
1047 /*
1048  * This is the Local implementation of the X Transport service layer
1049  */
1050 
1051 #ifdef TRANS_CLIENT
1052 
1053 static XtransConnInfo
1054 TRANS(LocalOpenCOTSClient)(Xtransport *thistrans _X_UNUSED, const char *protocol,
1055                const char *host, const char *port)
1056 
1057 {
1058     prmsg(2,"LocalOpenCOTSClient(%s,%s,%s)\n",protocol,host,port);
1059 
1060     return TRANS(LocalOpenClient)(XTRANS_OPEN_COTS_CLIENT, protocol, host, port);
1061 }
1062 
1063 #endif /* TRANS_CLIENT */
1064 
1065 
1066 #ifdef TRANS_SERVER
1067 
1068 static XtransConnInfo
1069 TRANS(LocalOpenCOTSServer)(Xtransport *thistrans, const char *protocol,
1070                const char *host, const char *port)
1071 
1072 {
1073     char *typetocheck = NULL;
1074     int found = 0;
1075 
1076     prmsg(2,"LocalOpenCOTSServer(%s,%s,%s)\n",protocol,host,port);
1077 
1078     /* Check if this local type is in the XLOCAL list */
1079     TRANS(LocalInitTransports)("local");
1080     typetocheck = workingXLOCAL;
1081     while (typetocheck && !found) {
1082 #ifndef HAVE_STRCASECMP
1083     int j;
1084     char typebuf[TYPEBUFSIZE];
1085 #endif
1086 
1087     workingXLOCAL = strchr(workingXLOCAL, ':');
1088     if (workingXLOCAL && *workingXLOCAL)
1089         *workingXLOCAL++ = '\0';
1090 #ifndef HAVE_STRCASECMP
1091     strncpy(typebuf, typetocheck, TYPEBUFSIZE);
1092     for (j = 0; j < TYPEBUFSIZE; j++)
1093         if (isupper(typebuf[j]))
1094         typebuf[j] = tolower(typebuf[j]);
1095     if (!strcmp(thistrans->TransName, typebuf))
1096 #else
1097     if (!strcasecmp(thistrans->TransName, typetocheck))
1098 #endif
1099         found = 1;
1100     typetocheck = workingXLOCAL;
1101     }
1102     TRANS(LocalEndTransports)();
1103 
1104     if (!found) {
1105     prmsg(3,"LocalOpenCOTSServer: disabling %s\n",thistrans->TransName);
1106     thistrans->flags |= TRANS_DISABLED;
1107     return NULL;
1108     }
1109 
1110     return TRANS(LocalOpenServer)(XTRANS_OPEN_COTS_SERVER, protocol, host, port);
1111 }
1112 
1113 #endif /* TRANS_SERVER */
1114 
1115 #ifdef TRANS_REOPEN
1116 
1117 static XtransConnInfo
1118 TRANS(LocalReopenCOTSServer)(Xtransport *thistrans, int fd, const char *port)
1119 
1120 {
1121     unsigned int index;
1122 
1123     prmsg(2,"LocalReopenCOTSServer(%d,%s)\n", fd, port);
1124 
1125     for(index=1;index<NUMTRANSPORTS;index++)
1126     {
1127     if( strcmp(thistrans->TransName,
1128         LOCALtrans2devtab[index].transname) == 0 )
1129         break;
1130     }
1131 
1132     if (index >= NUMTRANSPORTS)
1133     {
1134     return (NULL);
1135     }
1136 
1137     return TRANS(LocalReopenServer)(XTRANS_OPEN_COTS_SERVER,
1138     index, fd, port);
1139 }
1140 
1141 #endif /* TRANS_REOPEN */
1142 
1143 
1144 
1145 static int
1146 TRANS(LocalSetOption)(XtransConnInfo ciptr, int option, int arg)
1147 
1148 {
1149     prmsg(2,"LocalSetOption(%d,%d,%d)\n",ciptr->fd,option,arg);
1150 
1151     return -1;
1152 }
1153 
1154 
1155 #ifdef TRANS_SERVER
1156 
1157 static int
1158 TRANS(LocalCreateListener)(XtransConnInfo ciptr, const char *port,
1159                            unsigned int flags _X_UNUSED)
1160 
1161 {
1162     prmsg(2,"LocalCreateListener(%p->%d,%s)\n",ciptr,ciptr->fd,port);
1163 
1164     return 0;
1165 }
1166 
1167 static int
1168 TRANS(LocalResetListener)(XtransConnInfo ciptr)
1169 
1170 {
1171     LOCALtrans2dev  *transptr;
1172 
1173     prmsg(2,"LocalResetListener(%p)\n",ciptr);
1174 
1175     transptr=(LOCALtrans2dev *)ciptr->priv;
1176     if (transptr->devreset != NULL) {
1177     return transptr->devreset(ciptr);
1178     }
1179     return TRANS_RESET_NOOP;
1180 }
1181 
1182 
1183 static XtransConnInfo
1184 TRANS(LocalAccept)(XtransConnInfo ciptr, int *status)
1185 
1186 {
1187     XtransConnInfo  newciptr;
1188     LOCALtrans2dev  *transptr;
1189 
1190     prmsg(2,"LocalAccept(%p->%d)\n", ciptr, ciptr->fd);
1191 
1192     transptr=(LOCALtrans2dev *)ciptr->priv;
1193 
1194     if( (newciptr = calloc(1,sizeof(struct _XtransConnInfo)))==NULL )
1195     {
1196     prmsg(1,"LocalAccept: calloc(1,%lu) failed\n",
1197           sizeof(struct _XtransConnInfo));
1198     *status = TRANS_ACCEPT_BAD_MALLOC;
1199     return NULL;
1200     }
1201 
1202     newciptr->fd=transptr->devaccept(ciptr,newciptr,status);
1203 
1204     if( newciptr->fd < 0 )
1205     {
1206     free(newciptr);
1207     return NULL;
1208     }
1209 
1210     newciptr->priv=(char *)transptr;
1211     newciptr->index = ciptr->index;
1212 
1213     *status = 0;
1214 
1215     return newciptr;
1216 }
1217 
1218 #endif /* TRANS_SERVER */
1219 
1220 
1221 #ifdef TRANS_CLIENT
1222 
1223 static int
1224 TRANS(LocalConnect)(XtransConnInfo ciptr,
1225                     const char *host _X_UNUSED, const char *port)
1226 
1227 {
1228     prmsg(2,"LocalConnect(%p->%d,%s)\n", ciptr, ciptr->fd, port);
1229 
1230     return 0;
1231 }
1232 
1233 #endif /* TRANS_CLIENT */
1234 
1235 
1236 static int
1237 TRANS(LocalBytesReadable)(XtransConnInfo ciptr, BytesReadable_t *pend )
1238 
1239 {
1240     prmsg(2,"LocalBytesReadable(%p->%d,%p)\n", ciptr, ciptr->fd, pend);
1241 
1242     return ioctl(ciptr->fd, FIONREAD, (char *)pend);
1243 }
1244 
1245 static int
1246 TRANS(LocalRead)(XtransConnInfo ciptr, char *buf, int size)
1247 
1248 {
1249     prmsg(2,"LocalRead(%d,%p,%d)\n", ciptr->fd, buf, size );
1250 
1251     return read(ciptr->fd,buf,size);
1252 }
1253 
1254 static int
1255 TRANS(LocalWrite)(XtransConnInfo ciptr, char *buf, int size)
1256 
1257 {
1258     prmsg(2,"LocalWrite(%d,%p,%d)\n", ciptr->fd, buf, size );
1259 
1260     return write(ciptr->fd,buf,size);
1261 }
1262 
1263 static int
1264 TRANS(LocalReadv)(XtransConnInfo ciptr, struct iovec *buf, int size)
1265 
1266 {
1267     prmsg(2,"LocalReadv(%d,%p,%d)\n", ciptr->fd, buf, size );
1268 
1269     return READV(ciptr,buf,size);
1270 }
1271 
1272 static int
1273 TRANS(LocalWritev)(XtransConnInfo ciptr, struct iovec *buf, int size)
1274 
1275 {
1276     prmsg(2,"LocalWritev(%d,%p,%d)\n", ciptr->fd, buf, size );
1277 
1278     return WRITEV(ciptr,buf,size);
1279 }
1280 
1281 static int
1282 TRANS(LocalDisconnect)(XtransConnInfo ciptr)
1283 
1284 {
1285     prmsg(2,"LocalDisconnect(%p->%d)\n", ciptr, ciptr->fd);
1286 
1287     return 0;
1288 }
1289 
1290 static int
1291 TRANS(LocalClose)(XtransConnInfo ciptr)
1292 
1293 {
1294     struct sockaddr_un      *sockname=(struct sockaddr_un *) ciptr->addr;
1295     int ret;
1296 
1297     prmsg(2,"LocalClose(%p->%d)\n", ciptr, ciptr->fd );
1298 
1299     ret=close(ciptr->fd);
1300 
1301     if(ciptr->flags
1302        && sockname
1303        && sockname->sun_family == AF_UNIX
1304        && sockname->sun_path[0] )
1305     {
1306     if (!(ciptr->flags & TRANS_NOUNLINK))
1307         unlink(sockname->sun_path);
1308     }
1309 
1310     return ret;
1311 }
1312 
1313 static int
1314 TRANS(LocalCloseForCloning)(XtransConnInfo ciptr)
1315 
1316 {
1317     int ret;
1318 
1319     prmsg(2,"LocalCloseForCloning(%p->%d)\n", ciptr, ciptr->fd );
1320 
1321     /* Don't unlink path */
1322 
1323     ret=close(ciptr->fd);
1324 
1325     return ret;
1326 }
1327 
1328 
1329 /*
1330  * MakeAllCOTSServerListeners() will go through the entire Xtransports[]
1331  * array defined in Xtrans.c and try to OpenCOTSServer() for each entry.
1332  * We will add duplicate entries to that table so that the OpenCOTSServer()
1333  * function will get called once for each type of local transport.
1334  *
1335  * The TransName is in lowercase, so it will never match during a normal
1336  * call to SelectTransport() in Xtrans.c.
1337  */
1338 
1339 #ifdef TRANS_SERVER
1340 static const char * local_aliases[] = {
1341                   "named",
1342                   "pipe", /* compatibility with Solaris Xlib */
1343                   NULL };
1344 #endif
1345 
1346 Xtransport  TRANS(LocalFuncs) = {
1347     /* Local Interface */
1348     "local",
1349     TRANS_ALIAS | TRANS_LOCAL,
1350 #ifdef TRANS_CLIENT
1351     TRANS(LocalOpenCOTSClient),
1352 #endif /* TRANS_CLIENT */
1353 #ifdef TRANS_SERVER
1354     local_aliases,
1355     TRANS(LocalOpenCOTSServer),
1356 #endif /* TRANS_SERVER */
1357 #ifdef TRANS_REOPEN
1358     TRANS(LocalReopenCOTSServer),
1359 #endif
1360     TRANS(LocalSetOption),
1361 #ifdef TRANS_SERVER
1362     TRANS(LocalCreateListener),
1363     TRANS(LocalResetListener),
1364     TRANS(LocalAccept),
1365 #endif /* TRANS_SERVER */
1366 #ifdef TRANS_CLIENT
1367     TRANS(LocalConnect),
1368 #endif /* TRANS_CLIENT */
1369     TRANS(LocalBytesReadable),
1370     TRANS(LocalRead),
1371     TRANS(LocalWrite),
1372     TRANS(LocalReadv),
1373     TRANS(LocalWritev),
1374 #if XTRANS_SEND_FDS
1375     TRANS(LocalSendFdInvalid),
1376     TRANS(LocalRecvFdInvalid),
1377 #endif
1378     TRANS(LocalDisconnect),
1379     TRANS(LocalClose),
1380     TRANS(LocalCloseForCloning),
1381 };
1382 
1383 
1384 #ifdef LOCAL_TRANS_NAMED
1385 
1386 Xtransport  TRANS(NAMEDFuncs) = {
1387     /* Local Interface */
1388     "named",
1389     TRANS_LOCAL,
1390 #ifdef TRANS_CLIENT
1391     TRANS(LocalOpenCOTSClient),
1392 #endif /* TRANS_CLIENT */
1393 #ifdef TRANS_SERVER
1394     NULL,
1395     TRANS(LocalOpenCOTSServer),
1396 #endif /* TRANS_SERVER */
1397 #ifdef TRANS_REOPEN
1398     TRANS(LocalReopenCOTSServer),
1399 #endif
1400     TRANS(LocalSetOption),
1401 #ifdef TRANS_SERVER
1402     TRANS(LocalCreateListener),
1403     TRANS(LocalResetListener),
1404     TRANS(LocalAccept),
1405 #endif /* TRANS_SERVER */
1406 #ifdef TRANS_CLIENT
1407     TRANS(LocalConnect),
1408 #endif /* TRANS_CLIENT */
1409     TRANS(LocalBytesReadable),
1410     TRANS(LocalRead),
1411     TRANS(LocalWrite),
1412     TRANS(LocalReadv),
1413     TRANS(LocalWritev),
1414 #if XTRANS_SEND_FDS
1415     TRANS(LocalSendFdInvalid),
1416     TRANS(LocalRecvFdInvalid),
1417 #endif
1418     TRANS(LocalDisconnect),
1419     TRANS(LocalClose),
1420     TRANS(LocalCloseForCloning),
1421 };
1422 
1423 Xtransport  TRANS(PIPEFuncs) = {
1424     /* Local Interface */
1425     "pipe",
1426     TRANS_ALIAS | TRANS_LOCAL,
1427 #ifdef TRANS_CLIENT
1428     TRANS(LocalOpenCOTSClient),
1429 #endif /* TRANS_CLIENT */
1430 #ifdef TRANS_SERVER
1431     NULL,
1432     TRANS(LocalOpenCOTSServer),
1433 #endif /* TRANS_SERVER */
1434 #ifdef TRANS_REOPEN
1435     TRANS(LocalReopenCOTSServer),
1436 #endif
1437     TRANS(LocalSetOption),
1438 #ifdef TRANS_SERVER
1439     TRANS(LocalCreateListener),
1440     TRANS(LocalResetListener),
1441     TRANS(LocalAccept),
1442 #endif /* TRANS_SERVER */
1443 #ifdef TRANS_CLIENT
1444     TRANS(LocalConnect),
1445 #endif /* TRANS_CLIENT */
1446     TRANS(LocalBytesReadable),
1447     TRANS(LocalRead),
1448     TRANS(LocalWrite),
1449     TRANS(LocalReadv),
1450     TRANS(LocalWritev),
1451 #if XTRANS_SEND_FDS
1452     TRANS(LocalSendFdInvalid),
1453     TRANS(LocalRecvFdInvalid),
1454 #endif
1455     TRANS(LocalDisconnect),
1456     TRANS(LocalClose),
1457     TRANS(LocalCloseForCloning),
1458 };
1459 #endif /* LOCAL_TRANS_NAMED */
1460 
1461