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