Xtranslcl.c revision 75ebec6d
1/* 2 3Copyright 1993, 1994, 1998 The Open Group 4 5Permission to use, copy, modify, distribute, and sell this software and its 6documentation for any purpose is hereby granted without fee, provided that 7the above copyright notice appear in all copies and that both that 8copyright notice and this permission notice appear in supporting 9documentation. 10 11The above copyright notice and this permission notice shall be included 12in all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 18OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20OTHER DEALINGS IN THE SOFTWARE. 21 22Except as contained in this notice, the name of The Open Group shall 23not be used in advertising or otherwise to promote the sale, use or 24other dealings in this Software without prior written authorization 25from 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#ifdef sun 82# include <stropts.h> 83#else 84# include <sys/stropts.h> 85#endif 86#include <sys/wait.h> 87#include <sys/types.h> 88 89/* 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 93 * The X Server. 94 */ 95 96#include <sys/socket.h> 97#ifndef X_NO_SYS_UN 98#include <sys/un.h> 99#endif 100 101 102/* Types of local connections supported: 103 * - PTS 104 * - named pipes 105 * - SCO 106 */ 107#if !defined(sun) 108# define LOCAL_TRANS_PTS 109#endif 110#if defined(SVR4) || defined(__SVR4) 111# define LOCAL_TRANS_NAMED 112#endif 113#if defined(__SCO__) || defined(__UNIXWARE__) 114# define LOCAL_TRANS_SCO 115#endif 116 117static int TRANS(LocalClose)(XtransConnInfo ciptr); 118 119/* 120 * These functions actually implement the local connection mechanisms. 121 */ 122 123/* Type Not Supported */ 124 125static int 126TRANS(OpenFail)(XtransConnInfo ciptr _X_UNUSED, char *port _X_UNUSED) 127 128{ 129 return -1; 130} 131 132#ifdef TRANS_REOPEN 133 134static int 135TRANS(ReopenFail)(XtransConnInfo ciptr _X_UNUSED, int fd _X_UNUSED, char *port _X_UNUSED) 136 137{ 138 return 0; 139} 140 141#endif /* TRANS_REOPEN */ 142 143#if XTRANS_SEND_FDS 144static int 145TRANS(LocalRecvFdInvalid)(XtransConnInfo ciptr) 146{ 147 errno = EINVAL; 148 return -1; 149} 150 151static int 152TRANS(LocalSendFdInvalid)(XtransConnInfo ciptr, int fd, int do_close) 153{ 154 errno = EINVAL; 155 return -1; 156} 157#endif 158 159 160static int 161TRANS(FillAddrInfo)(XtransConnInfo ciptr, char *sun_path, char *peer_sun_path) 162 163{ 164 struct sockaddr_un *sunaddr; 165 struct sockaddr_un *p_sunaddr; 166 167 ciptr->family = AF_UNIX; 168 ciptr->addrlen = sizeof (struct sockaddr_un); 169 170 if ((sunaddr = malloc (ciptr->addrlen)) == NULL) 171 { 172 prmsg(1,"FillAddrInfo: failed to allocate memory for addr\n"); 173 return 0; 174 } 175 176 sunaddr->sun_family = AF_UNIX; 177 178 if (strlen(sun_path) > sizeof(sunaddr->sun_path) - 1) { 179 prmsg(1, "FillAddrInfo: path too long\n"); 180 free((char *) sunaddr); 181 return 0; 182 } 183 strcpy (sunaddr->sun_path, sun_path); 184#if defined(BSD44SOCKETS) 185 sunaddr->sun_len = strlen (sunaddr->sun_path); 186#endif 187 188 ciptr->addr = (char *) sunaddr; 189 190 ciptr->peeraddrlen = sizeof (struct sockaddr_un); 191 192 if ((p_sunaddr = malloc (ciptr->peeraddrlen)) == NULL) 193 { 194 prmsg(1, 195 "FillAddrInfo: failed to allocate memory for peer addr\n"); 196 free (sunaddr); 197 ciptr->addr = NULL; 198 199 return 0; 200 } 201 202 p_sunaddr->sun_family = AF_UNIX; 203 204 if (strlen(peer_sun_path) > sizeof(p_sunaddr->sun_path) - 1) { 205 prmsg(1, "FillAddrInfo: peer path too long\n"); 206 free((char *) p_sunaddr); 207 return 0; 208 } 209 strcpy (p_sunaddr->sun_path, peer_sun_path); 210#if defined(BSD44SOCKETS) 211 p_sunaddr->sun_len = strlen (p_sunaddr->sun_path); 212#endif 213 214 ciptr->peeraddr = (char *) p_sunaddr; 215 216 return 1; 217} 218 219 220 221#ifdef LOCAL_TRANS_PTS 222/* PTS */ 223 224#if defined(SYSV) && !defined(__SCO__) 225#define SIGNAL_T int 226#else 227#define SIGNAL_T void 228#endif /* SYSV */ 229 230typedef SIGNAL_T (*PFV)(); 231 232extern PFV signal(); 233 234extern char *ptsname( 235 int 236); 237 238static void _dummy(int sig _X_UNUSED) 239 240{ 241} 242#endif /* LOCAL_TRANS_PTS */ 243 244#ifndef sun 245#define X_STREAMS_DIR "/dev/X" 246#define DEV_SPX "/dev/spx" 247#else 248#ifndef X11_t 249#define X_STREAMS_DIR "/dev/X" 250#else 251#define X_STREAMS_DIR "/tmp/.X11-pipe" 252#endif 253#endif 254 255#define DEV_PTMX "/dev/ptmx" 256 257#if defined(X11_t) 258 259#define PTSNODENAME "/dev/X/server." 260#ifdef sun 261#define NAMEDNODENAME "/tmp/.X11-pipe/X" 262#else 263#define NAMEDNODENAME "/dev/X/Nserver." 264 265#define SCORNODENAME "/dev/X%1sR" 266#define SCOSNODENAME "/dev/X%1sS" 267#endif /* !sun */ 268#endif 269#if defined(XIM_t) 270#ifdef sun 271#define NAMEDNODENAME "/tmp/.XIM-pipe/XIM" 272#else 273#define PTSNODENAME "/dev/X/XIM." 274#define NAMEDNODENAME "/dev/X/NXIM." 275#define SCORNODENAME "/dev/XIM.%sR" 276#define SCOSNODENAME "/dev/XIM.%sS" 277#endif 278#endif 279#if defined(FS_t) || defined (FONT_t) 280#ifdef sun 281#define NAMEDNODENAME "/tmp/.font-pipe/fs" 282#else 283/* 284 * USL has already defined something here. We need to check with them 285 * and see if their choice is usable here. 286 */ 287#define PTSNODENAME "/dev/X/fontserver." 288#define NAMEDNODENAME "/dev/X/Nfontserver." 289#define SCORNODENAME "/dev/fontserver.%sR" 290#define SCOSNODENAME "/dev/fontserver.%sS" 291#endif 292#endif 293#if defined(ICE_t) 294#ifdef sun 295#define NAMEDNODENAME "/tmp/.ICE-pipe/" 296#else 297#define PTSNODENAME "/dev/X/ICE." 298#define NAMEDNODENAME "/dev/X/NICE." 299#define SCORNODENAME "/dev/ICE.%sR" 300#define SCOSNODENAME "/dev/ICE.%sS" 301#endif 302#endif 303#if defined(TEST_t) 304#ifdef sun 305#define NAMEDNODENAME "/tmp/.Test-unix/test" 306#endif 307#define PTSNODENAME "/dev/X/transtest." 308#define NAMEDNODENAME "/dev/X/Ntranstest." 309#define SCORNODENAME "/dev/transtest.%sR" 310#define SCOSNODENAME "/dev/transtest.%sS" 311#endif 312 313 314 315#ifdef LOCAL_TRANS_PTS 316#ifdef TRANS_CLIENT 317 318static int 319TRANS(PTSOpenClient)(XtransConnInfo ciptr, char *port) 320 321{ 322#ifdef PTSNODENAME 323 int fd,server,exitval,alarm_time,ret; 324 char server_path[64]; 325 char *slave, namelen; 326 char buf[20]; /* MAX_PATH_LEN?? */ 327 PFV savef; 328 pid_t saved_pid; 329#endif 330 331 prmsg(2,"PTSOpenClient(%s)\n", port); 332 333#if !defined(PTSNODENAME) 334 prmsg(1,"PTSOpenClient: Protocol is not supported by a pts connection\n"); 335 return -1; 336#else 337 if (port && *port ) { 338 if( *port == '/' ) { /* A full pathname */ 339 snprintf(server_path, sizeof(server_path), "%s", port); 340 } else { 341 snprintf(server_path, sizeof(server_path), "%s%s", 342 PTSNODENAME, port); 343 } 344 } else { 345 snprintf(server_path, sizeof(server_path), "%s%d", 346 PTSNODENAME, getpid()); 347 } 348 349 350 /* 351 * Open the node the on which the server is listening. 352 */ 353 354 if ((server = open (server_path, O_RDWR)) < 0) { 355 prmsg(1,"PTSOpenClient: failed to open %s\n", server_path); 356 return -1; 357 } 358 359 360 /* 361 * Open the streams based pipe that will be this connection. 362 */ 363 364 if ((fd = open(DEV_PTMX, O_RDWR)) < 0) { 365 prmsg(1,"PTSOpenClient: failed to open %s\n", DEV_PTMX); 366 close(server); 367 return(-1); 368 } 369 370 (void) grantpt(fd); 371 (void) unlockpt(fd); 372 373 slave = ptsname(fd); /* get name */ 374 375 if( slave == NULL ) { 376 prmsg(1,"PTSOpenClient: failed to get ptsname()\n"); 377 close(fd); 378 close(server); 379 return -1; 380 } 381 382 /* 383 * This is neccesary for the case where a program is setuid to non-root. 384 * grantpt() calls /usr/lib/pt_chmod which is set-uid root. This program will 385 * set the owner of the pt device incorrectly if the uid is not restored 386 * before it is called. The problem is that once it gets restored, it 387 * cannot be changed back to its original condition, hence the fork(). 388 */ 389 390 if(!(saved_pid=fork())) { 391 uid_t saved_euid; 392 393 saved_euid = geteuid(); 394 /** sets the euid to the actual/real uid **/ 395 if (setuid( getuid() ) == -1) { 396 exit(1); 397 } 398 if( chown( slave, saved_euid, -1 ) < 0 ) { 399 exit( 1 ); 400 } 401 402 exit( 0 ); 403 } 404 405 waitpid(saved_pid, &exitval, 0); 406 if (WIFEXITED(exitval) && WEXITSTATUS(exitval) != 0) { 407 close(fd); 408 close(server); 409 prmsg(1, "PTSOpenClient: cannot set the owner of %s\n", 410 slave); 411 return(-1); 412 } 413 if (chmod(slave, 0666) < 0) { 414 close(fd); 415 close(server); 416 prmsg(1,"PTSOpenClient: Cannot chmod %s\n", slave); 417 return(-1); 418 } 419 420 /* 421 * write slave name to server 422 */ 423 424 namelen = strlen(slave); 425 buf[0] = namelen; 426 (void) sprintf(&buf[1], slave); 427 (void) write(server, buf, namelen+1); 428 (void) close(server); 429 430 /* 431 * wait for server to respond 432 */ 433 434 savef = signal(SIGALRM, _dummy); 435 alarm_time = alarm (30); /* CONNECT_TIMEOUT */ 436 437 ret = read(fd, buf, 1); 438 439 (void) alarm(alarm_time); 440 (void) signal(SIGALRM, savef); 441 442 if (ret != 1) { 443 prmsg(1, 444 "PTSOpenClient: failed to get acknoledgement from server\n"); 445 (void) close(fd); 446 fd = -1; 447 } 448 449 /* 450 * Everything looks good: fill in the XtransConnInfo structure. 451 */ 452 453 if (TRANS(FillAddrInfo) (ciptr, slave, server_path) == 0) 454 { 455 prmsg(1,"PTSOpenClient: failed to fill in addr info\n"); 456 close(fd); 457 return -1; 458 } 459 460 return(fd); 461 462#endif /* !PTSNODENAME */ 463} 464 465#endif /* TRANS_CLIENT */ 466 467 468#ifdef TRANS_SERVER 469 470static int 471TRANS(PTSOpenServer)(XtransConnInfo ciptr, char *port) 472 473{ 474#ifdef PTSNODENAME 475 int fd, server; 476 char server_path[64], *slave; 477 int mode; 478#endif 479 480 prmsg(2,"PTSOpenServer(%s)\n", port); 481 482#if !defined(PTSNODENAME) 483 prmsg(1,"PTSOpenServer: Protocol is not supported by a pts connection\n"); 484 return -1; 485#else 486 if (port && *port ) { 487 if( *port == '/' ) { /* A full pathname */ 488 (void) sprintf(server_path, "%s", port); 489 } else { 490 (void) sprintf(server_path, "%s%s", PTSNODENAME, port); 491 } 492 } else { 493 (void) sprintf(server_path, "%s%d", PTSNODENAME, getpid()); 494 } 495 496#ifdef HAS_STICKY_DIR_BIT 497 mode = 01777; 498#else 499 mode = 0777; 500#endif 501 if (trans_mkdir(X_STREAMS_DIR, mode) == -1) { 502 prmsg (1, "PTSOpenServer: mkdir(%s) failed, errno = %d\n", 503 X_STREAMS_DIR, errno); 504 return(-1); 505 } 506 507#if 0 508 if( (fd=open(server_path, O_RDWR)) >= 0 ) { 509 /* 510 * This doesn't prevent the server from starting up, and doesn't 511 * prevent clients from trying to connect to the in-use PTS (which 512 * is often in use by something other than another server). 513 */ 514 prmsg(1, "PTSOpenServer: A server is already running on port %s\n", port); 515 prmsg(1, "PTSOpenServer: Remove %s if this is incorrect.\n", server_path); 516 close(fd); 517 return(-1); 518 } 519#else 520 /* Just remove the old path (which is what happens with UNIXCONN) */ 521#endif 522 523 unlink(server_path); 524 525 if( (fd=open(DEV_PTMX, O_RDWR)) < 0) { 526 prmsg(1, "PTSOpenServer: Unable to open %s\n", DEV_PTMX); 527 return(-1); 528 } 529 530 grantpt(fd); 531 unlockpt(fd); 532 533 if( (slave=ptsname(fd)) == NULL) { 534 prmsg(1, "PTSOpenServer: Unable to get slave device name\n"); 535 close(fd); 536 return(-1); 537 } 538 539 if( link(slave,server_path) < 0 ) { 540 prmsg(1, "PTSOpenServer: Unable to link %s to %s\n", slave, server_path); 541 close(fd); 542 return(-1); 543 } 544 545 if( chmod(server_path, 0666) < 0 ) { 546 prmsg(1, "PTSOpenServer: Unable to chmod %s to 0666\n", server_path); 547 close(fd); 548 return(-1); 549 } 550 551 if( (server=open(server_path, O_RDWR)) < 0 ) { 552 prmsg(1, "PTSOpenServer: Unable to open server device %s\n", server_path); 553 close(fd); 554 return(-1); 555 } 556 557 close(server); 558 559 /* 560 * Everything looks good: fill in the XtransConnInfo structure. 561 */ 562 563 if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0) 564 { 565 prmsg(1,"PTSOpenServer: failed to fill in addr info\n"); 566 close(fd); 567 return -1; 568 } 569 570 return fd; 571 572#endif /* !PTSNODENAME */ 573} 574 575static int 576TRANS(PTSAccept)(XtransConnInfo ciptr, XtransConnInfo newciptr, int *status) 577 578{ 579 int newfd; 580 int in; 581 unsigned char length; 582 char buf[256]; 583 struct sockaddr_un *sunaddr; 584 585 prmsg(2,"PTSAccept(%x->%d)\n",ciptr,ciptr->fd); 586 587 if( (in=read(ciptr->fd,&length,1)) <= 0 ){ 588 if( !in ) { 589 prmsg(2, 590 "PTSAccept: Incoming connection closed\n"); 591 } 592 else { 593 prmsg(1, 594 "PTSAccept: Error reading incoming connection. errno=%d \n", 595 errno); 596 } 597 *status = TRANS_ACCEPT_MISC_ERROR; 598 return -1; 599 } 600 601 if( (in=read(ciptr->fd,buf,length)) <= 0 ){ 602 if( !in ) { 603 prmsg(2, 604 "PTSAccept: Incoming connection closed\n"); 605 } 606 else { 607 prmsg(1, 608"PTSAccept: Error reading device name for new connection. errno=%d \n", 609 errno); 610 } 611 *status = TRANS_ACCEPT_MISC_ERROR; 612 return -1; 613 } 614 615 buf[length] = '\0'; 616 617 if( (newfd=open(buf,O_RDWR)) < 0 ) { 618 prmsg(1, "PTSAccept: Failed to open %s\n",buf); 619 *status = TRANS_ACCEPT_MISC_ERROR; 620 return -1; 621 } 622 623 write(newfd,"1",1); 624 625 /* 626 * Everything looks good: fill in the XtransConnInfo structure. 627 */ 628 629 newciptr->addrlen=ciptr->addrlen; 630 if( (newciptr->addr = malloc(newciptr->addrlen)) == NULL ) { 631 prmsg(1,"PTSAccept: failed to allocate memory for peer addr\n"); 632 close(newfd); 633 *status = TRANS_ACCEPT_BAD_MALLOC; 634 return -1; 635 } 636 637 memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen); 638 639 newciptr->peeraddrlen=sizeof(struct sockaddr_un); 640 if( (sunaddr = malloc(newciptr->peeraddrlen)) == NULL ) { 641 prmsg(1,"PTSAccept: failed to allocate memory for peer addr\n"); 642 free(newciptr->addr); 643 close(newfd); 644 *status = TRANS_ACCEPT_BAD_MALLOC; 645 return -1; 646 } 647 648 sunaddr->sun_family=AF_UNIX; 649 strcpy(sunaddr->sun_path,buf); 650#if defined(BSD44SOCKETS) 651 sunaddr->sun_len=strlen(sunaddr->sun_path); 652#endif 653 654 newciptr->peeraddr=(char *)sunaddr; 655 656 *status = 0; 657 658 return newfd; 659} 660 661#endif /* TRANS_SERVER */ 662#endif /* LOCAL_TRANS_PTS */ 663 664 665#ifdef LOCAL_TRANS_NAMED 666 667/* NAMED */ 668 669#ifdef TRANS_CLIENT 670 671static int 672TRANS(NAMEDOpenClient)(XtransConnInfo ciptr, char *port) 673 674{ 675#ifdef NAMEDNODENAME 676 int fd; 677 char server_path[64]; 678 struct stat filestat; 679# ifndef sun 680 extern int isastream(int); 681# endif 682#endif 683 684 prmsg(2,"NAMEDOpenClient(%s)\n", port); 685 686#if !defined(NAMEDNODENAME) 687 prmsg(1,"NAMEDOpenClient: Protocol is not supported by a NAMED connection\n"); 688 return -1; 689#else 690 if ( port && *port ) { 691 if( *port == '/' ) { /* A full pathname */ 692 (void) snprintf(server_path, sizeof(server_path), "%s", port); 693 } else { 694 (void) snprintf(server_path, sizeof(server_path), "%s%s", NAMEDNODENAME, port); 695 } 696 } else { 697 (void) snprintf(server_path, sizeof(server_path), "%s%ld", NAMEDNODENAME, (long)getpid()); 698 } 699 700 if ((fd = open(server_path, O_RDWR)) < 0) { 701 prmsg(1,"NAMEDOpenClient: Cannot open %s for NAMED connection\n", server_path); 702 return -1; 703 } 704 705 if (fstat(fd, &filestat) < 0 ) { 706 prmsg(1,"NAMEDOpenClient: Cannot stat %s for NAMED connection\n", server_path); 707 (void) close(fd); 708 return -1; 709 } 710 711 if ((filestat.st_mode & S_IFMT) != S_IFIFO) { 712 prmsg(1,"NAMEDOpenClient: Device %s is not a FIFO\n", server_path); 713 /* Is this really a failure? */ 714 (void) close(fd); 715 return -1; 716 } 717 718 719 if (isastream(fd) <= 0) { 720 prmsg(1,"NAMEDOpenClient: %s is not a streams device\n", server_path); 721 (void) close(fd); 722 return -1; 723 } 724 725 /* 726 * Everything looks good: fill in the XtransConnInfo structure. 727 */ 728 729 if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0) 730 { 731 prmsg(1,"NAMEDOpenClient: failed to fill in addr info\n"); 732 close(fd); 733 return -1; 734 } 735 736 return(fd); 737 738#endif /* !NAMEDNODENAME */ 739} 740 741#endif /* TRANS_CLIENT */ 742 743 744#ifdef TRANS_SERVER 745 746 747#ifdef NAMEDNODENAME 748static int 749TRANS(NAMEDOpenPipe)(const char *server_path) 750{ 751 int fd, pipefd[2]; 752 struct stat sbuf; 753 int mode; 754 755 prmsg(2,"NAMEDOpenPipe(%s)\n", server_path); 756 757#ifdef HAS_STICKY_DIR_BIT 758 mode = 01777; 759#else 760 mode = 0777; 761#endif 762 if (trans_mkdir(X_STREAMS_DIR, mode) == -1) { 763 prmsg (1, "NAMEDOpenPipe: mkdir(%s) failed, errno = %d\n", 764 X_STREAMS_DIR, errno); 765 return(-1); 766 } 767 768 if(stat(server_path, &sbuf) != 0) { 769 if (errno == ENOENT) { 770 if ((fd = creat(server_path, (mode_t)0666)) == -1) { 771 prmsg(1, "NAMEDOpenPipe: Can't open %s\n", server_path); 772 return(-1); 773 } 774 close(fd); 775 if (chmod(server_path, (mode_t)0666) < 0) { 776 prmsg(1, "NAMEDOpenPipe: Can't open %s\n", server_path); 777 return(-1); 778 } 779 } else { 780 prmsg(1, "NAMEDOpenPipe: stat on %s failed\n", server_path); 781 return(-1); 782 } 783 } 784 785 if( pipe(pipefd) != 0) { 786 prmsg(1, "NAMEDOpenPipe: pipe() failed, errno=%d\n",errno); 787 return(-1); 788 } 789 790 if( ioctl(pipefd[0], I_PUSH, "connld") != 0) { 791 prmsg(1, "NAMEDOpenPipe: ioctl(I_PUSH,\"connld\") failed, errno=%d\n",errno); 792 close(pipefd[0]); 793 close(pipefd[1]); 794 return(-1); 795 } 796 797 if( fattach(pipefd[0], server_path) != 0) { 798 prmsg(1, "NAMEDOpenPipe: fattach(%s) failed, errno=%d\n", server_path,errno); 799 close(pipefd[0]); 800 close(pipefd[1]); 801 return(-1); 802 } 803 804 return(pipefd[1]); 805} 806#endif 807 808static int 809TRANS(NAMEDOpenServer)(XtransConnInfo ciptr, char *port) 810{ 811#ifdef NAMEDNODENAME 812 int fd; 813 char server_path[64]; 814#endif 815 816 prmsg(2,"NAMEDOpenServer(%s)\n", port); 817 818#if !defined(NAMEDNODENAME) 819 prmsg(1,"NAMEDOpenServer: Protocol is not supported by a NAMED connection\n"); 820 return -1; 821#else 822 if ( port && *port ) { 823 if( *port == '/' ) { /* A full pathname */ 824 (void) snprintf(server_path, sizeof(server_path), "%s", port); 825 } else { 826 (void) snprintf(server_path, sizeof(server_path), "%s%s", 827 NAMEDNODENAME, port); 828 } 829 } else { 830 (void) snprintf(server_path, sizeof(server_path), "%s%ld", 831 NAMEDNODENAME, (long)getpid()); 832 } 833 834 fd = TRANS(NAMEDOpenPipe)(server_path); 835 if (fd < 0) { 836 return -1; 837 } 838 839 /* 840 * Everything looks good: fill in the XtransConnInfo structure. 841 */ 842 843 if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0) 844 { 845 prmsg(1,"NAMEDOpenServer: failed to fill in addr info\n"); 846 TRANS(LocalClose)(ciptr); 847 return -1; 848 } 849 850 return fd; 851 852#endif /* !NAMEDNODENAME */ 853} 854 855static int 856TRANS(NAMEDResetListener) (XtransConnInfo ciptr) 857 858{ 859 struct sockaddr_un *sockname=(struct sockaddr_un *) ciptr->addr; 860 struct stat statb; 861 862 prmsg(2,"NAMEDResetListener(%p, %d)\n", ciptr, ciptr->fd); 863 864 if (ciptr->fd != -1) { 865 /* 866 * see if the pipe has disappeared 867 */ 868 869 if (stat (sockname->sun_path, &statb) == -1 || 870 (statb.st_mode & S_IFMT) != S_IFIFO) { 871 prmsg(3, "Pipe %s trashed, recreating\n", sockname->sun_path); 872 TRANS(LocalClose)(ciptr); 873 ciptr->fd = TRANS(NAMEDOpenPipe)(sockname->sun_path); 874 if (ciptr->fd >= 0) 875 return TRANS_RESET_NEW_FD; 876 else 877 return TRANS_CREATE_LISTENER_FAILED; 878 } 879 } 880 return TRANS_RESET_NOOP; 881} 882 883static int 884TRANS(NAMEDAccept)(XtransConnInfo ciptr, XtransConnInfo newciptr, int *status) 885 886{ 887 struct strrecvfd str; 888 889 prmsg(2,"NAMEDAccept(%p->%d)\n", ciptr, ciptr->fd); 890 891 if( ioctl(ciptr->fd, I_RECVFD, &str ) < 0 ) { 892 prmsg(1, "NAMEDAccept: ioctl(I_RECVFD) failed, errno=%d\n", errno); 893 *status = TRANS_ACCEPT_MISC_ERROR; 894 return(-1); 895 } 896 897 /* 898 * Everything looks good: fill in the XtransConnInfo structure. 899 */ 900 newciptr->family=ciptr->family; 901 newciptr->addrlen=ciptr->addrlen; 902 if( (newciptr->addr = malloc(newciptr->addrlen)) == NULL ) { 903 prmsg(1, 904 "NAMEDAccept: failed to allocate memory for pipe addr\n"); 905 close(str.fd); 906 *status = TRANS_ACCEPT_BAD_MALLOC; 907 return -1; 908 } 909 910 memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen); 911 912 newciptr->peeraddrlen=newciptr->addrlen; 913 if( (newciptr->peeraddr = malloc(newciptr->peeraddrlen)) == NULL ) { 914 prmsg(1, 915 "NAMEDAccept: failed to allocate memory for peer addr\n"); 916 free(newciptr->addr); 917 close(str.fd); 918 *status = TRANS_ACCEPT_BAD_MALLOC; 919 return -1; 920 } 921 922 memcpy(newciptr->peeraddr,newciptr->addr,newciptr->peeraddrlen); 923 924 *status = 0; 925 926 return str.fd; 927} 928 929#endif /* TRANS_SERVER */ 930 931#endif /* LOCAL_TRANS_NAMED */ 932 933 934 935#if defined(LOCAL_TRANS_SCO) 936 937/* 938 * connect_spipe is used by the SCO connection type. 939 */ 940static int 941connect_spipe(int fd1, int fd2) 942{ 943 long temp; 944 struct strfdinsert sbuf; 945 946 sbuf.databuf.maxlen = -1; 947 sbuf.databuf.len = -1; 948 sbuf.databuf.buf = NULL; 949 sbuf.ctlbuf.maxlen = sizeof(long); 950 sbuf.ctlbuf.len = sizeof(long); 951 sbuf.ctlbuf.buf = (caddr_t)&temp; 952 sbuf.offset = 0; 953 sbuf.fildes = fd2; 954 sbuf.flags = 0; 955 956 if( ioctl(fd1, I_FDINSERT, &sbuf) < 0 ) 957 return(-1); 958 959 return(0); 960} 961 962/* 963 * named_spipe is used by the SCO connection type. 964 */ 965 966static int 967named_spipe(int fd, char *path) 968 969{ 970 int oldUmask, ret; 971 struct stat sbuf; 972 973 oldUmask = umask(0); 974 975 (void) fstat(fd, &sbuf); 976 ret = mknod(path, 0020666, sbuf.st_rdev); 977 978 umask(oldUmask); 979 980 if (ret < 0) { 981 ret = -1; 982 } else { 983 ret = fd; 984 } 985 986 return(ret); 987} 988 989#endif /* defined(LOCAL_TRANS_SCO) */ 990 991 992 993 994#ifdef LOCAL_TRANS_SCO 995/* SCO */ 996 997/* 998 * 2002-11-09 (jkj@sco.com) 999 * 1000 * This code has been modified to match what is in the actual SCO X server. 1001 * This greatly helps inter-operability between X11R6 and X11R5 (the native 1002 * SCO server). Mainly, it relies on streams nodes existing in /dev, not 1003 * creating them or unlinking them, which breaks the native X server. 1004 * 1005 * However, this is only for the X protocol. For all other protocols, we 1006 * do in fact create the nodes, as only X11R6 will use them, and this makes 1007 * it possible to have both types of clients running, otherwise we get all 1008 * kinds of nasty errors on startup for anything that doesnt use the X 1009 * protocol (like SM, when KDE starts up). 1010 */ 1011 1012#ifdef TRANS_CLIENT 1013 1014static int 1015TRANS(SCOOpenClient)(XtransConnInfo ciptr, char *port) 1016{ 1017#ifdef SCORNODENAME 1018 int fd, server, fl, ret; 1019 char server_path[64]; 1020 struct strbuf ctlbuf; 1021 unsigned long alarm_time; 1022 void (*savef)(); 1023 long temp; 1024 extern int getmsg(), putmsg(); 1025#endif 1026 1027 prmsg(2,"SCOOpenClient(%s)\n", port); 1028 if (!port || !port[0]) 1029 port = "0"; 1030 1031#if !defined(SCORNODENAME) 1032 prmsg(2,"SCOOpenClient: Protocol is not supported by a SCO connection\n"); 1033 return -1; 1034#else 1035 (void) sprintf(server_path, SCORNODENAME, port); 1036 1037 if ((server = open(server_path, O_RDWR)) < 0) { 1038 prmsg(1,"SCOOpenClient: failed to open %s\n", server_path); 1039 return -1; 1040 } 1041 1042 if ((fd = open(DEV_SPX, O_RDWR)) < 0) { 1043 prmsg(1,"SCOOpenClient: failed to open %s\n", DEV_SPX); 1044 close(server); 1045 return -1; 1046 } 1047 1048 (void) write(server, &server, 1); 1049 ctlbuf.len = 0; 1050 ctlbuf.maxlen = sizeof(long); 1051 ctlbuf.buf = (caddr_t)&temp; 1052 fl = 0; 1053 1054 savef = signal(SIGALRM, _dummy); 1055 alarm_time = alarm(10); 1056 1057 ret = getmsg(server, &ctlbuf, 0, &fl); 1058 1059 (void) alarm(alarm_time); 1060 (void) signal(SIGALRM, savef); 1061 1062 if (ret < 0) { 1063 prmsg(1,"SCOOpenClient: error from getmsg\n"); 1064 close(fd); 1065 close(server); 1066 return -1; 1067 } 1068 1069 /* The msg we got via getmsg is the result of an 1070 * I_FDINSERT, so if we do a putmsg with whatever 1071 * we recieved, we're doing another I_FDINSERT ... 1072 */ 1073 (void) putmsg(fd, &ctlbuf, 0, 0); 1074 (void) fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,0)|O_NDELAY); 1075 1076 (void) close(server); 1077 1078 /* 1079 * Everything looks good: fill in the XtransConnInfo structure. 1080 */ 1081 1082#if defined(X11_t) && defined(__SCO__) 1083 ciptr->flags |= TRANS_NOUNLINK; 1084#endif 1085 if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0) 1086 { 1087 prmsg(1,"SCOOpenClient: failed to fill addr info\n"); 1088 close(fd); 1089 return -1; 1090 } 1091 1092 return(fd); 1093 1094#endif /* !SCORNODENAME */ 1095} 1096 1097#endif /* TRANS_CLIENT */ 1098 1099 1100#ifdef TRANS_SERVER 1101 1102static int 1103TRANS(SCOOpenServer)(XtransConnInfo ciptr, char *port) 1104{ 1105#ifdef SCORNODENAME 1106 char serverR_path[64]; 1107 char serverS_path[64]; 1108 struct flock mylock; 1109 int fdr = -1; 1110 int fds = -1; 1111#endif 1112 1113 prmsg(2,"SCOOpenServer(%s)\n", port); 1114 if (!port || !port[0]) 1115 port = "0"; 1116 1117#if !defined(SCORNODENAME) 1118 prmsg(1,"SCOOpenServer: Protocol is not supported by a SCO connection\n"); 1119 return -1; 1120#else 1121 (void) sprintf(serverR_path, SCORNODENAME, port); 1122 (void) sprintf(serverS_path, SCOSNODENAME, port); 1123 1124#if !defined(X11_t) || !defined(__SCO__) 1125 unlink(serverR_path); 1126 unlink(serverS_path); 1127 1128 if ((fds = open(DEV_SPX, O_RDWR)) < 0 || 1129 (fdr = open(DEV_SPX, O_RDWR)) < 0 ) { 1130 prmsg(1,"SCOOpenServer: failed to open %s\n", DEV_SPX); 1131 if (fds >= 0) 1132 close(fds); 1133 if (fdr >= 0) 1134 close(fdr); 1135 return -1; 1136 } 1137 1138 if (named_spipe (fds, serverS_path) == -1) { 1139 prmsg(1,"SCOOpenServer: failed to create %s\n", serverS_path); 1140 close (fdr); 1141 close (fds); 1142 return -1; 1143 } 1144 1145 if (named_spipe (fdr, serverR_path) == -1) { 1146 prmsg(1,"SCOOpenServer: failed to create %s\n", serverR_path); 1147 close (fdr); 1148 close (fds); 1149 return -1; 1150 } 1151#else /* X11_t */ 1152 1153 fds = open (serverS_path, O_RDWR | O_NDELAY); 1154 if (fds < 0) { 1155 prmsg(1,"SCOOpenServer: failed to open %s\n", serverS_path); 1156 return -1; 1157 } 1158 1159 /* 1160 * Lock the connection device for the duration of the server. 1161 * This resolves multiple server starts especially on SMP machines. 1162 */ 1163 mylock.l_type = F_WRLCK; 1164 mylock.l_whence = 0; 1165 mylock.l_start = 0; 1166 mylock.l_len = 0; 1167 if (fcntl (fds, F_SETLK, &mylock) < 0) { 1168 prmsg(1,"SCOOpenServer: failed to lock %s\n", serverS_path); 1169 close (fds); 1170 return -1; 1171 } 1172 1173 fdr = open (serverR_path, O_RDWR | O_NDELAY); 1174 if (fdr < 0) { 1175 prmsg(1,"SCOOpenServer: failed to open %s\n", serverR_path); 1176 close (fds); 1177 return -1; 1178 } 1179#endif /* X11_t */ 1180 1181 if (connect_spipe(fds, fdr)) { 1182 prmsg(1,"SCOOpenServer: ioctl(I_FDINSERT) failed on %s\n", 1183 serverS_path); 1184 close (fdr); 1185 close (fds); 1186 return -1; 1187 } 1188 1189 /* 1190 * Everything looks good: fill in the XtransConnInfo structure. 1191 */ 1192 1193#if defined(X11_t) && defined(__SCO__) 1194 ciptr->flags |= TRANS_NOUNLINK; 1195#endif 1196 if (TRANS(FillAddrInfo) (ciptr, serverS_path, serverR_path) == 0) { 1197 prmsg(1,"SCOOpenServer: failed to fill in addr info\n"); 1198 close(fds); 1199 close(fdr); 1200 return -1; 1201 } 1202 1203 return(fds); 1204 1205#endif /* !SCORNODENAME */ 1206} 1207 1208static int 1209TRANS(SCOAccept)(XtransConnInfo ciptr, XtransConnInfo newciptr, int *status) 1210{ 1211 char c; 1212 int fd; 1213 1214 prmsg(2,"SCOAccept(%d)\n", ciptr->fd); 1215 1216 if (read(ciptr->fd, &c, 1) < 0) { 1217 prmsg(1,"SCOAccept: can't read from client\n"); 1218 *status = TRANS_ACCEPT_MISC_ERROR; 1219 return(-1); 1220 } 1221 1222 if( (fd = open(DEV_SPX, O_RDWR)) < 0 ) { 1223 prmsg(1,"SCOAccept: can't open \"%s\"\n",DEV_SPX); 1224 *status = TRANS_ACCEPT_MISC_ERROR; 1225 return(-1); 1226 } 1227 1228 if (connect_spipe (ciptr->fd, fd) < 0) { 1229 prmsg(1,"SCOAccept: ioctl(I_FDINSERT) failed\n"); 1230 close (fd); 1231 *status = TRANS_ACCEPT_MISC_ERROR; 1232 return -1; 1233 } 1234 1235 /* 1236 * Everything looks good: fill in the XtransConnInfo structure. 1237 */ 1238 1239 newciptr->addrlen=ciptr->addrlen; 1240 if( (newciptr->addr = malloc(newciptr->addrlen)) == NULL ) { 1241 prmsg(1, 1242 "SCOAccept: failed to allocate memory for peer addr\n"); 1243 close(fd); 1244 *status = TRANS_ACCEPT_BAD_MALLOC; 1245 return -1; 1246 } 1247 1248 memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen); 1249#if defined(__SCO__) 1250 newciptr->flags |= TRANS_NOUNLINK; 1251#endif 1252 1253 newciptr->peeraddrlen=newciptr->addrlen; 1254 if( (newciptr->peeraddr = malloc(newciptr->peeraddrlen)) == NULL ) { 1255 prmsg(1, 1256 "SCOAccept: failed to allocate memory for peer addr\n"); 1257 free(newciptr->addr); 1258 close(fd); 1259 *status = TRANS_ACCEPT_BAD_MALLOC; 1260 return -1; 1261 } 1262 1263 memcpy(newciptr->peeraddr,newciptr->addr,newciptr->peeraddrlen); 1264 1265 *status = 0; 1266 1267 return(fd); 1268} 1269 1270#endif /* TRANS_SERVER */ 1271#endif /* LOCAL_TRANS_SCO */ 1272 1273 1274 1275#ifdef TRANS_REOPEN 1276#ifdef LOCAL_TRANS_PTS 1277 1278static int 1279TRANS(PTSReopenServer)(XtransConnInfo ciptr, int fd, char *port) 1280 1281{ 1282#ifdef PTSNODENAME 1283 char server_path[64]; 1284#endif 1285 1286 prmsg(2,"PTSReopenServer(%d,%s)\n", fd, port); 1287 1288#if !defined(PTSNODENAME) 1289 prmsg(1,"PTSReopenServer: Protocol is not supported by a pts connection\n"); 1290 return 0; 1291#else 1292 if (port && *port ) { 1293 if( *port == '/' ) { /* A full pathname */ 1294 snprintf(server_path, sizeof(server_path), "%s", port); 1295 } else { 1296 snprintf(server_path, sizeof(server_path), "%s%s", 1297 PTSNODENAME, port); 1298 } 1299 } else { 1300 snprintf(server_path, sizeof(server_path), "%s%ld", 1301 PTSNODENAME, (long)getpid()); 1302 } 1303 1304 if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0) 1305 { 1306 prmsg(1,"PTSReopenServer: failed to fill in addr info\n"); 1307 return 0; 1308 } 1309 1310 return 1; 1311 1312#endif /* !PTSNODENAME */ 1313} 1314 1315#endif /* LOCAL_TRANS_PTS */ 1316 1317#ifdef LOCAL_TRANS_NAMED 1318 1319static int 1320TRANS(NAMEDReopenServer)(XtransConnInfo ciptr, int fd _X_UNUSED, char *port) 1321 1322{ 1323#ifdef NAMEDNODENAME 1324 char server_path[64]; 1325#endif 1326 1327 prmsg(2,"NAMEDReopenServer(%s)\n", port); 1328 1329#if !defined(NAMEDNODENAME) 1330 prmsg(1,"NAMEDReopenServer: Protocol is not supported by a NAMED connection\n"); 1331 return 0; 1332#else 1333 if ( port && *port ) { 1334 if( *port == '/' ) { /* A full pathname */ 1335 snprintf(server_path, sizeof(server_path),"%s", port); 1336 } else { 1337 snprintf(server_path, sizeof(server_path), "%s%s", 1338 NAMEDNODENAME, port); 1339 } 1340 } else { 1341 snprintf(server_path, sizeof(server_path), "%s%ld", 1342 NAMEDNODENAME, (long)getpid()); 1343 } 1344 1345 if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0) 1346 { 1347 prmsg(1,"NAMEDReopenServer: failed to fill in addr info\n"); 1348 return 0; 1349 } 1350 1351 return 1; 1352 1353#endif /* !NAMEDNODENAME */ 1354} 1355 1356#endif /* LOCAL_TRANS_NAMED */ 1357 1358 1359#ifdef LOCAL_TRANS_SCO 1360static int 1361TRANS(SCOReopenServer)(XtransConnInfo ciptr, int fd, char *port) 1362 1363{ 1364#ifdef SCORNODENAME 1365 char serverR_path[64], serverS_path[64]; 1366#endif 1367 1368 prmsg(2,"SCOReopenServer(%s)\n", port); 1369 if (!port || !port[0]) 1370 port = "0"; 1371 1372#if !defined(SCORNODENAME) 1373 prmsg(2,"SCOReopenServer: Protocol is not supported by a SCO connection\n"); 1374 return 0; 1375#else 1376 (void) sprintf(serverR_path, SCORNODENAME, port); 1377 (void) sprintf(serverS_path, SCOSNODENAME, port); 1378 1379#if defined(X11_t) && defined(__SCO__) 1380 ciptr->flags |= TRANS_NOUNLINK; 1381#endif 1382 if (TRANS(FillAddrInfo) (ciptr, serverS_path, serverR_path) == 0) 1383 { 1384 prmsg(1, "SCOReopenServer: failed to fill in addr info\n"); 1385 return 0; 1386 } 1387 1388 return 1; 1389 1390#endif /* SCORNODENAME */ 1391} 1392 1393#endif /* LOCAL_TRANS_SCO */ 1394 1395#endif /* TRANS_REOPEN */ 1396 1397 1398 1399/* 1400 * This table contains all of the entry points for the different local 1401 * connection mechanisms. 1402 */ 1403 1404typedef struct _LOCALtrans2dev { 1405 const char *transname; 1406 1407#ifdef TRANS_CLIENT 1408 1409 int (*devcotsopenclient)( 1410 XtransConnInfo, char * /*port*/ 1411); 1412 1413#endif /* TRANS_CLIENT */ 1414 1415#ifdef TRANS_SERVER 1416 1417 int (*devcotsopenserver)( 1418 XtransConnInfo, char * /*port*/ 1419); 1420 1421#endif /* TRANS_SERVER */ 1422 1423#ifdef TRANS_CLIENT 1424 1425 int (*devcltsopenclient)( 1426 XtransConnInfo, char * /*port*/ 1427); 1428 1429#endif /* TRANS_CLIENT */ 1430 1431#ifdef TRANS_SERVER 1432 1433 int (*devcltsopenserver)( 1434 XtransConnInfo, char * /*port*/ 1435); 1436 1437#endif /* TRANS_SERVER */ 1438 1439#ifdef TRANS_REOPEN 1440 1441 int (*devcotsreopenserver)( 1442 XtransConnInfo, 1443 int, /* fd */ 1444 char * /* port */ 1445); 1446 1447 int (*devcltsreopenserver)( 1448 XtransConnInfo, 1449 int, /* fd */ 1450 char * /* port */ 1451); 1452 1453#endif /* TRANS_REOPEN */ 1454 1455#ifdef TRANS_SERVER 1456 1457 int (*devreset)( 1458 XtransConnInfo /* ciptr */ 1459); 1460 1461 int (*devaccept)( 1462 XtransConnInfo, XtransConnInfo, int * 1463); 1464 1465#endif /* TRANS_SERVER */ 1466 1467} LOCALtrans2dev; 1468 1469static LOCALtrans2dev LOCALtrans2devtab[] = { 1470#ifdef LOCAL_TRANS_PTS 1471{"", 1472#ifdef TRANS_CLIENT 1473 TRANS(PTSOpenClient), 1474#endif /* TRANS_CLIENT */ 1475#ifdef TRANS_SERVER 1476 TRANS(PTSOpenServer), 1477#endif /* TRANS_SERVER */ 1478#ifdef TRANS_CLIENT 1479 TRANS(OpenFail), 1480#endif /* TRANS_CLIENT */ 1481#ifdef TRANS_SERVER 1482 TRANS(OpenFail), 1483#endif /* TRANS_SERVER */ 1484#ifdef TRANS_REOPEN 1485 TRANS(PTSReopenServer), 1486 TRANS(ReopenFail), 1487#endif 1488#ifdef TRANS_SERVER 1489 NULL, /* ResetListener */ 1490 TRANS(PTSAccept) 1491#endif /* TRANS_SERVER */ 1492}, 1493 1494{"local", 1495#ifdef TRANS_CLIENT 1496 TRANS(PTSOpenClient), 1497#endif /* TRANS_CLIENT */ 1498#ifdef TRANS_SERVER 1499 TRANS(PTSOpenServer), 1500#endif /* TRANS_SERVER */ 1501#ifdef TRANS_CLIENT 1502 TRANS(OpenFail), 1503#endif /* TRANS_CLIENT */ 1504#ifdef TRANS_SERVER 1505 TRANS(OpenFail), 1506#endif /* TRANS_SERVER */ 1507#ifdef TRANS_REOPEN 1508 TRANS(PTSReopenServer), 1509 TRANS(ReopenFail), 1510#endif 1511#ifdef TRANS_SERVER 1512 NULL, /* ResetListener */ 1513 TRANS(PTSAccept) 1514#endif /* TRANS_SERVER */ 1515}, 1516 1517{"pts", 1518#ifdef TRANS_CLIENT 1519 TRANS(PTSOpenClient), 1520#endif /* TRANS_CLIENT */ 1521#ifdef TRANS_SERVER 1522 TRANS(PTSOpenServer), 1523#endif /* TRANS_SERVER */ 1524#ifdef TRANS_CLIENT 1525 TRANS(OpenFail), 1526#endif /* TRANS_CLIENT */ 1527#ifdef TRANS_SERVER 1528 TRANS(OpenFail), 1529#endif /* TRANS_SERVER */ 1530#ifdef TRANS_REOPEN 1531 TRANS(PTSReopenServer), 1532 TRANS(ReopenFail), 1533#endif 1534#ifdef TRANS_SERVER 1535 NULL, /* ResetListener */ 1536 TRANS(PTSAccept) 1537#endif /* TRANS_SERVER */ 1538}, 1539#else /* !LOCAL_TRANS_PTS */ 1540{"", 1541#ifdef TRANS_CLIENT 1542 TRANS(NAMEDOpenClient), 1543#endif /* TRANS_CLIENT */ 1544#ifdef TRANS_SERVER 1545 TRANS(NAMEDOpenServer), 1546#endif /* TRANS_SERVER */ 1547#ifdef TRANS_CLIENT 1548 TRANS(OpenFail), 1549#endif /* TRANS_CLIENT */ 1550#ifdef TRANS_SERVER 1551 TRANS(OpenFail), 1552#endif /* TRANS_SERVER */ 1553#ifdef TRANS_REOPEN 1554 TRANS(NAMEDReopenServer), 1555 TRANS(ReopenFail), 1556#endif 1557#ifdef TRANS_SERVER 1558 TRANS(NAMEDResetListener), 1559 TRANS(NAMEDAccept) 1560#endif /* TRANS_SERVER */ 1561}, 1562 1563{"local", 1564#ifdef TRANS_CLIENT 1565 TRANS(NAMEDOpenClient), 1566#endif /* TRANS_CLIENT */ 1567#ifdef TRANS_SERVER 1568 TRANS(NAMEDOpenServer), 1569#endif /* TRANS_SERVER */ 1570#ifdef TRANS_CLIENT 1571 TRANS(OpenFail), 1572#endif /* TRANS_CLIENT */ 1573#ifdef TRANS_SERVER 1574 TRANS(OpenFail), 1575#endif /* TRANS_SERVER */ 1576#ifdef TRANS_REOPEN 1577 TRANS(NAMEDReopenServer), 1578 TRANS(ReopenFail), 1579#endif 1580#ifdef TRANS_SERVER 1581 TRANS(NAMEDResetListener), 1582 TRANS(NAMEDAccept) 1583#endif /* TRANS_SERVER */ 1584}, 1585#endif /* !LOCAL_TRANS_PTS */ 1586 1587#ifdef LOCAL_TRANS_NAMED 1588{"named", 1589#ifdef TRANS_CLIENT 1590 TRANS(NAMEDOpenClient), 1591#endif /* TRANS_CLIENT */ 1592#ifdef TRANS_SERVER 1593 TRANS(NAMEDOpenServer), 1594#endif /* TRANS_SERVER */ 1595#ifdef TRANS_CLIENT 1596 TRANS(OpenFail), 1597#endif /* TRANS_CLIENT */ 1598#ifdef TRANS_SERVER 1599 TRANS(OpenFail), 1600#endif /* TRANS_SERVER */ 1601#ifdef TRANS_REOPEN 1602 TRANS(NAMEDReopenServer), 1603 TRANS(ReopenFail), 1604#endif 1605#ifdef TRANS_SERVER 1606 TRANS(NAMEDResetListener), 1607 TRANS(NAMEDAccept) 1608#endif /* TRANS_SERVER */ 1609}, 1610 1611#ifdef sun /* Alias "pipe" to named, since that's what Solaris called it */ 1612{"pipe", 1613#ifdef TRANS_CLIENT 1614 TRANS(NAMEDOpenClient), 1615#endif /* TRANS_CLIENT */ 1616#ifdef TRANS_SERVER 1617 TRANS(NAMEDOpenServer), 1618#endif /* TRANS_SERVER */ 1619#ifdef TRANS_CLIENT 1620 TRANS(OpenFail), 1621#endif /* TRANS_CLIENT */ 1622#ifdef TRANS_SERVER 1623 TRANS(OpenFail), 1624#endif /* TRANS_SERVER */ 1625#ifdef TRANS_REOPEN 1626 TRANS(NAMEDReopenServer), 1627 TRANS(ReopenFail), 1628#endif 1629#ifdef TRANS_SERVER 1630 TRANS(NAMEDResetListener), 1631 TRANS(NAMEDAccept) 1632#endif /* TRANS_SERVER */ 1633}, 1634#endif /* sun */ 1635#endif /* LOCAL_TRANS_NAMED */ 1636 1637 1638#ifdef LOCAL_TRANS_SCO 1639{"sco", 1640#ifdef TRANS_CLIENT 1641 TRANS(SCOOpenClient), 1642#endif /* TRANS_CLIENT */ 1643#ifdef TRANS_SERVER 1644 TRANS(SCOOpenServer), 1645#endif /* TRANS_SERVER */ 1646#ifdef TRANS_CLIENT 1647 TRANS(OpenFail), 1648#endif /* TRANS_CLIENT */ 1649#ifdef TRANS_SERVER 1650 TRANS(OpenFail), 1651#endif /* TRANS_SERVER */ 1652#ifdef TRANS_REOPEN 1653 TRANS(SCOReopenServer), 1654 TRANS(ReopenFail), 1655#endif 1656#ifdef TRANS_SERVER 1657 NULL, /* ResetListener */ 1658 TRANS(SCOAccept) 1659#endif /* TRANS_SERVER */ 1660}, 1661#endif /* LOCAL_TRANS_SCO */ 1662}; 1663 1664#define NUMTRANSPORTS (sizeof(LOCALtrans2devtab)/sizeof(LOCALtrans2dev)) 1665 1666static const char *XLOCAL=NULL; 1667static char *workingXLOCAL=NULL; 1668static char *freeXLOCAL=NULL; 1669 1670#if defined(__SCO__) 1671#define DEF_XLOCAL "SCO:UNIX:PTS" 1672#elif defined(__UNIXWARE__) 1673#define DEF_XLOCAL "UNIX:PTS:NAMED:SCO" 1674#elif defined(sun) 1675#define DEF_XLOCAL "UNIX:NAMED" 1676#else 1677#define DEF_XLOCAL "UNIX:PTS:NAMED:SCO" 1678#endif 1679 1680static void 1681TRANS(LocalInitTransports)(const char *protocol) 1682 1683{ 1684 prmsg(3,"LocalInitTransports(%s)\n", protocol); 1685 1686 if( strcmp(protocol,"local") && strcmp(protocol,"LOCAL") ) 1687 { 1688 workingXLOCAL = freeXLOCAL = strdup (protocol); 1689 } 1690 else { 1691 XLOCAL=(char *)getenv("XLOCAL"); 1692 if(XLOCAL==NULL) 1693 XLOCAL=DEF_XLOCAL; 1694 workingXLOCAL = freeXLOCAL = strdup (XLOCAL); 1695 } 1696} 1697 1698static void 1699TRANS(LocalEndTransports)(void) 1700 1701{ 1702 prmsg(3,"LocalEndTransports()\n"); 1703 free(freeXLOCAL); 1704} 1705 1706#define TYPEBUFSIZE 32 1707 1708#ifdef TRANS_CLIENT 1709 1710static LOCALtrans2dev * 1711TRANS(LocalGetNextTransport)(void) 1712 1713{ 1714 int i,j; 1715 char *typetocheck; 1716 char typebuf[TYPEBUFSIZE]; 1717 prmsg(3,"LocalGetNextTransport()\n"); 1718 1719 while(1) 1720 { 1721 if( workingXLOCAL == NULL || *workingXLOCAL == '\0' ) 1722 return NULL; 1723 1724 typetocheck=workingXLOCAL; 1725 workingXLOCAL=strchr(workingXLOCAL,':'); 1726 if(workingXLOCAL && *workingXLOCAL) 1727 *workingXLOCAL++='\0'; 1728 1729 for(i=0;i<NUMTRANSPORTS;i++) 1730 { 1731 /* 1732 * This is equivalent to a case insensitive strcmp(), 1733 * but should be more portable. 1734 */ 1735 strncpy(typebuf,typetocheck,TYPEBUFSIZE); 1736 for(j=0;j<TYPEBUFSIZE;j++) 1737 if (isupper(typebuf[j])) 1738 typebuf[j]=tolower(typebuf[j]); 1739 1740 /* Now, see if they match */ 1741 if(!strcmp(LOCALtrans2devtab[i].transname,typebuf)) 1742 return &LOCALtrans2devtab[i]; 1743 } 1744 } 1745#if 0 1746 /*NOTREACHED*/ 1747 return NULL; 1748#endif 1749} 1750 1751#ifdef NEED_UTSNAME 1752#include <sys/utsname.h> 1753#endif 1754 1755/* 1756 * Make sure 'host' is really local. 1757 */ 1758 1759static int 1760HostReallyLocal (char *host) 1761 1762{ 1763 /* 1764 * The 'host' passed to this function may have been generated 1765 * by either uname() or gethostname(). We try both if possible. 1766 */ 1767 1768#ifdef NEED_UTSNAME 1769 struct utsname name; 1770#endif 1771 char buf[256]; 1772 1773#ifdef NEED_UTSNAME 1774 if (uname (&name) >= 0 && strcmp (host, name.nodename) == 0) 1775 return (1); 1776#endif 1777 1778 buf[0] = '\0'; 1779 (void) gethostname (buf, 256); 1780 buf[255] = '\0'; 1781 1782 if (strcmp (host, buf) == 0) 1783 return (1); 1784 1785 return (0); 1786} 1787 1788 1789static XtransConnInfo 1790TRANS(LocalOpenClient)(int type, char *protocol, char *host, char *port) 1791 1792{ 1793 LOCALtrans2dev *transptr; 1794 XtransConnInfo ciptr; 1795 int index; 1796 1797 prmsg(3,"LocalOpenClient()\n"); 1798 1799 /* 1800 * Make sure 'host' is really local. If not, we return failure. 1801 * The reason we make this check is because a process may advertise 1802 * a "local" address for which it can accept connections, but if a 1803 * process on a remote machine tries to connect to this address, 1804 * we know for sure it will fail. 1805 */ 1806 1807 if (strcmp (host, "unix") != 0 && !HostReallyLocal (host)) 1808 { 1809 prmsg (1, 1810 "LocalOpenClient: Cannot connect to non-local host %s\n", 1811 host); 1812 return NULL; 1813 } 1814 1815 1816#if defined(X11_t) 1817 /* 1818 * X has a well known port, that is transport dependant. It is easier 1819 * to handle it here, than try and come up with a transport independent 1820 * representation that can be passed in and resolved the usual way. 1821 * 1822 * The port that is passed here is really a string containing the idisplay 1823 * from ConnectDisplay(). Since that is what we want for the local transports, 1824 * we don't have to do anything special. 1825 */ 1826#endif /* X11_t */ 1827 1828 if( (ciptr = calloc(1,sizeof(struct _XtransConnInfo))) == NULL ) 1829 { 1830 prmsg(1,"LocalOpenClient: calloc(1,%lu) failed\n", 1831 sizeof(struct _XtransConnInfo)); 1832 return NULL; 1833 } 1834 1835 ciptr->fd = -1; 1836 1837 TRANS(LocalInitTransports)(protocol); 1838 1839 index = 0; 1840 for(transptr=TRANS(LocalGetNextTransport)(); 1841 transptr!=NULL;transptr=TRANS(LocalGetNextTransport)(), index++) 1842 { 1843 switch( type ) 1844 { 1845 case XTRANS_OPEN_COTS_CLIENT: 1846 ciptr->fd=transptr->devcotsopenclient(ciptr,port); 1847 break; 1848 case XTRANS_OPEN_CLTS_CLIENT: 1849 ciptr->fd=transptr->devcltsopenclient(ciptr,port); 1850 break; 1851 case XTRANS_OPEN_COTS_SERVER: 1852 case XTRANS_OPEN_CLTS_SERVER: 1853 prmsg(1, 1854 "LocalOpenClient: Should not be opening a server with this function\n"); 1855 break; 1856 default: 1857 prmsg(1, 1858 "LocalOpenClient: Unknown Open type %d\n", 1859 type); 1860 } 1861 if( ciptr->fd >= 0 ) 1862 break; 1863 } 1864 1865 TRANS(LocalEndTransports)(); 1866 1867 if( ciptr->fd < 0 ) 1868 { 1869 free(ciptr); 1870 return NULL; 1871 } 1872 1873 ciptr->priv=(char *)transptr; 1874 ciptr->index = index; 1875 1876 return ciptr; 1877} 1878 1879#endif /* TRANS_CLIENT */ 1880 1881 1882#ifdef TRANS_SERVER 1883 1884static XtransConnInfo 1885TRANS(LocalOpenServer)(int type, char *protocol, char *host _X_UNUSED, char *port) 1886 1887{ 1888 int i; 1889 XtransConnInfo ciptr; 1890 1891 prmsg(2,"LocalOpenServer(%d,%s,%s)\n", type, protocol, port); 1892 1893#if defined(X11_t) 1894 /* 1895 * For X11, the port will be in the format xserverN where N is the 1896 * display number. All of the local connections just need to know 1897 * the display number because they don't do any name resolution on 1898 * the port. This just truncates port to the display portion. 1899 */ 1900#endif /* X11_t */ 1901 1902 if( (ciptr = calloc(1,sizeof(struct _XtransConnInfo))) == NULL ) 1903 { 1904 prmsg(1,"LocalOpenServer: calloc(1,%lu) failed\n", 1905 sizeof(struct _XtransConnInfo)); 1906 return NULL; 1907 } 1908 1909 for(i=1;i<NUMTRANSPORTS;i++) 1910 { 1911 if( strcmp(protocol,LOCALtrans2devtab[i].transname) != 0 ) 1912 continue; 1913 switch( type ) 1914 { 1915 case XTRANS_OPEN_COTS_CLIENT: 1916 case XTRANS_OPEN_CLTS_CLIENT: 1917 prmsg(1, 1918 "LocalOpenServer: Should not be opening a client with this function\n"); 1919 break; 1920 case XTRANS_OPEN_COTS_SERVER: 1921 ciptr->fd=LOCALtrans2devtab[i].devcotsopenserver(ciptr,port); 1922 break; 1923 case XTRANS_OPEN_CLTS_SERVER: 1924 ciptr->fd=LOCALtrans2devtab[i].devcltsopenserver(ciptr,port); 1925 break; 1926 default: 1927 prmsg(1,"LocalOpenServer: Unknown Open type %d\n", 1928 type ); 1929 } 1930 if( ciptr->fd >= 0 ) { 1931 ciptr->priv=(char *)&LOCALtrans2devtab[i]; 1932 ciptr->index=i; 1933 ciptr->flags = 1 | (ciptr->flags & TRANS_KEEPFLAGS); 1934 return ciptr; 1935 } 1936 } 1937 1938 free(ciptr); 1939 return NULL; 1940} 1941 1942#endif /* TRANS_SERVER */ 1943 1944 1945#ifdef TRANS_REOPEN 1946 1947static XtransConnInfo 1948TRANS(LocalReopenServer)(int type, int index, int fd, char *port) 1949 1950{ 1951 XtransConnInfo ciptr; 1952 int stat = 0; 1953 1954 prmsg(2,"LocalReopenServer(%d,%d,%d)\n", type, index, fd); 1955 1956 if( (ciptr = calloc(1,sizeof(struct _XtransConnInfo))) == NULL ) 1957 { 1958 prmsg(1,"LocalReopenServer: calloc(1,%lu) failed\n", 1959 sizeof(struct _XtransConnInfo)); 1960 return NULL; 1961 } 1962 1963 ciptr->fd = fd; 1964 1965 switch( type ) 1966 { 1967 case XTRANS_OPEN_COTS_SERVER: 1968 stat = LOCALtrans2devtab[index].devcotsreopenserver(ciptr,fd,port); 1969 break; 1970 case XTRANS_OPEN_CLTS_SERVER: 1971 stat = LOCALtrans2devtab[index].devcltsreopenserver(ciptr,fd,port); 1972 break; 1973 default: 1974 prmsg(1,"LocalReopenServer: Unknown Open type %d\n", 1975 type ); 1976 } 1977 1978 if( stat > 0 ) { 1979 ciptr->priv=(char *)&LOCALtrans2devtab[index]; 1980 ciptr->index=index; 1981 ciptr->flags = 1 | (ciptr->flags & TRANS_KEEPFLAGS); 1982 return ciptr; 1983 } 1984 1985 free(ciptr); 1986 return NULL; 1987} 1988 1989#endif /* TRANS_REOPEN */ 1990 1991 1992 1993/* 1994 * This is the Local implementation of the X Transport service layer 1995 */ 1996 1997#ifdef TRANS_CLIENT 1998 1999static XtransConnInfo 2000TRANS(LocalOpenCOTSClient)(Xtransport *thistrans _X_UNUSED, char *protocol, 2001 char *host, char *port) 2002 2003{ 2004 prmsg(2,"LocalOpenCOTSClient(%s,%s,%s)\n",protocol,host,port); 2005 2006 return TRANS(LocalOpenClient)(XTRANS_OPEN_COTS_CLIENT, protocol, host, port); 2007} 2008 2009#endif /* TRANS_CLIENT */ 2010 2011 2012#ifdef TRANS_SERVER 2013 2014static XtransConnInfo 2015TRANS(LocalOpenCOTSServer)(Xtransport *thistrans, char *protocol, 2016 char *host, char *port) 2017 2018{ 2019 char *typetocheck = NULL; 2020 int found = 0; 2021 char typebuf[TYPEBUFSIZE]; 2022 2023 prmsg(2,"LocalOpenCOTSServer(%s,%s,%s)\n",protocol,host,port); 2024 2025 /* Check if this local type is in the XLOCAL list */ 2026 TRANS(LocalInitTransports)("local"); 2027 typetocheck = workingXLOCAL; 2028 while (typetocheck && !found) { 2029 int j; 2030 2031 workingXLOCAL = strchr(workingXLOCAL, ':'); 2032 if (workingXLOCAL && *workingXLOCAL) 2033 *workingXLOCAL++ = '\0'; 2034 strncpy(typebuf, typetocheck, TYPEBUFSIZE); 2035 for (j = 0; j < TYPEBUFSIZE; j++) 2036 if (isupper(typebuf[j])) 2037 typebuf[j] = tolower(typebuf[j]); 2038 if (!strcmp(thistrans->TransName, typebuf)) 2039 found = 1; 2040 typetocheck = workingXLOCAL; 2041 } 2042 TRANS(LocalEndTransports)(); 2043 2044 if (!found) { 2045 prmsg(3,"LocalOpenCOTSServer: disabling %s\n",thistrans->TransName); 2046 thistrans->flags |= TRANS_DISABLED; 2047 return NULL; 2048 } 2049 2050 return TRANS(LocalOpenServer)(XTRANS_OPEN_COTS_SERVER, protocol, host, port); 2051} 2052 2053#endif /* TRANS_SERVER */ 2054 2055 2056#ifdef TRANS_CLIENT 2057 2058static XtransConnInfo 2059TRANS(LocalOpenCLTSClient)(Xtransport *thistrans _X_UNUSED, char *protocol, 2060 char *host, char *port) 2061 2062{ 2063 prmsg(2,"LocalOpenCLTSClient(%s,%s,%s)\n",protocol,host,port); 2064 2065 return TRANS(LocalOpenClient)(XTRANS_OPEN_CLTS_CLIENT, protocol, host, port); 2066} 2067 2068#endif /* TRANS_CLIENT */ 2069 2070 2071#ifdef TRANS_SERVER 2072 2073static XtransConnInfo 2074TRANS(LocalOpenCLTSServer)(Xtransport *thistrans _X_UNUSED, char *protocol, 2075 char *host, char *port) 2076 2077{ 2078 prmsg(2,"LocalOpenCLTSServer(%s,%s,%s)\n",protocol,host,port); 2079 2080 return TRANS(LocalOpenServer)(XTRANS_OPEN_CLTS_SERVER, protocol, host, port); 2081} 2082 2083#endif /* TRANS_SERVER */ 2084 2085 2086#ifdef TRANS_REOPEN 2087 2088static XtransConnInfo 2089TRANS(LocalReopenCOTSServer)(Xtransport *thistrans, int fd, char *port) 2090 2091{ 2092 int index; 2093 2094 prmsg(2,"LocalReopenCOTSServer(%d,%s)\n", fd, port); 2095 2096 for(index=1;index<NUMTRANSPORTS;index++) 2097 { 2098 if( strcmp(thistrans->TransName, 2099 LOCALtrans2devtab[index].transname) == 0 ) 2100 break; 2101 } 2102 2103 if (index >= NUMTRANSPORTS) 2104 { 2105 return (NULL); 2106 } 2107 2108 return TRANS(LocalReopenServer)(XTRANS_OPEN_COTS_SERVER, 2109 index, fd, port); 2110} 2111 2112static XtransConnInfo 2113TRANS(LocalReopenCLTSServer)(Xtransport *thistrans, int fd, char *port) 2114 2115{ 2116 int index; 2117 2118 prmsg(2,"LocalReopenCLTSServer(%d,%s)\n", fd, port); 2119 2120 for(index=1;index<NUMTRANSPORTS;index++) 2121 { 2122 if( strcmp(thistrans->TransName, 2123 LOCALtrans2devtab[index].transname) == 0 ) 2124 break; 2125 } 2126 2127 if (index >= NUMTRANSPORTS) 2128 { 2129 return (NULL); 2130 } 2131 2132 return TRANS(LocalReopenServer)(XTRANS_OPEN_CLTS_SERVER, 2133 index, fd, port); 2134} 2135 2136#endif /* TRANS_REOPEN */ 2137 2138 2139 2140static int 2141TRANS(LocalSetOption)(XtransConnInfo ciptr, int option, int arg) 2142 2143{ 2144 prmsg(2,"LocalSetOption(%d,%d,%d)\n",ciptr->fd,option,arg); 2145 2146 return -1; 2147} 2148 2149 2150#ifdef TRANS_SERVER 2151 2152static int 2153TRANS(LocalCreateListener)(XtransConnInfo ciptr, char *port, unsigned int flags _X_UNUSED) 2154 2155{ 2156 prmsg(2,"LocalCreateListener(%p->%d,%s)\n",ciptr,ciptr->fd,port); 2157 2158 return 0; 2159} 2160 2161static int 2162TRANS(LocalResetListener)(XtransConnInfo ciptr) 2163 2164{ 2165 LOCALtrans2dev *transptr; 2166 2167 prmsg(2,"LocalResetListener(%p)\n",ciptr); 2168 2169 transptr=(LOCALtrans2dev *)ciptr->priv; 2170 if (transptr->devreset != NULL) { 2171 return transptr->devreset(ciptr); 2172 } 2173 return TRANS_RESET_NOOP; 2174} 2175 2176 2177static XtransConnInfo 2178TRANS(LocalAccept)(XtransConnInfo ciptr, int *status) 2179 2180{ 2181 XtransConnInfo newciptr; 2182 LOCALtrans2dev *transptr; 2183 2184 prmsg(2,"LocalAccept(%p->%d)\n", ciptr, ciptr->fd); 2185 2186 transptr=(LOCALtrans2dev *)ciptr->priv; 2187 2188 if( (newciptr = calloc(1,sizeof(struct _XtransConnInfo)))==NULL ) 2189 { 2190 prmsg(1,"LocalAccept: calloc(1,%lu) failed\n", 2191 sizeof(struct _XtransConnInfo)); 2192 *status = TRANS_ACCEPT_BAD_MALLOC; 2193 return NULL; 2194 } 2195 2196 newciptr->fd=transptr->devaccept(ciptr,newciptr,status); 2197 2198 if( newciptr->fd < 0 ) 2199 { 2200 free(newciptr); 2201 return NULL; 2202 } 2203 2204 newciptr->priv=(char *)transptr; 2205 newciptr->index = ciptr->index; 2206 2207 *status = 0; 2208 2209 return newciptr; 2210} 2211 2212#endif /* TRANS_SERVER */ 2213 2214 2215#ifdef TRANS_CLIENT 2216 2217static int 2218TRANS(LocalConnect)(XtransConnInfo ciptr, char *host _X_UNUSED, char *port) 2219 2220{ 2221 prmsg(2,"LocalConnect(%p->%d,%s)\n", ciptr, ciptr->fd, port); 2222 2223 return 0; 2224} 2225 2226#endif /* TRANS_CLIENT */ 2227 2228 2229static int 2230TRANS(LocalBytesReadable)(XtransConnInfo ciptr, BytesReadable_t *pend ) 2231 2232{ 2233 prmsg(2,"LocalBytesReadable(%p->%d,%p)\n", ciptr, ciptr->fd, pend); 2234 2235#if defined(SCO325) 2236 return ioctl(ciptr->fd, I_NREAD, (char *)pend); 2237#else 2238 return ioctl(ciptr->fd, FIONREAD, (char *)pend); 2239#endif 2240} 2241 2242static int 2243TRANS(LocalRead)(XtransConnInfo ciptr, char *buf, int size) 2244 2245{ 2246 prmsg(2,"LocalRead(%d,%p,%d)\n", ciptr->fd, buf, size ); 2247 2248 return read(ciptr->fd,buf,size); 2249} 2250 2251static int 2252TRANS(LocalWrite)(XtransConnInfo ciptr, char *buf, int size) 2253 2254{ 2255 prmsg(2,"LocalWrite(%d,%p,%d)\n", ciptr->fd, buf, size ); 2256 2257 return write(ciptr->fd,buf,size); 2258} 2259 2260static int 2261TRANS(LocalReadv)(XtransConnInfo ciptr, struct iovec *buf, int size) 2262 2263{ 2264 prmsg(2,"LocalReadv(%d,%p,%d)\n", ciptr->fd, buf, size ); 2265 2266 return READV(ciptr,buf,size); 2267} 2268 2269static int 2270TRANS(LocalWritev)(XtransConnInfo ciptr, struct iovec *buf, int size) 2271 2272{ 2273 prmsg(2,"LocalWritev(%d,%p,%d)\n", ciptr->fd, buf, size ); 2274 2275 return WRITEV(ciptr,buf,size); 2276} 2277 2278static int 2279TRANS(LocalDisconnect)(XtransConnInfo ciptr) 2280 2281{ 2282 prmsg(2,"LocalDisconnect(%p->%d)\n", ciptr, ciptr->fd); 2283 2284 return 0; 2285} 2286 2287static int 2288TRANS(LocalClose)(XtransConnInfo ciptr) 2289 2290{ 2291 struct sockaddr_un *sockname=(struct sockaddr_un *) ciptr->addr; 2292 int ret; 2293 2294 prmsg(2,"LocalClose(%p->%d)\n", ciptr, ciptr->fd ); 2295 2296 ret=close(ciptr->fd); 2297 2298 if(ciptr->flags 2299 && sockname 2300 && sockname->sun_family == AF_UNIX 2301 && sockname->sun_path[0] ) 2302 { 2303 if (!(ciptr->flags & TRANS_NOUNLINK)) 2304 unlink(sockname->sun_path); 2305 } 2306 2307 return ret; 2308} 2309 2310static int 2311TRANS(LocalCloseForCloning)(XtransConnInfo ciptr) 2312 2313{ 2314 int ret; 2315 2316 prmsg(2,"LocalCloseForCloning(%p->%d)\n", ciptr, ciptr->fd ); 2317 2318 /* Don't unlink path */ 2319 2320 ret=close(ciptr->fd); 2321 2322 return ret; 2323} 2324 2325 2326/* 2327 * MakeAllCOTSServerListeners() will go through the entire Xtransports[] 2328 * array defined in Xtrans.c and try to OpenCOTSServer() for each entry. 2329 * We will add duplicate entries to that table so that the OpenCOTSServer() 2330 * function will get called once for each type of local transport. 2331 * 2332 * The TransName is in lowercase, so it will never match during a normal 2333 * call to SelectTransport() in Xtrans.c. 2334 */ 2335 2336#ifdef TRANS_SERVER 2337static const char * local_aliases[] = { 2338# ifdef LOCAL_TRANS_PTS 2339 "pts", 2340# endif 2341 "named", 2342# ifdef sun 2343 "pipe", /* compatibility with Solaris Xlib */ 2344# endif 2345# ifdef LOCAL_TRANS_SCO 2346 "sco", 2347# endif 2348 NULL }; 2349#endif 2350 2351Xtransport TRANS(LocalFuncs) = { 2352 /* Local Interface */ 2353 "local", 2354 TRANS_ALIAS | TRANS_LOCAL, 2355#ifdef TRANS_CLIENT 2356 TRANS(LocalOpenCOTSClient), 2357#endif /* TRANS_CLIENT */ 2358#ifdef TRANS_SERVER 2359 local_aliases, 2360 TRANS(LocalOpenCOTSServer), 2361#endif /* TRANS_SERVER */ 2362#ifdef TRANS_CLIENT 2363 TRANS(LocalOpenCLTSClient), 2364#endif /* TRANS_CLIENT */ 2365#ifdef TRANS_SERVER 2366 TRANS(LocalOpenCLTSServer), 2367#endif /* TRANS_SERVER */ 2368#ifdef TRANS_REOPEN 2369 TRANS(LocalReopenCOTSServer), 2370 TRANS(LocalReopenCLTSServer), 2371#endif 2372 TRANS(LocalSetOption), 2373#ifdef TRANS_SERVER 2374 TRANS(LocalCreateListener), 2375 TRANS(LocalResetListener), 2376 TRANS(LocalAccept), 2377#endif /* TRANS_SERVER */ 2378#ifdef TRANS_CLIENT 2379 TRANS(LocalConnect), 2380#endif /* TRANS_CLIENT */ 2381 TRANS(LocalBytesReadable), 2382 TRANS(LocalRead), 2383 TRANS(LocalWrite), 2384 TRANS(LocalReadv), 2385 TRANS(LocalWritev), 2386#if XTRANS_SEND_FDS 2387 TRANS(LocalSendFdInvalid), 2388 TRANS(LocalRecvFdInvalid), 2389#endif 2390 TRANS(LocalDisconnect), 2391 TRANS(LocalClose), 2392 TRANS(LocalCloseForCloning), 2393}; 2394 2395#ifdef LOCAL_TRANS_PTS 2396 2397Xtransport TRANS(PTSFuncs) = { 2398 /* Local Interface */ 2399 "pts", 2400 TRANS_LOCAL, 2401#ifdef TRANS_CLIENT 2402 TRANS(LocalOpenCOTSClient), 2403#endif /* TRANS_CLIENT */ 2404#ifdef TRANS_SERVER 2405 NULL, 2406 TRANS(LocalOpenCOTSServer), 2407#endif /* TRANS_SERVER */ 2408#ifdef TRANS_CLIENT 2409 TRANS(LocalOpenCLTSClient), 2410#endif /* TRANS_CLIENT */ 2411#ifdef TRANS_SERVER 2412 TRANS(LocalOpenCLTSServer), 2413#endif /* TRANS_SERVER */ 2414#ifdef TRANS_REOPEN 2415 TRANS(LocalReopenCOTSServer), 2416 TRANS(LocalReopenCLTSServer), 2417#endif 2418 TRANS(LocalSetOption), 2419#ifdef TRANS_SERVER 2420 TRANS(LocalCreateListener), 2421 TRANS(LocalResetListener), 2422 TRANS(LocalAccept), 2423#endif /* TRANS_SERVER */ 2424#ifdef TRANS_CLIENT 2425 TRANS(LocalConnect), 2426#endif /* TRANS_CLIENT */ 2427 TRANS(LocalBytesReadable), 2428 TRANS(LocalRead), 2429 TRANS(LocalWrite), 2430 TRANS(LocalReadv), 2431 TRANS(LocalWritev), 2432#if XTRANS_SEND_FDS 2433 TRANS(LocalSendFdInvalid), 2434 TRANS(LocalRecvFdInvalid), 2435#endif 2436 TRANS(LocalDisconnect), 2437 TRANS(LocalClose), 2438 TRANS(LocalCloseForCloning), 2439}; 2440 2441#endif /* LOCAL_TRANS_PTS */ 2442 2443#ifdef LOCAL_TRANS_NAMED 2444 2445Xtransport TRANS(NAMEDFuncs) = { 2446 /* Local Interface */ 2447 "named", 2448 TRANS_LOCAL, 2449#ifdef TRANS_CLIENT 2450 TRANS(LocalOpenCOTSClient), 2451#endif /* TRANS_CLIENT */ 2452#ifdef TRANS_SERVER 2453 NULL, 2454 TRANS(LocalOpenCOTSServer), 2455#endif /* TRANS_SERVER */ 2456#ifdef TRANS_CLIENT 2457 TRANS(LocalOpenCLTSClient), 2458#endif /* TRANS_CLIENT */ 2459#ifdef TRANS_SERVER 2460 TRANS(LocalOpenCLTSServer), 2461#endif /* TRANS_SERVER */ 2462#ifdef TRANS_REOPEN 2463 TRANS(LocalReopenCOTSServer), 2464 TRANS(LocalReopenCLTSServer), 2465#endif 2466 TRANS(LocalSetOption), 2467#ifdef TRANS_SERVER 2468 TRANS(LocalCreateListener), 2469 TRANS(LocalResetListener), 2470 TRANS(LocalAccept), 2471#endif /* TRANS_SERVER */ 2472#ifdef TRANS_CLIENT 2473 TRANS(LocalConnect), 2474#endif /* TRANS_CLIENT */ 2475 TRANS(LocalBytesReadable), 2476 TRANS(LocalRead), 2477 TRANS(LocalWrite), 2478 TRANS(LocalReadv), 2479 TRANS(LocalWritev), 2480#if XTRANS_SEND_FDS 2481 TRANS(LocalSendFdInvalid), 2482 TRANS(LocalRecvFdInvalid), 2483#endif 2484 TRANS(LocalDisconnect), 2485 TRANS(LocalClose), 2486 TRANS(LocalCloseForCloning), 2487}; 2488 2489#ifdef sun 2490Xtransport TRANS(PIPEFuncs) = { 2491 /* Local Interface */ 2492 "pipe", 2493 TRANS_ALIAS | TRANS_LOCAL, 2494#ifdef TRANS_CLIENT 2495 TRANS(LocalOpenCOTSClient), 2496#endif /* TRANS_CLIENT */ 2497#ifdef TRANS_SERVER 2498 NULL, 2499 TRANS(LocalOpenCOTSServer), 2500#endif /* TRANS_SERVER */ 2501#ifdef TRANS_CLIENT 2502 TRANS(LocalOpenCLTSClient), 2503#endif /* TRANS_CLIENT */ 2504#ifdef TRANS_SERVER 2505 TRANS(LocalOpenCLTSServer), 2506#endif /* TRANS_SERVER */ 2507#ifdef TRANS_REOPEN 2508 TRANS(LocalReopenCOTSServer), 2509 TRANS(LocalReopenCLTSServer), 2510#endif 2511 TRANS(LocalSetOption), 2512#ifdef TRANS_SERVER 2513 TRANS(LocalCreateListener), 2514 TRANS(LocalResetListener), 2515 TRANS(LocalAccept), 2516#endif /* TRANS_SERVER */ 2517#ifdef TRANS_CLIENT 2518 TRANS(LocalConnect), 2519#endif /* TRANS_CLIENT */ 2520 TRANS(LocalBytesReadable), 2521 TRANS(LocalRead), 2522 TRANS(LocalWrite), 2523 TRANS(LocalReadv), 2524 TRANS(LocalWritev), 2525#if XTRANS_SEND_FDS 2526 TRANS(LocalSendFdInvalid), 2527 TRANS(LocalRecvFdInvalid), 2528#endif 2529 TRANS(LocalDisconnect), 2530 TRANS(LocalClose), 2531 TRANS(LocalCloseForCloning), 2532}; 2533#endif /* sun */ 2534#endif /* LOCAL_TRANS_NAMED */ 2535 2536 2537#ifdef LOCAL_TRANS_SCO 2538Xtransport TRANS(SCOFuncs) = { 2539 /* Local Interface */ 2540 "sco", 2541 TRANS_LOCAL, 2542#ifdef TRANS_CLIENT 2543 TRANS(LocalOpenCOTSClient), 2544#endif /* TRANS_CLIENT */ 2545#ifdef TRANS_SERVER 2546 NULL, 2547 TRANS(LocalOpenCOTSServer), 2548#endif /* TRANS_SERVER */ 2549#ifdef TRANS_CLIENT 2550 TRANS(LocalOpenCLTSClient), 2551#endif /* TRANS_CLIENT */ 2552#ifdef TRANS_SERVER 2553 TRANS(LocalOpenCLTSServer), 2554#endif /* TRANS_SERVER */ 2555#ifdef TRANS_REOPEN 2556 TRANS(LocalReopenCOTSServer), 2557 TRANS(LocalReopenCLTSServer), 2558#endif 2559 TRANS(LocalSetOption), 2560#ifdef TRANS_SERVER 2561 TRANS(LocalCreateListener), 2562 TRANS(LocalResetListener), 2563 TRANS(LocalAccept), 2564#endif /* TRANS_SERVER */ 2565#ifdef TRANS_CLIENT 2566 TRANS(LocalConnect), 2567#endif /* TRANS_CLIENT */ 2568 TRANS(LocalBytesReadable), 2569 TRANS(LocalRead), 2570 TRANS(LocalWrite), 2571 TRANS(LocalReadv), 2572 TRANS(LocalWritev), 2573#if XTRANS_SEND_FDS 2574 TRANS(LocalSendFdInvalid), 2575 TRANS(LocalRecvFdInvalid), 2576#endif 2577 TRANS(LocalDisconnect), 2578 TRANS(LocalClose), 2579 TRANS(LocalCloseForCloning), 2580}; 2581#endif /* LOCAL_TRANS_SCO */ 2582