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