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