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