Home | History | Annotate | Line # | Download | only in dist
      1 /*
      2 
      3 Copyright 1993, 1994, 1998  The Open Group
      4 
      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
      9 documentation.
     10 
     11 The above copyright notice and this permission notice shall be included
     12 in all copies or substantial portions of the Software.
     13 
     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.
     21 
     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
     25 from The Open Group.
     26 
     27  * Copyright 1993, 1994 NCR Corporation - Dayton, Ohio, USA
     28  *
     29  * All Rights Reserved
     30  *
     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.
     40  *
     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.
     48  */
     49 
     50 /*
     51  *
     52  * The connection code/ideas in lib/X and server/os for SVR4/Intel
     53  * environments was contributed by the following companies/groups:
     54  *
     55  *	MetroLink Inc
     56  *	NCR
     57  *	Pittsburgh Powercomputing Corporation (PPc)/Quarterdeck Office Systems
     58  *	SGCS
     59  *	Unix System Laboratories (USL) / Novell
     60  *	XFree86
     61  *
     62  * The goal is to have common connection code among all SVR4/Intel vendors.
     63  *
     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.
     71  */
     72 
     73 #include <errno.h>
     74 #include <ctype.h>
     75 #include <sys/signal.h>
     76 #include <sys/ioctl.h>
     77 #include <sys/stat.h>
     78 #if defined(SVR4) || defined(__SVR4)
     79 #include <sys/filio.h>
     80 #endif
     81 # include <stropts.h>
     82 #include <sys/wait.h>
     83 #include <sys/types.h>
     84 
     85 /*
     86  * The local transports should be treated the same as a UNIX domain socket
     87  * wrt authentication, etc. Because of this, we will use struct sockaddr_un
     88  * for the address format. This will simplify the code in other places like
     89  * The X Server.
     90  */
     91 
     92 #include <sys/socket.h>
     93 #ifndef X_NO_SYS_UN
     94 #include <sys/un.h>
     95 #endif
     96 
     97 
     98 /* Types of local connections supported:
     99  *  - PTS
    100  *  - named pipes
    101  */
    102 #if defined(SVR4) || defined(__SVR4)
    103 # define LOCAL_TRANS_NAMED
    104 #endif
    105 
    106 static int TRANS(LocalClose)(XtransConnInfo ciptr);
    107 
    108 /*
    109  * These functions actually implement the local connection mechanisms.
    110  */
    111 
    112 /* Type Not Supported */
    113 
    114 static int
    115 TRANS(OpenFail)(XtransConnInfo ciptr _X_UNUSED, const char *port _X_UNUSED)
    116 
    117 {
    118     return -1;
    119 }
    120 
    121 #ifdef TRANS_REOPEN
    122 
    123 static int
    124 TRANS(ReopenFail)(XtransConnInfo ciptr _X_UNUSED, int fd _X_UNUSED,
    125                   const char *port _X_UNUSED)
    126 
    127 {
    128     return 0;
    129 }
    130 
    131 #endif /* TRANS_REOPEN */
    132 
    133 #if XTRANS_SEND_FDS
    134 static int
    135 TRANS(LocalRecvFdInvalid)(XtransConnInfo ciptr)
    136 {
    137     errno = EINVAL;
    138     return -1;
    139 }
    140 
    141 static int
    142 TRANS(LocalSendFdInvalid)(XtransConnInfo ciptr, int fd, int do_close)
    143 {
    144     errno = EINVAL;
    145     return -1;
    146 }
    147 #endif
    148 
    149 
    150 static int
    152 TRANS(FillAddrInfo)(XtransConnInfo ciptr,
    153                     const char *sun_path, const char *peer_sun_path)
    154 
    155 {
    156     struct sockaddr_un	*sunaddr;
    157     struct sockaddr_un	*p_sunaddr;
    158 
    159     ciptr->family = AF_UNIX;
    160     ciptr->addrlen = sizeof (struct sockaddr_un);
    161 
    162     if ((sunaddr = malloc (ciptr->addrlen)) == NULL)
    163     {
    164 	prmsg(1,"FillAddrInfo: failed to allocate memory for addr\n");
    165 	return 0;
    166     }
    167 
    168     sunaddr->sun_family = AF_UNIX;
    169 
    170     if (strlen(sun_path) > sizeof(sunaddr->sun_path) - 1) {
    171 	prmsg(1, "FillAddrInfo: path too long\n");
    172 	free((char *) sunaddr);
    173 	return 0;
    174     }
    175     strcpy (sunaddr->sun_path, sun_path);
    176 #if defined(BSD44SOCKETS)
    177     sunaddr->sun_len = strlen (sunaddr->sun_path);
    178 #endif
    179 
    180     ciptr->addr = (char *) sunaddr;
    181 
    182     ciptr->peeraddrlen = sizeof (struct sockaddr_un);
    183 
    184     if ((p_sunaddr = malloc (ciptr->peeraddrlen)) == NULL)
    185     {
    186 	prmsg(1,
    187 	   "FillAddrInfo: failed to allocate memory for peer addr\n");
    188 	free (sunaddr);
    189 	ciptr->addr = NULL;
    190 
    191 	return 0;
    192     }
    193 
    194     p_sunaddr->sun_family = AF_UNIX;
    195 
    196     if (strlen(peer_sun_path) > sizeof(p_sunaddr->sun_path) - 1) {
    197 	prmsg(1, "FillAddrInfo: peer path too long\n");
    198 	free((char *) p_sunaddr);
    199 	return 0;
    200     }
    201     strcpy (p_sunaddr->sun_path, peer_sun_path);
    202 #if defined(BSD44SOCKETS)
    203     p_sunaddr->sun_len = strlen (p_sunaddr->sun_path);
    204 #endif
    205 
    206     ciptr->peeraddr = (char *) p_sunaddr;
    207 
    208     return 1;
    209 }
    210 
    211 
    212 
    213 
    215 #ifndef X11_t
    216 #define X_STREAMS_DIR	"/dev/X"
    217 #else
    218 #define X_STREAMS_DIR	"/tmp/.X11-pipe"
    219 #endif
    220 
    221 #define DEV_PTMX	"/dev/ptmx"
    222 
    223 #if defined(X11_t)
    224 
    225 #define NAMEDNODENAME "/tmp/.X11-pipe/X"
    226 #endif
    227 #if defined(XIM_t)
    228 #define NAMEDNODENAME "/tmp/.XIM-pipe/XIM"
    229 #endif
    230 #if defined(FS_t) || defined (FONT_t)
    231 #define NAMEDNODENAME	"/tmp/.font-pipe/fs"
    232 #endif
    233 #if defined(ICE_t)
    234 #define NAMEDNODENAME	"/tmp/.ICE-pipe/"
    235 #endif
    236 
    237 
    238 
    239 
    241 
    242 #ifdef LOCAL_TRANS_NAMED
    244 
    245 /* NAMED */
    246 
    247 #ifdef TRANS_CLIENT
    248 
    249 static int
    250 TRANS(NAMEDOpenClient)(XtransConnInfo ciptr, const char *port)
    251 
    252 {
    253 #ifdef NAMEDNODENAME
    254     int			fd;
    255     char		server_path[64];
    256     struct stat		filestat;
    257 #endif
    258 
    259     prmsg(2,"NAMEDOpenClient(%s)\n", port);
    260 
    261 #if !defined(NAMEDNODENAME)
    262     prmsg(1,"NAMEDOpenClient: Protocol is not supported by a NAMED connection\n");
    263     return -1;
    264 #else
    265     if ( port && *port ) {
    266 	if( *port == '/' ) { /* A full pathname */
    267 		(void) snprintf(server_path, sizeof(server_path), "%s", port);
    268 	    } else {
    269 		(void) snprintf(server_path, sizeof(server_path), "%s%s", NAMEDNODENAME, port);
    270 	    }
    271     } else {
    272 	(void) snprintf(server_path, sizeof(server_path), "%s%ld", NAMEDNODENAME, (long)getpid());
    273     }
    274 
    275     if ((fd = open(server_path, O_RDWR)) < 0) {
    276 	prmsg(1,"NAMEDOpenClient: Cannot open %s for NAMED connection\n", server_path);
    277 	return -1;
    278     }
    279 
    280     if (fstat(fd, &filestat) < 0 ) {
    281 	prmsg(1,"NAMEDOpenClient: Cannot stat %s for NAMED connection\n", server_path);
    282 	(void) close(fd);
    283 	return -1;
    284     }
    285 
    286     if ((filestat.st_mode & S_IFMT) != S_IFIFO) {
    287 	prmsg(1,"NAMEDOpenClient: Device %s is not a FIFO\n", server_path);
    288 	/* Is this really a failure? */
    289 	(void) close(fd);
    290 	return -1;
    291     }
    292 
    293 
    294     if (isastream(fd) <= 0) {
    295 	prmsg(1,"NAMEDOpenClient: %s is not a streams device\n", server_path);
    296 	(void) close(fd);
    297 	return -1;
    298     }
    299 
    300     /*
    301      * Everything looks good: fill in the XtransConnInfo structure.
    302      */
    303 
    304     if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
    305     {
    306 	prmsg(1,"NAMEDOpenClient: failed to fill in addr info\n");
    307 	close(fd);
    308 	return -1;
    309     }
    310 
    311     return(fd);
    312 
    313 #endif /* !NAMEDNODENAME */
    314 }
    315 
    316 #endif /* TRANS_CLIENT */
    317 
    318 
    319 #ifdef TRANS_SERVER
    320 
    321 
    322 #ifdef NAMEDNODENAME
    323 static int
    324 TRANS(NAMEDOpenPipe)(const char *server_path)
    325 {
    326     int			fd, pipefd[2];
    327     struct stat		sbuf;
    328     int			mode;
    329 
    330     prmsg(2,"NAMEDOpenPipe(%s)\n", server_path);
    331 
    332 #ifdef HAS_STICKY_DIR_BIT
    333     mode = 01777;
    334 #else
    335     mode = 0777;
    336 #endif
    337     if (trans_mkdir(X_STREAMS_DIR, mode) == -1) {
    338 	prmsg (1, "NAMEDOpenPipe: mkdir(%s) failed, errno = %d\n",
    339 	       X_STREAMS_DIR, errno);
    340 	return(-1);
    341     }
    342 
    343     if(stat(server_path, &sbuf) != 0) {
    344 	if (errno == ENOENT) {
    345 	    if ((fd = creat(server_path, (mode_t)0666)) == -1) {
    346 		prmsg(1, "NAMEDOpenPipe: Can't open %s\n", server_path);
    347 		return(-1);
    348 	    }
    349 	    if (fchmod(fd, (mode_t)0666) < 0) {
    350 		prmsg(1, "NAMEDOpenPipe: Can't chmod %s\n", server_path);
    351 		close(fd);
    352 		return(-1);
    353 	    }
    354 	    close(fd);
    355 	} else {
    356 	    prmsg(1, "NAMEDOpenPipe: stat on %s failed\n", server_path);
    357 	    return(-1);
    358 	}
    359     }
    360 
    361     if( pipe(pipefd) != 0) {
    362 	prmsg(1, "NAMEDOpenPipe: pipe() failed, errno=%d\n",errno);
    363 	return(-1);
    364     }
    365 
    366     if( ioctl(pipefd[0], I_PUSH, "connld") != 0) {
    367 	prmsg(1, "NAMEDOpenPipe: ioctl(I_PUSH,\"connld\") failed, errno=%d\n",errno);
    368 	close(pipefd[0]);
    369 	close(pipefd[1]);
    370 	return(-1);
    371     }
    372 
    373     if( fattach(pipefd[0], server_path) != 0) {
    374 	prmsg(1, "NAMEDOpenPipe: fattach(%s) failed, errno=%d\n", server_path,errno);
    375 	close(pipefd[0]);
    376 	close(pipefd[1]);
    377 	return(-1);
    378     }
    379 
    380     return(pipefd[1]);
    381 }
    382 #endif
    383 
    384 static int
    385 TRANS(NAMEDOpenServer)(XtransConnInfo ciptr, const char *port)
    386 {
    387 #ifdef NAMEDNODENAME
    388     int			fd;
    389     char		server_path[64];
    390 #endif
    391 
    392     prmsg(2,"NAMEDOpenServer(%s)\n", port);
    393 
    394 #if !defined(NAMEDNODENAME)
    395     prmsg(1,"NAMEDOpenServer: Protocol is not supported by a NAMED connection\n");
    396     return -1;
    397 #else
    398     if ( port && *port ) {
    399 	if( *port == '/' ) { /* A full pathname */
    400 	    (void) snprintf(server_path, sizeof(server_path), "%s", port);
    401 	} else {
    402 	    (void) snprintf(server_path, sizeof(server_path), "%s%s",
    403 			    NAMEDNODENAME, port);
    404 	}
    405     } else {
    406 	(void) snprintf(server_path, sizeof(server_path), "%s%ld",
    407 		       NAMEDNODENAME, (long)getpid());
    408     }
    409 
    410     fd = TRANS(NAMEDOpenPipe)(server_path);
    411     if (fd < 0) {
    412 	return -1;
    413     }
    414 
    415     /*
    416      * Everything looks good: fill in the XtransConnInfo structure.
    417      */
    418 
    419     if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
    420     {
    421 	prmsg(1,"NAMEDOpenServer: failed to fill in addr info\n");
    422 	TRANS(LocalClose)(ciptr);
    423 	return -1;
    424     }
    425 
    426     return fd;
    427 
    428 #endif /* !NAMEDNODENAME */
    429 }
    430 
    431 static int
    432 TRANS(NAMEDResetListener) (XtransConnInfo ciptr)
    433 
    434 {
    435   struct sockaddr_un      *sockname=(struct sockaddr_un *) ciptr->addr;
    436   struct stat     statb;
    437 
    438   prmsg(2,"NAMEDResetListener(%p, %d)\n", (void *) ciptr, ciptr->fd);
    439 
    440   if (ciptr->fd != -1) {
    441     /*
    442      * see if the pipe has disappeared
    443      */
    444 
    445     if (stat (sockname->sun_path, &statb) == -1 ||
    446 	(statb.st_mode & S_IFMT) != S_IFIFO) {
    447       prmsg(3, "Pipe %s trashed, recreating\n", sockname->sun_path);
    448       TRANS(LocalClose)(ciptr);
    449       ciptr->fd = TRANS(NAMEDOpenPipe)(sockname->sun_path);
    450       if (ciptr->fd >= 0)
    451 	  return TRANS_RESET_NEW_FD;
    452       else
    453 	  return TRANS_CREATE_LISTENER_FAILED;
    454     }
    455   }
    456   return TRANS_RESET_NOOP;
    457 }
    458 
    459 static int
    460 TRANS(NAMEDAccept)(XtransConnInfo ciptr, XtransConnInfo newciptr, int *status)
    461 
    462 {
    463     struct strrecvfd str;
    464 
    465     prmsg(2,"NAMEDAccept(%p->%d)\n", (void *) ciptr, ciptr->fd);
    466 
    467     if( ioctl(ciptr->fd, I_RECVFD, &str ) < 0 ) {
    468 	prmsg(1, "NAMEDAccept: ioctl(I_RECVFD) failed, errno=%d\n", errno);
    469 	*status = TRANS_ACCEPT_MISC_ERROR;
    470 	return(-1);
    471     }
    472 
    473     /*
    474      * Everything looks good: fill in the XtransConnInfo structure.
    475      */
    476     newciptr->family=ciptr->family;
    477     newciptr->addrlen=ciptr->addrlen;
    478     if( (newciptr->addr = malloc(newciptr->addrlen)) == NULL ) {
    479 	prmsg(1,
    480 	      "NAMEDAccept: failed to allocate memory for pipe addr\n");
    481 	close(str.fd);
    482 	*status = TRANS_ACCEPT_BAD_MALLOC;
    483 	return -1;
    484     }
    485 
    486     memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen);
    487 
    488     newciptr->peeraddrlen=newciptr->addrlen;
    489     if( (newciptr->peeraddr = malloc(newciptr->peeraddrlen)) == NULL ) {
    490 	prmsg(1,
    491 	"NAMEDAccept: failed to allocate memory for peer addr\n");
    492 	free(newciptr->addr);
    493 	close(str.fd);
    494 	*status = TRANS_ACCEPT_BAD_MALLOC;
    495 	return -1;
    496     }
    497 
    498     memcpy(newciptr->peeraddr,newciptr->addr,newciptr->peeraddrlen);
    499 
    500     *status = 0;
    501 
    502     return str.fd;
    503 }
    504 
    505 #endif /* TRANS_SERVER */
    506 
    507 #endif /* LOCAL_TRANS_NAMED */
    508 
    509 
    510 
    511 
    513 
    514 
    515 
    516 
    518 
    519 
    520 #ifdef TRANS_REOPEN
    522 
    523 #ifdef LOCAL_TRANS_NAMED
    524 
    525 static int
    526 TRANS(NAMEDReopenServer)(XtransConnInfo ciptr, int fd _X_UNUSED, const char *port)
    527 
    528 {
    529 #ifdef NAMEDNODENAME
    530     char server_path[64];
    531 #endif
    532 
    533     prmsg(2,"NAMEDReopenServer(%s)\n", port);
    534 
    535 #if !defined(NAMEDNODENAME)
    536     prmsg(1,"NAMEDReopenServer: Protocol is not supported by a NAMED connection\n");
    537     return 0;
    538 #else
    539     if ( port && *port ) {
    540 	if( *port == '/' ) { /* A full pathname */
    541 	    snprintf(server_path, sizeof(server_path),"%s", port);
    542 	} else {
    543 	    snprintf(server_path, sizeof(server_path), "%s%s",
    544 		     NAMEDNODENAME, port);
    545 	}
    546     } else {
    547 	snprintf(server_path, sizeof(server_path), "%s%ld",
    548 		NAMEDNODENAME, (long)getpid());
    549     }
    550 
    551     if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
    552     {
    553 	prmsg(1,"NAMEDReopenServer: failed to fill in addr info\n");
    554 	return 0;
    555     }
    556 
    557     return 1;
    558 
    559 #endif /* !NAMEDNODENAME */
    560 }
    561 
    562 #endif /* LOCAL_TRANS_NAMED */
    563 
    564 
    565 
    566 #endif /* TRANS_REOPEN */
    567 
    568 
    569 
    570 /*
    572  * This table contains all of the entry points for the different local
    573  * connection mechanisms.
    574  */
    575 
    576 typedef struct _LOCALtrans2dev {
    577     const char	*transname;
    578 
    579 #ifdef TRANS_CLIENT
    580 
    581     int	(*devcotsopenclient)(
    582 	XtransConnInfo, const char * /*port*/
    583 );
    584 
    585 #endif /* TRANS_CLIENT */
    586 
    587 #ifdef TRANS_SERVER
    588 
    589     int	(*devcotsopenserver)(
    590 	XtransConnInfo, const char * /*port*/
    591 );
    592 
    593 #endif /* TRANS_SERVER */
    594 
    595 #ifdef TRANS_CLIENT
    596 
    597     int	(*devcltsopenclient)(
    598 	XtransConnInfo, const char * /*port*/
    599 );
    600 
    601 #endif /* TRANS_CLIENT */
    602 
    603 #ifdef TRANS_SERVER
    604 
    605     int	(*devcltsopenserver)(
    606 	XtransConnInfo, const char * /*port*/
    607 );
    608 
    609 #endif /* TRANS_SERVER */
    610 
    611 #ifdef TRANS_REOPEN
    612 
    613     int	(*devcotsreopenserver)(
    614 	XtransConnInfo,
    615 	int, 	/* fd */
    616 	const char * 	/* port */
    617 );
    618 
    619     int	(*devcltsreopenserver)(
    620 	XtransConnInfo,
    621 	int, 	/* fd */
    622 	const char *	/* port */
    623 );
    624 
    625 #endif /* TRANS_REOPEN */
    626 
    627 #ifdef TRANS_SERVER
    628 
    629     int (*devreset)(
    630 	XtransConnInfo /* ciptr */
    631 );
    632 
    633     int	(*devaccept)(
    634 	XtransConnInfo, XtransConnInfo, int *
    635 );
    636 
    637 #endif /* TRANS_SERVER */
    638 
    639 } LOCALtrans2dev;
    640 
    641 static LOCALtrans2dev LOCALtrans2devtab[] = {
    642 {"",
    643 #ifdef TRANS_CLIENT
    644      TRANS(NAMEDOpenClient),
    645 #endif /* TRANS_CLIENT */
    646 #ifdef TRANS_SERVER
    647      TRANS(NAMEDOpenServer),
    648 #endif /* TRANS_SERVER */
    649 #ifdef TRANS_CLIENT
    650      TRANS(OpenFail),
    651 #endif /* TRANS_CLIENT */
    652 #ifdef TRANS_SERVER
    653      TRANS(OpenFail),
    654 #endif /* TRANS_SERVER */
    655 #ifdef TRANS_REOPEN
    656      TRANS(NAMEDReopenServer),
    657      TRANS(ReopenFail),
    658 #endif
    659 #ifdef TRANS_SERVER
    660      TRANS(NAMEDResetListener),
    661      TRANS(NAMEDAccept)
    662 #endif /* TRANS_SERVER */
    663 },
    664 
    665 {"local",
    666 #ifdef TRANS_CLIENT
    667      TRANS(NAMEDOpenClient),
    668 #endif /* TRANS_CLIENT */
    669 #ifdef TRANS_SERVER
    670      TRANS(NAMEDOpenServer),
    671 #endif /* TRANS_SERVER */
    672 #ifdef TRANS_CLIENT
    673      TRANS(OpenFail),
    674 #endif /* TRANS_CLIENT */
    675 #ifdef TRANS_SERVER
    676      TRANS(OpenFail),
    677 #endif /* TRANS_SERVER */
    678 #ifdef TRANS_REOPEN
    679      TRANS(NAMEDReopenServer),
    680      TRANS(ReopenFail),
    681 #endif
    682 #ifdef TRANS_SERVER
    683      TRANS(NAMEDResetListener),
    684      TRANS(NAMEDAccept)
    685 #endif /* TRANS_SERVER */
    686 },
    687 
    688 #ifdef LOCAL_TRANS_NAMED
    689 {"named",
    690 #ifdef TRANS_CLIENT
    691      TRANS(NAMEDOpenClient),
    692 #endif /* TRANS_CLIENT */
    693 #ifdef TRANS_SERVER
    694      TRANS(NAMEDOpenServer),
    695 #endif /* TRANS_SERVER */
    696 #ifdef TRANS_CLIENT
    697      TRANS(OpenFail),
    698 #endif /* TRANS_CLIENT */
    699 #ifdef TRANS_SERVER
    700      TRANS(OpenFail),
    701 #endif /* TRANS_SERVER */
    702 #ifdef TRANS_REOPEN
    703      TRANS(NAMEDReopenServer),
    704      TRANS(ReopenFail),
    705 #endif
    706 #ifdef TRANS_SERVER
    707      TRANS(NAMEDResetListener),
    708      TRANS(NAMEDAccept)
    709 #endif /* TRANS_SERVER */
    710 },
    711 
    712 {"pipe",
    713 #ifdef TRANS_CLIENT
    714      TRANS(NAMEDOpenClient),
    715 #endif /* TRANS_CLIENT */
    716 #ifdef TRANS_SERVER
    717      TRANS(NAMEDOpenServer),
    718 #endif /* TRANS_SERVER */
    719 #ifdef TRANS_CLIENT
    720      TRANS(OpenFail),
    721 #endif /* TRANS_CLIENT */
    722 #ifdef TRANS_SERVER
    723      TRANS(OpenFail),
    724 #endif /* TRANS_SERVER */
    725 #ifdef TRANS_REOPEN
    726      TRANS(NAMEDReopenServer),
    727      TRANS(ReopenFail),
    728 #endif
    729 #ifdef TRANS_SERVER
    730      TRANS(NAMEDResetListener),
    731      TRANS(NAMEDAccept)
    732 #endif /* TRANS_SERVER */
    733 },
    734 #endif /* LOCAL_TRANS_NAMED */
    735 
    736 
    737 };
    738 
    739 #define NUMTRANSPORTS	(sizeof(LOCALtrans2devtab)/sizeof(LOCALtrans2dev))
    740 
    741 static const char	*XLOCAL=NULL;
    742 static	char	*workingXLOCAL=NULL;
    743 static	char	*freeXLOCAL=NULL;
    744 
    745 #define DEF_XLOCAL "UNIX:NAMED"
    746 
    747 static void
    748 TRANS(LocalInitTransports)(const char *protocol)
    749 
    750 {
    751     prmsg(3,"LocalInitTransports(%s)\n", protocol);
    752 
    753     if( strcmp(protocol,"local") && strcmp(protocol,"LOCAL") )
    754     {
    755 	workingXLOCAL = freeXLOCAL = strdup (protocol);
    756     }
    757     else {
    758 	XLOCAL = getenv("XLOCAL");
    759 	if(XLOCAL==NULL)
    760 	    XLOCAL=DEF_XLOCAL;
    761 	workingXLOCAL = freeXLOCAL = strdup (XLOCAL);
    762     }
    763 }
    764 
    765 static void
    766 TRANS(LocalEndTransports)(void)
    767 
    768 {
    769     prmsg(3,"LocalEndTransports()\n");
    770     free(freeXLOCAL);
    771     freeXLOCAL = NULL;
    772 }
    773 
    774 #define TYPEBUFSIZE	32
    775 
    776 #ifdef TRANS_CLIENT
    777 
    778 static LOCALtrans2dev *
    779 TRANS(LocalGetNextTransport)(void)
    780 
    781 {
    782     char	*typetocheck;
    783     prmsg(3,"LocalGetNextTransport()\n");
    784 
    785     while(1)
    786     {
    787 	if( workingXLOCAL == NULL || *workingXLOCAL == '\0' )
    788 	    return NULL;
    789 
    790 	typetocheck=workingXLOCAL;
    791 	workingXLOCAL=strchr(workingXLOCAL,':');
    792 	if(workingXLOCAL && *workingXLOCAL)
    793 	    *workingXLOCAL++='\0';
    794 
    795 	for (unsigned int i = 0; i < NUMTRANSPORTS; i++)
    796 	{
    797 #ifndef HAVE_STRCASECMP
    798 	    int		j;
    799 	    char	typebuf[TYPEBUFSIZE];
    800 	    /*
    801 	     * This is equivalent to a case insensitive strcmp(),
    802 	     * but should be more portable.
    803 	     */
    804 	    strncpy(typebuf,typetocheck,TYPEBUFSIZE);
    805 	    for(j=0;j<TYPEBUFSIZE;j++)
    806 		if (isupper(typebuf[j]))
    807 		    typebuf[j]=tolower(typebuf[j]);
    808 
    809 	    /* Now, see if they match */
    810 	    if(!strcmp(LOCALtrans2devtab[i].transname,typebuf))
    811 #else
    812 	    if(!strcasecmp(LOCALtrans2devtab[i].transname,typetocheck))
    813 #endif
    814 		return &LOCALtrans2devtab[i];
    815 	}
    816     }
    817 #if 0
    818     /*NOTREACHED*/
    819     return NULL;
    820 #endif
    821 }
    822 
    823 #ifdef NEED_UTSNAME
    824 #include <sys/utsname.h>
    825 #endif
    826 
    827 /*
    828  * Make sure 'host' is really local.
    829  */
    830 
    831 static int
    832 HostReallyLocal (const char *host)
    833 
    834 {
    835     /*
    836      * The 'host' passed to this function may have been generated
    837      * by either uname() or gethostname().  We try both if possible.
    838      */
    839 
    840 #ifdef NEED_UTSNAME
    841     struct utsname name;
    842 #endif
    843     char buf[256];
    844 
    845 #ifdef NEED_UTSNAME
    846     if (uname (&name) >= 0 && strcmp (host, name.nodename) == 0)
    847 	return (1);
    848 #endif
    849 
    850     buf[0] = '\0';
    851     (void) gethostname (buf, 256);
    852     buf[255] = '\0';
    853 
    854     if (strcmp (host, buf) == 0)
    855 	return (1);
    856 
    857     return (0);
    858 }
    859 
    860 
    861 static XtransConnInfo
    862 TRANS(LocalOpenClient)(int type, const char *protocol,
    863                        const char *host, const char *port)
    864 
    865 {
    866     LOCALtrans2dev *transptr;
    867     XtransConnInfo ciptr;
    868     int index;
    869 
    870     prmsg(3,"LocalOpenClient()\n");
    871 
    872     /*
    873      * Make sure 'host' is really local.  If not, we return failure.
    874      * The reason we make this check is because a process may advertise
    875      * a "local" address for which it can accept connections, but if a
    876      * process on a remote machine tries to connect to this address,
    877      * we know for sure it will fail.
    878      */
    879 
    880     if (strcmp (host, "unix") != 0 && !HostReallyLocal (host))
    881     {
    882 	prmsg (1,
    883 	   "LocalOpenClient: Cannot connect to non-local host %s\n",
    884 	       host);
    885 	return NULL;
    886     }
    887 
    888 
    889 #if defined(X11_t)
    890     /*
    891      * X has a well known port, that is transport dependent. It is easier
    892      * to handle it here, than try and come up with a transport independent
    893      * representation that can be passed in and resolved the usual way.
    894      *
    895      * The port that is passed here is really a string containing the idisplay
    896      * from ConnectDisplay(). Since that is what we want for the local transports,
    897      * we don't have to do anything special.
    898      */
    899 #endif /* X11_t */
    900 
    901     if( (ciptr = calloc(1,sizeof(struct _XtransConnInfo))) == NULL )
    902     {
    903 	prmsg(1,"LocalOpenClient: calloc(1,%lu) failed\n",
    904 	      sizeof(struct _XtransConnInfo));
    905 	return NULL;
    906     }
    907 
    908     ciptr->fd = -1;
    909 
    910     TRANS(LocalInitTransports)(protocol);
    911 
    912     index = 0;
    913     for(transptr=TRANS(LocalGetNextTransport)();
    914 	transptr!=NULL;transptr=TRANS(LocalGetNextTransport)(), index++)
    915     {
    916 	switch( type )
    917 	{
    918 	case XTRANS_OPEN_COTS_CLIENT:
    919 	    ciptr->fd=transptr->devcotsopenclient(ciptr,port);
    920 	    break;
    921 	case XTRANS_OPEN_COTS_SERVER:
    922 	    prmsg(1,
    923 		  "LocalOpenClient: Should not be opening a server with this function\n");
    924 	    break;
    925 	default:
    926 	    prmsg(1,
    927 		  "LocalOpenClient: Unknown Open type %d\n",
    928 		  type);
    929 	}
    930 	if( ciptr->fd >= 0 )
    931 	    break;
    932     }
    933 
    934     TRANS(LocalEndTransports)();
    935 
    936     if( ciptr->fd < 0 )
    937     {
    938 	free(ciptr);
    939 	return NULL;
    940     }
    941 
    942     ciptr->priv=(char *)transptr;
    943     ciptr->index = index;
    944 
    945     return ciptr;
    946 }
    947 
    948 #endif /* TRANS_CLIENT */
    949 
    950 
    951 #ifdef TRANS_SERVER
    952 
    953 static XtransConnInfo
    954 TRANS(LocalOpenServer)(int type, const char *protocol,
    955                        const char *host _X_UNUSED, const char *port)
    956 
    957 {
    958     XtransConnInfo ciptr;
    959 
    960     prmsg(2,"LocalOpenServer(%d,%s,%s)\n", type, protocol, port);
    961 
    962 #if defined(X11_t)
    963     /*
    964      * For X11, the port will be in the format xserverN where N is the
    965      * display number. All of the local connections just need to know
    966      * the display number because they don't do any name resolution on
    967      * the port. This just truncates port to the display portion.
    968      */
    969 #endif /* X11_t */
    970 
    971     if( (ciptr = calloc(1,sizeof(struct _XtransConnInfo))) == NULL )
    972     {
    973 	prmsg(1,"LocalOpenServer: calloc(1,%lu) failed\n",
    974 	      sizeof(struct _XtransConnInfo));
    975 	return NULL;
    976     }
    977 
    978     for (unsigned int i = 1; i < NUMTRANSPORTS; i++)
    979     {
    980 	if( strcmp(protocol,LOCALtrans2devtab[i].transname) != 0 )
    981 	    continue;
    982 	switch( type )
    983 	{
    984 	case XTRANS_OPEN_COTS_CLIENT:
    985 	    prmsg(1,
    986 		  "LocalOpenServer: Should not be opening a client with this function\n");
    987 	    break;
    988 	case XTRANS_OPEN_COTS_SERVER:
    989 	    ciptr->fd=LOCALtrans2devtab[i].devcotsopenserver(ciptr,port);
    990 	    break;
    991 	default:
    992 	    prmsg(1,"LocalOpenServer: Unknown Open type %d\n",
    993 		  type );
    994 	}
    995 	if( ciptr->fd >= 0 ) {
    996 	    ciptr->priv=(char *)&LOCALtrans2devtab[i];
    997 	    ciptr->index=i;
    998 	    ciptr->flags = 1 | (ciptr->flags & TRANS_KEEPFLAGS);
    999 	    return ciptr;
   1000 	}
   1001     }
   1002 
   1003     free(ciptr);
   1004     return NULL;
   1005 }
   1006 
   1007 #endif /* TRANS_SERVER */
   1008 
   1009 
   1010 #ifdef TRANS_REOPEN
   1011 
   1012 static XtransConnInfo
   1013 TRANS(LocalReopenServer)(int type, int index, int fd, const char *port)
   1014 
   1015 {
   1016     XtransConnInfo ciptr;
   1017     int stat = 0;
   1018 
   1019     prmsg(2,"LocalReopenServer(%d,%d,%d)\n", type, index, fd);
   1020 
   1021     if( (ciptr = calloc(1,sizeof(struct _XtransConnInfo))) == NULL )
   1022     {
   1023 	prmsg(1,"LocalReopenServer: calloc(1,%lu) failed\n",
   1024 	      sizeof(struct _XtransConnInfo));
   1025 	return NULL;
   1026     }
   1027 
   1028     ciptr->fd = fd;
   1029 
   1030     switch( type )
   1031     {
   1032     case XTRANS_OPEN_COTS_SERVER:
   1033 	stat = LOCALtrans2devtab[index].devcotsreopenserver(ciptr,fd,port);
   1034 	break;
   1035     default:
   1036 	prmsg(1,"LocalReopenServer: Unknown Open type %d\n",
   1037 	  type );
   1038     }
   1039 
   1040     if( stat > 0 ) {
   1041 	ciptr->priv=(char *)&LOCALtrans2devtab[index];
   1042 	ciptr->index=index;
   1043 	ciptr->flags = 1 | (ciptr->flags & TRANS_KEEPFLAGS);
   1044 	return ciptr;
   1045     }
   1046 
   1047     free(ciptr);
   1048     return NULL;
   1049 }
   1050 
   1051 #endif /* TRANS_REOPEN */
   1052 
   1053 
   1054 
   1055 /*
   1057  * This is the Local implementation of the X Transport service layer
   1058  */
   1059 
   1060 #ifdef TRANS_CLIENT
   1061 
   1062 static XtransConnInfo
   1063 TRANS(LocalOpenCOTSClient)(Xtransport *thistrans _X_UNUSED, const char *protocol,
   1064 			   const char *host, const char *port)
   1065 
   1066 {
   1067     prmsg(2,"LocalOpenCOTSClient(%s,%s,%s)\n",protocol,host,port);
   1068 
   1069     return TRANS(LocalOpenClient)(XTRANS_OPEN_COTS_CLIENT, protocol, host, port);
   1070 }
   1071 
   1072 #endif /* TRANS_CLIENT */
   1073 
   1074 
   1075 #ifdef TRANS_SERVER
   1076 
   1077 static XtransConnInfo
   1078 TRANS(LocalOpenCOTSServer)(Xtransport *thistrans, const char *protocol,
   1079 			   const char *host, const char *port)
   1080 
   1081 {
   1082     char *typetocheck = NULL;
   1083     int found = 0;
   1084 
   1085     prmsg(2,"LocalOpenCOTSServer(%s,%s,%s)\n",protocol,host,port);
   1086 
   1087     /* Check if this local type is in the XLOCAL list */
   1088     TRANS(LocalInitTransports)("local");
   1089     typetocheck = workingXLOCAL;
   1090     while (typetocheck && !found) {
   1091 #ifndef HAVE_STRCASECMP
   1092 	int j;
   1093 	char typebuf[TYPEBUFSIZE];
   1094 #endif
   1095 
   1096 	workingXLOCAL = strchr(workingXLOCAL, ':');
   1097 	if (workingXLOCAL && *workingXLOCAL)
   1098 	    *workingXLOCAL++ = '\0';
   1099 #ifndef HAVE_STRCASECMP
   1100 	strncpy(typebuf, typetocheck, TYPEBUFSIZE);
   1101 	for (j = 0; j < TYPEBUFSIZE; j++)
   1102 	    if (isupper(typebuf[j]))
   1103 		typebuf[j] = tolower(typebuf[j]);
   1104 	if (!strcmp(thistrans->TransName, typebuf))
   1105 #else
   1106 	if (!strcasecmp(thistrans->TransName, typetocheck))
   1107 #endif
   1108 	    found = 1;
   1109 	typetocheck = workingXLOCAL;
   1110     }
   1111     TRANS(LocalEndTransports)();
   1112 
   1113     if (!found) {
   1114 	prmsg(3,"LocalOpenCOTSServer: disabling %s\n",thistrans->TransName);
   1115 	thistrans->flags |= TRANS_DISABLED;
   1116 	return NULL;
   1117     }
   1118 
   1119     return TRANS(LocalOpenServer)(XTRANS_OPEN_COTS_SERVER, protocol, host, port);
   1120 }
   1121 
   1122 #endif /* TRANS_SERVER */
   1123 
   1124 #ifdef TRANS_REOPEN
   1125 
   1126 static XtransConnInfo
   1127 TRANS(LocalReopenCOTSServer)(Xtransport *thistrans, int fd, const char *port)
   1128 
   1129 {
   1130     unsigned int index;
   1131 
   1132     prmsg(2,"LocalReopenCOTSServer(%d,%s)\n", fd, port);
   1133 
   1134     for(index=1;index<NUMTRANSPORTS;index++)
   1135     {
   1136 	if( strcmp(thistrans->TransName,
   1137 	    LOCALtrans2devtab[index].transname) == 0 )
   1138 	    break;
   1139     }
   1140 
   1141     if (index >= NUMTRANSPORTS)
   1142     {
   1143 	return (NULL);
   1144     }
   1145 
   1146     return TRANS(LocalReopenServer)(XTRANS_OPEN_COTS_SERVER,
   1147 	index, fd, port);
   1148 }
   1149 
   1150 #endif /* TRANS_REOPEN */
   1151 
   1152 
   1153 
   1154 static int
   1155 TRANS(LocalSetOption)(XtransConnInfo ciptr, int option, int arg)
   1156 
   1157 {
   1158     prmsg(2,"LocalSetOption(%d,%d,%d)\n",ciptr->fd,option,arg);
   1159 
   1160     return -1;
   1161 }
   1162 
   1163 
   1164 #ifdef TRANS_SERVER
   1165 
   1166 static int
   1167 TRANS(LocalCreateListener)(XtransConnInfo ciptr, const char *port,
   1168                            unsigned int flags _X_UNUSED)
   1169 
   1170 {
   1171     prmsg(2,"LocalCreateListener(%p->%d,%s)\n", (void *) ciptr, ciptr->fd, port);
   1172 
   1173     return 0;
   1174 }
   1175 
   1176 static int
   1177 TRANS(LocalResetListener)(XtransConnInfo ciptr)
   1178 
   1179 {
   1180     LOCALtrans2dev	*transptr;
   1181 
   1182     prmsg(2,"LocalResetListener(%p)\n", (void *) ciptr);
   1183 
   1184     transptr=(LOCALtrans2dev *)ciptr->priv;
   1185     if (transptr->devreset != NULL) {
   1186 	return transptr->devreset(ciptr);
   1187     }
   1188     return TRANS_RESET_NOOP;
   1189 }
   1190 
   1191 
   1192 static XtransConnInfo
   1193 TRANS(LocalAccept)(XtransConnInfo ciptr, int *status)
   1194 
   1195 {
   1196     XtransConnInfo	newciptr;
   1197     LOCALtrans2dev	*transptr;
   1198 
   1199     prmsg(2,"LocalAccept(%p->%d)\n", (void *) ciptr, ciptr->fd);
   1200 
   1201     transptr=(LOCALtrans2dev *)ciptr->priv;
   1202 
   1203     if( (newciptr = calloc(1,sizeof(struct _XtransConnInfo)))==NULL )
   1204     {
   1205 	prmsg(1,"LocalAccept: calloc(1,%lu) failed\n",
   1206 	      sizeof(struct _XtransConnInfo));
   1207 	*status = TRANS_ACCEPT_BAD_MALLOC;
   1208 	return NULL;
   1209     }
   1210 
   1211     newciptr->fd=transptr->devaccept(ciptr,newciptr,status);
   1212 
   1213     if( newciptr->fd < 0 )
   1214     {
   1215 	free(newciptr);
   1216 	return NULL;
   1217     }
   1218 
   1219     newciptr->priv=(char *)transptr;
   1220     newciptr->index = ciptr->index;
   1221 
   1222     *status = 0;
   1223 
   1224     return newciptr;
   1225 }
   1226 
   1227 #endif /* TRANS_SERVER */
   1228 
   1229 
   1230 #ifdef TRANS_CLIENT
   1231 
   1232 static int
   1233 TRANS(LocalConnect)(XtransConnInfo ciptr,
   1234                     const char *host _X_UNUSED, const char *port)
   1235 
   1236 {
   1237     prmsg(2,"LocalConnect(%p->%d,%s)\n", (void *) ciptr, ciptr->fd, port);
   1238 
   1239     return 0;
   1240 }
   1241 
   1242 #endif /* TRANS_CLIENT */
   1243 
   1244 
   1245 static int
   1246 TRANS(LocalBytesReadable)(XtransConnInfo ciptr, BytesReadable_t *pend )
   1247 
   1248 {
   1249     prmsg(2,"LocalBytesReadable(%p->%d,%p)\n",
   1250           (void *) ciptr, ciptr->fd, (void *) pend);
   1251 
   1252     return ioctl(ciptr->fd, FIONREAD, (char *)pend);
   1253 }
   1254 
   1255 static int
   1256 TRANS(LocalRead)(XtransConnInfo ciptr, char *buf, int size)
   1257 
   1258 {
   1259     prmsg(2,"LocalRead(%d,%p,%d)\n", ciptr->fd, (void *) buf, size );
   1260 
   1261     return read(ciptr->fd,buf,size);
   1262 }
   1263 
   1264 static int
   1265 TRANS(LocalWrite)(XtransConnInfo ciptr, const char *buf, int size)
   1266 
   1267 {
   1268     prmsg(2,"LocalWrite(%d,%p,%d)\n", ciptr->fd, (const void *) buf, size );
   1269 
   1270     return write(ciptr->fd,buf,size);
   1271 }
   1272 
   1273 static int
   1274 TRANS(LocalReadv)(XtransConnInfo ciptr, struct iovec *buf, int size)
   1275 
   1276 {
   1277     prmsg(2,"LocalReadv(%d,%p,%d)\n", ciptr->fd, (void *) buf, size );
   1278 
   1279     return READV(ciptr,buf,size);
   1280 }
   1281 
   1282 static int
   1283 TRANS(LocalWritev)(XtransConnInfo ciptr, struct iovec *buf, int size)
   1284 
   1285 {
   1286     prmsg(2,"LocalWritev(%d,%p,%d)\n", ciptr->fd, (const void *) buf, size );
   1287 
   1288     return WRITEV(ciptr,buf,size);
   1289 }
   1290 
   1291 static int
   1292 TRANS(LocalDisconnect)(XtransConnInfo ciptr)
   1293 
   1294 {
   1295     prmsg(2,"LocalDisconnect(%p->%d)\n", (void *) ciptr, ciptr->fd);
   1296 
   1297     return 0;
   1298 }
   1299 
   1300 static int
   1301 TRANS(LocalClose)(XtransConnInfo ciptr)
   1302 
   1303 {
   1304     struct sockaddr_un      *sockname=(struct sockaddr_un *) ciptr->addr;
   1305     int	ret;
   1306 
   1307     prmsg(2,"LocalClose(%p->%d)\n", (void *) ciptr, ciptr->fd );
   1308 
   1309     ret=close(ciptr->fd);
   1310 
   1311     if(ciptr->flags
   1312        && sockname
   1313        && sockname->sun_family == AF_UNIX
   1314        && sockname->sun_path[0] )
   1315     {
   1316 	if (!(ciptr->flags & TRANS_NOUNLINK))
   1317 	    unlink(sockname->sun_path);
   1318     }
   1319 
   1320     return ret;
   1321 }
   1322 
   1323 static int
   1324 TRANS(LocalCloseForCloning)(XtransConnInfo ciptr)
   1325 
   1326 {
   1327     int ret;
   1328 
   1329     prmsg(2,"LocalCloseForCloning(%p->%d)\n", (void *) ciptr, ciptr->fd );
   1330 
   1331     /* Don't unlink path */
   1332 
   1333     ret=close(ciptr->fd);
   1334 
   1335     return ret;
   1336 }
   1337 
   1338 
   1339 /*
   1340  * MakeAllCOTSServerListeners() will go through the entire Xtransports[]
   1341  * array defined in Xtrans.c and try to OpenCOTSServer() for each entry.
   1342  * We will add duplicate entries to that table so that the OpenCOTSServer()
   1343  * function will get called once for each type of local transport.
   1344  *
   1345  * The TransName is in lowercase, so it will never match during a normal
   1346  * call to SelectTransport() in Xtrans.c.
   1347  */
   1348 
   1349 #ifdef TRANS_SERVER
   1350 static const char * local_aliases[] = {
   1351 				  "named",
   1352 				  "pipe", /* compatibility with Solaris Xlib */
   1353 				  NULL };
   1354 #endif
   1355 
   1356 static Xtransport	TRANS(LocalFuncs) = {
   1357 	/* Local Interface */
   1358 	"local",
   1359 	TRANS_ALIAS | TRANS_LOCAL,
   1360 #ifdef TRANS_CLIENT
   1361 	TRANS(LocalOpenCOTSClient),
   1362 #endif /* TRANS_CLIENT */
   1363 #ifdef TRANS_SERVER
   1364 	local_aliases,
   1365 	TRANS(LocalOpenCOTSServer),
   1366 #endif /* TRANS_SERVER */
   1367 #ifdef TRANS_REOPEN
   1368 	TRANS(LocalReopenCOTSServer),
   1369 #endif
   1370 	TRANS(LocalSetOption),
   1371 #ifdef TRANS_SERVER
   1372 	TRANS(LocalCreateListener),
   1373 	TRANS(LocalResetListener),
   1374 	TRANS(LocalAccept),
   1375 #endif /* TRANS_SERVER */
   1376 #ifdef TRANS_CLIENT
   1377 	TRANS(LocalConnect),
   1378 #endif /* TRANS_CLIENT */
   1379 	TRANS(LocalBytesReadable),
   1380 	TRANS(LocalRead),
   1381 	TRANS(LocalWrite),
   1382 	TRANS(LocalReadv),
   1383 	TRANS(LocalWritev),
   1384 #if XTRANS_SEND_FDS
   1385 	TRANS(LocalSendFdInvalid),
   1386 	TRANS(LocalRecvFdInvalid),
   1387 #endif
   1388 	TRANS(LocalDisconnect),
   1389 	TRANS(LocalClose),
   1390 	TRANS(LocalCloseForCloning),
   1391 };
   1392 
   1393 
   1394 #ifdef LOCAL_TRANS_NAMED
   1395 
   1396 static Xtransport	TRANS(NAMEDFuncs) = {
   1397 	/* Local Interface */
   1398 	"named",
   1399 	TRANS_LOCAL,
   1400 #ifdef TRANS_CLIENT
   1401 	TRANS(LocalOpenCOTSClient),
   1402 #endif /* TRANS_CLIENT */
   1403 #ifdef TRANS_SERVER
   1404 	NULL,
   1405 	TRANS(LocalOpenCOTSServer),
   1406 #endif /* TRANS_SERVER */
   1407 #ifdef TRANS_REOPEN
   1408 	TRANS(LocalReopenCOTSServer),
   1409 #endif
   1410 	TRANS(LocalSetOption),
   1411 #ifdef TRANS_SERVER
   1412 	TRANS(LocalCreateListener),
   1413 	TRANS(LocalResetListener),
   1414 	TRANS(LocalAccept),
   1415 #endif /* TRANS_SERVER */
   1416 #ifdef TRANS_CLIENT
   1417 	TRANS(LocalConnect),
   1418 #endif /* TRANS_CLIENT */
   1419 	TRANS(LocalBytesReadable),
   1420 	TRANS(LocalRead),
   1421 	TRANS(LocalWrite),
   1422 	TRANS(LocalReadv),
   1423 	TRANS(LocalWritev),
   1424 #if XTRANS_SEND_FDS
   1425 	TRANS(LocalSendFdInvalid),
   1426 	TRANS(LocalRecvFdInvalid),
   1427 #endif
   1428 	TRANS(LocalDisconnect),
   1429 	TRANS(LocalClose),
   1430 	TRANS(LocalCloseForCloning),
   1431 };
   1432 
   1433 static Xtransport	TRANS(PIPEFuncs) = {
   1434 	/* Local Interface */
   1435 	"pipe",
   1436 	TRANS_ALIAS | TRANS_LOCAL,
   1437 #ifdef TRANS_CLIENT
   1438 	TRANS(LocalOpenCOTSClient),
   1439 #endif /* TRANS_CLIENT */
   1440 #ifdef TRANS_SERVER
   1441 	NULL,
   1442 	TRANS(LocalOpenCOTSServer),
   1443 #endif /* TRANS_SERVER */
   1444 #ifdef TRANS_REOPEN
   1445 	TRANS(LocalReopenCOTSServer),
   1446 #endif
   1447 	TRANS(LocalSetOption),
   1448 #ifdef TRANS_SERVER
   1449 	TRANS(LocalCreateListener),
   1450 	TRANS(LocalResetListener),
   1451 	TRANS(LocalAccept),
   1452 #endif /* TRANS_SERVER */
   1453 #ifdef TRANS_CLIENT
   1454 	TRANS(LocalConnect),
   1455 #endif /* TRANS_CLIENT */
   1456 	TRANS(LocalBytesReadable),
   1457 	TRANS(LocalRead),
   1458 	TRANS(LocalWrite),
   1459 	TRANS(LocalReadv),
   1460 	TRANS(LocalWritev),
   1461 #if XTRANS_SEND_FDS
   1462 	TRANS(LocalSendFdInvalid),
   1463 	TRANS(LocalRecvFdInvalid),
   1464 #endif
   1465 	TRANS(LocalDisconnect),
   1466 	TRANS(LocalClose),
   1467 	TRANS(LocalCloseForCloning),
   1468 };
   1469 #endif /* LOCAL_TRANS_NAMED */
   1470 
   1471 
   1472