File indexing completed on 2025-01-30 10:26:38
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073 #include <errno.h>
0074 #include <ctype.h>
0075 #include <sys/signal.h>
0076 #include <sys/ioctl.h>
0077 #include <sys/stat.h>
0078 #if defined(SVR4) || defined(__SVR4)
0079 #include <sys/filio.h>
0080 #endif
0081 # include <stropts.h>
0082 #include <sys/wait.h>
0083 #include <sys/types.h>
0084
0085
0086
0087
0088
0089
0090
0091
0092 #include <sys/socket.h>
0093 #ifndef X_NO_SYS_UN
0094 #include <sys/un.h>
0095 #endif
0096
0097
0098
0099
0100
0101
0102 #if defined(SVR4) || defined(__SVR4)
0103 # define LOCAL_TRANS_NAMED
0104 #endif
0105
0106 static int TRANS(LocalClose)(XtransConnInfo ciptr);
0107
0108
0109
0110
0111
0112
0113
0114 static int
0115 TRANS(OpenFail)(XtransConnInfo ciptr _X_UNUSED, const char *port _X_UNUSED)
0116
0117 {
0118 return -1;
0119 }
0120
0121 #ifdef TRANS_REOPEN
0122
0123 static int
0124 TRANS(ReopenFail)(XtransConnInfo ciptr _X_UNUSED, int fd _X_UNUSED,
0125 const char *port _X_UNUSED)
0126
0127 {
0128 return 0;
0129 }
0130
0131 #endif
0132
0133 #if XTRANS_SEND_FDS
0134 static int
0135 TRANS(LocalRecvFdInvalid)(XtransConnInfo ciptr)
0136 {
0137 errno = EINVAL;
0138 return -1;
0139 }
0140
0141 static int
0142 TRANS(LocalSendFdInvalid)(XtransConnInfo ciptr, int fd, int do_close)
0143 {
0144 errno = EINVAL;
0145 return -1;
0146 }
0147 #endif
0148
0149
0150 static int
0151 TRANS(FillAddrInfo)(XtransConnInfo ciptr,
0152 const char *sun_path, const char *peer_sun_path)
0153
0154 {
0155 struct sockaddr_un *sunaddr;
0156 struct sockaddr_un *p_sunaddr;
0157
0158 ciptr->family = AF_UNIX;
0159 ciptr->addrlen = sizeof (struct sockaddr_un);
0160
0161 if ((sunaddr = malloc (ciptr->addrlen)) == NULL)
0162 {
0163 prmsg(1,"FillAddrInfo: failed to allocate memory for addr\n");
0164 return 0;
0165 }
0166
0167 sunaddr->sun_family = AF_UNIX;
0168
0169 if (strlen(sun_path) > sizeof(sunaddr->sun_path) - 1) {
0170 prmsg(1, "FillAddrInfo: path too long\n");
0171 free((char *) sunaddr);
0172 return 0;
0173 }
0174 strcpy (sunaddr->sun_path, sun_path);
0175 #if defined(BSD44SOCKETS)
0176 sunaddr->sun_len = strlen (sunaddr->sun_path);
0177 #endif
0178
0179 ciptr->addr = (char *) sunaddr;
0180
0181 ciptr->peeraddrlen = sizeof (struct sockaddr_un);
0182
0183 if ((p_sunaddr = malloc (ciptr->peeraddrlen)) == NULL)
0184 {
0185 prmsg(1,
0186 "FillAddrInfo: failed to allocate memory for peer addr\n");
0187 free (sunaddr);
0188 ciptr->addr = NULL;
0189
0190 return 0;
0191 }
0192
0193 p_sunaddr->sun_family = AF_UNIX;
0194
0195 if (strlen(peer_sun_path) > sizeof(p_sunaddr->sun_path) - 1) {
0196 prmsg(1, "FillAddrInfo: peer path too long\n");
0197 free((char *) p_sunaddr);
0198 return 0;
0199 }
0200 strcpy (p_sunaddr->sun_path, peer_sun_path);
0201 #if defined(BSD44SOCKETS)
0202 p_sunaddr->sun_len = strlen (p_sunaddr->sun_path);
0203 #endif
0204
0205 ciptr->peeraddr = (char *) p_sunaddr;
0206
0207 return 1;
0208 }
0209
0210
0211
0212
0213 #ifndef X11_t
0214 #define X_STREAMS_DIR "/dev/X"
0215 #else
0216 #define X_STREAMS_DIR "/tmp/.X11-pipe"
0217 #endif
0218
0219 #define DEV_PTMX "/dev/ptmx"
0220
0221 #if defined(X11_t)
0222
0223 #define NAMEDNODENAME "/tmp/.X11-pipe/X"
0224 #endif
0225 #if defined(XIM_t)
0226 #define NAMEDNODENAME "/tmp/.XIM-pipe/XIM"
0227 #endif
0228 #if defined(FS_t) || defined (FONT_t)
0229 #define NAMEDNODENAME "/tmp/.font-pipe/fs"
0230 #endif
0231 #if defined(ICE_t)
0232 #define NAMEDNODENAME "/tmp/.ICE-pipe/"
0233 #endif
0234
0235
0236
0237
0238
0239 #ifdef LOCAL_TRANS_NAMED
0240
0241
0242
0243 #ifdef TRANS_CLIENT
0244
0245 static int
0246 TRANS(NAMEDOpenClient)(XtransConnInfo ciptr, const char *port)
0247
0248 {
0249 #ifdef NAMEDNODENAME
0250 int fd;
0251 char server_path[64];
0252 struct stat filestat;
0253 #endif
0254
0255 prmsg(2,"NAMEDOpenClient(%s)\n", port);
0256
0257 #if !defined(NAMEDNODENAME)
0258 prmsg(1,"NAMEDOpenClient: Protocol is not supported by a NAMED connection\n");
0259 return -1;
0260 #else
0261 if ( port && *port ) {
0262 if( *port == '/' ) {
0263 (void) snprintf(server_path, sizeof(server_path), "%s", port);
0264 } else {
0265 (void) snprintf(server_path, sizeof(server_path), "%s%s", NAMEDNODENAME, port);
0266 }
0267 } else {
0268 (void) snprintf(server_path, sizeof(server_path), "%s%ld", NAMEDNODENAME, (long)getpid());
0269 }
0270
0271 if ((fd = open(server_path, O_RDWR)) < 0) {
0272 prmsg(1,"NAMEDOpenClient: Cannot open %s for NAMED connection\n", server_path);
0273 return -1;
0274 }
0275
0276 if (fstat(fd, &filestat) < 0 ) {
0277 prmsg(1,"NAMEDOpenClient: Cannot stat %s for NAMED connection\n", server_path);
0278 (void) close(fd);
0279 return -1;
0280 }
0281
0282 if ((filestat.st_mode & S_IFMT) != S_IFIFO) {
0283 prmsg(1,"NAMEDOpenClient: Device %s is not a FIFO\n", server_path);
0284
0285 (void) close(fd);
0286 return -1;
0287 }
0288
0289
0290 if (isastream(fd) <= 0) {
0291 prmsg(1,"NAMEDOpenClient: %s is not a streams device\n", server_path);
0292 (void) close(fd);
0293 return -1;
0294 }
0295
0296
0297
0298
0299
0300 if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
0301 {
0302 prmsg(1,"NAMEDOpenClient: failed to fill in addr info\n");
0303 close(fd);
0304 return -1;
0305 }
0306
0307 return(fd);
0308
0309 #endif
0310 }
0311
0312 #endif
0313
0314
0315 #ifdef TRANS_SERVER
0316
0317
0318 #ifdef NAMEDNODENAME
0319 static int
0320 TRANS(NAMEDOpenPipe)(const char *server_path)
0321 {
0322 int fd, pipefd[2];
0323 struct stat sbuf;
0324 int mode;
0325
0326 prmsg(2,"NAMEDOpenPipe(%s)\n", server_path);
0327
0328 #ifdef HAS_STICKY_DIR_BIT
0329 mode = 01777;
0330 #else
0331 mode = 0777;
0332 #endif
0333 if (trans_mkdir(X_STREAMS_DIR, mode) == -1) {
0334 prmsg (1, "NAMEDOpenPipe: mkdir(%s) failed, errno = %d\n",
0335 X_STREAMS_DIR, errno);
0336 return(-1);
0337 }
0338
0339 if(stat(server_path, &sbuf) != 0) {
0340 if (errno == ENOENT) {
0341 if ((fd = creat(server_path, (mode_t)0666)) == -1) {
0342 prmsg(1, "NAMEDOpenPipe: Can't open %s\n", server_path);
0343 return(-1);
0344 }
0345 if (fchmod(fd, (mode_t)0666) < 0) {
0346 prmsg(1, "NAMEDOpenPipe: Can't chmod %s\n", server_path);
0347 close(fd);
0348 return(-1);
0349 }
0350 close(fd);
0351 } else {
0352 prmsg(1, "NAMEDOpenPipe: stat on %s failed\n", server_path);
0353 return(-1);
0354 }
0355 }
0356
0357 if( pipe(pipefd) != 0) {
0358 prmsg(1, "NAMEDOpenPipe: pipe() failed, errno=%d\n",errno);
0359 return(-1);
0360 }
0361
0362 if( ioctl(pipefd[0], I_PUSH, "connld") != 0) {
0363 prmsg(1, "NAMEDOpenPipe: ioctl(I_PUSH,\"connld\") failed, errno=%d\n",errno);
0364 close(pipefd[0]);
0365 close(pipefd[1]);
0366 return(-1);
0367 }
0368
0369 if( fattach(pipefd[0], server_path) != 0) {
0370 prmsg(1, "NAMEDOpenPipe: fattach(%s) failed, errno=%d\n", server_path,errno);
0371 close(pipefd[0]);
0372 close(pipefd[1]);
0373 return(-1);
0374 }
0375
0376 return(pipefd[1]);
0377 }
0378 #endif
0379
0380 static int
0381 TRANS(NAMEDOpenServer)(XtransConnInfo ciptr, const char *port)
0382 {
0383 #ifdef NAMEDNODENAME
0384 int fd;
0385 char server_path[64];
0386 #endif
0387
0388 prmsg(2,"NAMEDOpenServer(%s)\n", port);
0389
0390 #if !defined(NAMEDNODENAME)
0391 prmsg(1,"NAMEDOpenServer: Protocol is not supported by a NAMED connection\n");
0392 return -1;
0393 #else
0394 if ( port && *port ) {
0395 if( *port == '/' ) {
0396 (void) snprintf(server_path, sizeof(server_path), "%s", port);
0397 } else {
0398 (void) snprintf(server_path, sizeof(server_path), "%s%s",
0399 NAMEDNODENAME, port);
0400 }
0401 } else {
0402 (void) snprintf(server_path, sizeof(server_path), "%s%ld",
0403 NAMEDNODENAME, (long)getpid());
0404 }
0405
0406 fd = TRANS(NAMEDOpenPipe)(server_path);
0407 if (fd < 0) {
0408 return -1;
0409 }
0410
0411
0412
0413
0414
0415 if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
0416 {
0417 prmsg(1,"NAMEDOpenServer: failed to fill in addr info\n");
0418 TRANS(LocalClose)(ciptr);
0419 return -1;
0420 }
0421
0422 return fd;
0423
0424 #endif
0425 }
0426
0427 static int
0428 TRANS(NAMEDResetListener) (XtransConnInfo ciptr)
0429
0430 {
0431 struct sockaddr_un *sockname=(struct sockaddr_un *) ciptr->addr;
0432 struct stat statb;
0433
0434 prmsg(2,"NAMEDResetListener(%p, %d)\n", ciptr, ciptr->fd);
0435
0436 if (ciptr->fd != -1) {
0437
0438
0439
0440
0441 if (stat (sockname->sun_path, &statb) == -1 ||
0442 (statb.st_mode & S_IFMT) != S_IFIFO) {
0443 prmsg(3, "Pipe %s trashed, recreating\n", sockname->sun_path);
0444 TRANS(LocalClose)(ciptr);
0445 ciptr->fd = TRANS(NAMEDOpenPipe)(sockname->sun_path);
0446 if (ciptr->fd >= 0)
0447 return TRANS_RESET_NEW_FD;
0448 else
0449 return TRANS_CREATE_LISTENER_FAILED;
0450 }
0451 }
0452 return TRANS_RESET_NOOP;
0453 }
0454
0455 static int
0456 TRANS(NAMEDAccept)(XtransConnInfo ciptr, XtransConnInfo newciptr, int *status)
0457
0458 {
0459 struct strrecvfd str;
0460
0461 prmsg(2,"NAMEDAccept(%p->%d)\n", ciptr, ciptr->fd);
0462
0463 if( ioctl(ciptr->fd, I_RECVFD, &str ) < 0 ) {
0464 prmsg(1, "NAMEDAccept: ioctl(I_RECVFD) failed, errno=%d\n", errno);
0465 *status = TRANS_ACCEPT_MISC_ERROR;
0466 return(-1);
0467 }
0468
0469
0470
0471
0472 newciptr->family=ciptr->family;
0473 newciptr->addrlen=ciptr->addrlen;
0474 if( (newciptr->addr = malloc(newciptr->addrlen)) == NULL ) {
0475 prmsg(1,
0476 "NAMEDAccept: failed to allocate memory for pipe addr\n");
0477 close(str.fd);
0478 *status = TRANS_ACCEPT_BAD_MALLOC;
0479 return -1;
0480 }
0481
0482 memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen);
0483
0484 newciptr->peeraddrlen=newciptr->addrlen;
0485 if( (newciptr->peeraddr = malloc(newciptr->peeraddrlen)) == NULL ) {
0486 prmsg(1,
0487 "NAMEDAccept: failed to allocate memory for peer addr\n");
0488 free(newciptr->addr);
0489 close(str.fd);
0490 *status = TRANS_ACCEPT_BAD_MALLOC;
0491 return -1;
0492 }
0493
0494 memcpy(newciptr->peeraddr,newciptr->addr,newciptr->peeraddrlen);
0495
0496 *status = 0;
0497
0498 return str.fd;
0499 }
0500
0501 #endif
0502
0503 #endif
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514 #ifdef TRANS_REOPEN
0515
0516 #ifdef LOCAL_TRANS_NAMED
0517
0518 static int
0519 TRANS(NAMEDReopenServer)(XtransConnInfo ciptr, int fd _X_UNUSED, const char *port)
0520
0521 {
0522 #ifdef NAMEDNODENAME
0523 char server_path[64];
0524 #endif
0525
0526 prmsg(2,"NAMEDReopenServer(%s)\n", port);
0527
0528 #if !defined(NAMEDNODENAME)
0529 prmsg(1,"NAMEDReopenServer: Protocol is not supported by a NAMED connection\n");
0530 return 0;
0531 #else
0532 if ( port && *port ) {
0533 if( *port == '/' ) {
0534 snprintf(server_path, sizeof(server_path),"%s", port);
0535 } else {
0536 snprintf(server_path, sizeof(server_path), "%s%s",
0537 NAMEDNODENAME, port);
0538 }
0539 } else {
0540 snprintf(server_path, sizeof(server_path), "%s%ld",
0541 NAMEDNODENAME, (long)getpid());
0542 }
0543
0544 if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
0545 {
0546 prmsg(1,"NAMEDReopenServer: failed to fill in addr info\n");
0547 return 0;
0548 }
0549
0550 return 1;
0551
0552 #endif
0553 }
0554
0555 #endif
0556
0557
0558
0559 #endif
0560
0561
0562
0563
0564
0565
0566
0567
0568 typedef struct _LOCALtrans2dev {
0569 const char *transname;
0570
0571 #ifdef TRANS_CLIENT
0572
0573 int (*devcotsopenclient)(
0574 XtransConnInfo, const char *
0575 );
0576
0577 #endif
0578
0579 #ifdef TRANS_SERVER
0580
0581 int (*devcotsopenserver)(
0582 XtransConnInfo, const char *
0583 );
0584
0585 #endif
0586
0587 #ifdef TRANS_CLIENT
0588
0589 int (*devcltsopenclient)(
0590 XtransConnInfo, const char *
0591 );
0592
0593 #endif
0594
0595 #ifdef TRANS_SERVER
0596
0597 int (*devcltsopenserver)(
0598 XtransConnInfo, const char *
0599 );
0600
0601 #endif
0602
0603 #ifdef TRANS_REOPEN
0604
0605 int (*devcotsreopenserver)(
0606 XtransConnInfo,
0607 int,
0608 const char *
0609 );
0610
0611 int (*devcltsreopenserver)(
0612 XtransConnInfo,
0613 int,
0614 const char *
0615 );
0616
0617 #endif
0618
0619 #ifdef TRANS_SERVER
0620
0621 int (*devreset)(
0622 XtransConnInfo
0623 );
0624
0625 int (*devaccept)(
0626 XtransConnInfo, XtransConnInfo, int *
0627 );
0628
0629 #endif
0630
0631 } LOCALtrans2dev;
0632
0633 static LOCALtrans2dev LOCALtrans2devtab[] = {
0634 {"",
0635 #ifdef TRANS_CLIENT
0636 TRANS(NAMEDOpenClient),
0637 #endif
0638 #ifdef TRANS_SERVER
0639 TRANS(NAMEDOpenServer),
0640 #endif
0641 #ifdef TRANS_CLIENT
0642 TRANS(OpenFail),
0643 #endif
0644 #ifdef TRANS_SERVER
0645 TRANS(OpenFail),
0646 #endif
0647 #ifdef TRANS_REOPEN
0648 TRANS(NAMEDReopenServer),
0649 TRANS(ReopenFail),
0650 #endif
0651 #ifdef TRANS_SERVER
0652 TRANS(NAMEDResetListener),
0653 TRANS(NAMEDAccept)
0654 #endif
0655 },
0656
0657 {"local",
0658 #ifdef TRANS_CLIENT
0659 TRANS(NAMEDOpenClient),
0660 #endif
0661 #ifdef TRANS_SERVER
0662 TRANS(NAMEDOpenServer),
0663 #endif
0664 #ifdef TRANS_CLIENT
0665 TRANS(OpenFail),
0666 #endif
0667 #ifdef TRANS_SERVER
0668 TRANS(OpenFail),
0669 #endif
0670 #ifdef TRANS_REOPEN
0671 TRANS(NAMEDReopenServer),
0672 TRANS(ReopenFail),
0673 #endif
0674 #ifdef TRANS_SERVER
0675 TRANS(NAMEDResetListener),
0676 TRANS(NAMEDAccept)
0677 #endif
0678 },
0679
0680 #ifdef LOCAL_TRANS_NAMED
0681 {"named",
0682 #ifdef TRANS_CLIENT
0683 TRANS(NAMEDOpenClient),
0684 #endif
0685 #ifdef TRANS_SERVER
0686 TRANS(NAMEDOpenServer),
0687 #endif
0688 #ifdef TRANS_CLIENT
0689 TRANS(OpenFail),
0690 #endif
0691 #ifdef TRANS_SERVER
0692 TRANS(OpenFail),
0693 #endif
0694 #ifdef TRANS_REOPEN
0695 TRANS(NAMEDReopenServer),
0696 TRANS(ReopenFail),
0697 #endif
0698 #ifdef TRANS_SERVER
0699 TRANS(NAMEDResetListener),
0700 TRANS(NAMEDAccept)
0701 #endif
0702 },
0703
0704 {"pipe",
0705 #ifdef TRANS_CLIENT
0706 TRANS(NAMEDOpenClient),
0707 #endif
0708 #ifdef TRANS_SERVER
0709 TRANS(NAMEDOpenServer),
0710 #endif
0711 #ifdef TRANS_CLIENT
0712 TRANS(OpenFail),
0713 #endif
0714 #ifdef TRANS_SERVER
0715 TRANS(OpenFail),
0716 #endif
0717 #ifdef TRANS_REOPEN
0718 TRANS(NAMEDReopenServer),
0719 TRANS(ReopenFail),
0720 #endif
0721 #ifdef TRANS_SERVER
0722 TRANS(NAMEDResetListener),
0723 TRANS(NAMEDAccept)
0724 #endif
0725 },
0726 #endif
0727
0728
0729 };
0730
0731 #define NUMTRANSPORTS (sizeof(LOCALtrans2devtab)/sizeof(LOCALtrans2dev))
0732
0733 static const char *XLOCAL=NULL;
0734 static char *workingXLOCAL=NULL;
0735 static char *freeXLOCAL=NULL;
0736
0737 #define DEF_XLOCAL "UNIX:NAMED"
0738
0739 static void
0740 TRANS(LocalInitTransports)(const char *protocol)
0741
0742 {
0743 prmsg(3,"LocalInitTransports(%s)\n", protocol);
0744
0745 if( strcmp(protocol,"local") && strcmp(protocol,"LOCAL") )
0746 {
0747 workingXLOCAL = freeXLOCAL = strdup (protocol);
0748 }
0749 else {
0750 XLOCAL = getenv("XLOCAL");
0751 if(XLOCAL==NULL)
0752 XLOCAL=DEF_XLOCAL;
0753 workingXLOCAL = freeXLOCAL = strdup (XLOCAL);
0754 }
0755 }
0756
0757 static void
0758 TRANS(LocalEndTransports)(void)
0759
0760 {
0761 prmsg(3,"LocalEndTransports()\n");
0762 free(freeXLOCAL);
0763 freeXLOCAL = NULL;
0764 }
0765
0766 #define TYPEBUFSIZE 32
0767
0768 #ifdef TRANS_CLIENT
0769
0770 static LOCALtrans2dev *
0771 TRANS(LocalGetNextTransport)(void)
0772
0773 {
0774 char *typetocheck;
0775 prmsg(3,"LocalGetNextTransport()\n");
0776
0777 while(1)
0778 {
0779 if( workingXLOCAL == NULL || *workingXLOCAL == '\0' )
0780 return NULL;
0781
0782 typetocheck=workingXLOCAL;
0783 workingXLOCAL=strchr(workingXLOCAL,':');
0784 if(workingXLOCAL && *workingXLOCAL)
0785 *workingXLOCAL++='\0';
0786
0787 for (unsigned int i = 0; i < NUMTRANSPORTS; i++)
0788 {
0789 #ifndef HAVE_STRCASECMP
0790 int j;
0791 char typebuf[TYPEBUFSIZE];
0792
0793
0794
0795
0796 strncpy(typebuf,typetocheck,TYPEBUFSIZE);
0797 for(j=0;j<TYPEBUFSIZE;j++)
0798 if (isupper(typebuf[j]))
0799 typebuf[j]=tolower(typebuf[j]);
0800
0801
0802 if(!strcmp(LOCALtrans2devtab[i].transname,typebuf))
0803 #else
0804 if(!strcasecmp(LOCALtrans2devtab[i].transname,typetocheck))
0805 #endif
0806 return &LOCALtrans2devtab[i];
0807 }
0808 }
0809 #if 0
0810
0811 return NULL;
0812 #endif
0813 }
0814
0815 #ifdef NEED_UTSNAME
0816 #include <sys/utsname.h>
0817 #endif
0818
0819
0820
0821
0822
0823 static int
0824 HostReallyLocal (const char *host)
0825
0826 {
0827
0828
0829
0830
0831
0832 #ifdef NEED_UTSNAME
0833 struct utsname name;
0834 #endif
0835 char buf[256];
0836
0837 #ifdef NEED_UTSNAME
0838 if (uname (&name) >= 0 && strcmp (host, name.nodename) == 0)
0839 return (1);
0840 #endif
0841
0842 buf[0] = '\0';
0843 (void) gethostname (buf, 256);
0844 buf[255] = '\0';
0845
0846 if (strcmp (host, buf) == 0)
0847 return (1);
0848
0849 return (0);
0850 }
0851
0852
0853 static XtransConnInfo
0854 TRANS(LocalOpenClient)(int type, const char *protocol,
0855 const char *host, const char *port)
0856
0857 {
0858 LOCALtrans2dev *transptr;
0859 XtransConnInfo ciptr;
0860 int index;
0861
0862 prmsg(3,"LocalOpenClient()\n");
0863
0864
0865
0866
0867
0868
0869
0870
0871
0872 if (strcmp (host, "unix") != 0 && !HostReallyLocal (host))
0873 {
0874 prmsg (1,
0875 "LocalOpenClient: Cannot connect to non-local host %s\n",
0876 host);
0877 return NULL;
0878 }
0879
0880
0881 #if defined(X11_t)
0882
0883
0884
0885
0886
0887
0888
0889
0890
0891 #endif
0892
0893 if( (ciptr = calloc(1,sizeof(struct _XtransConnInfo))) == NULL )
0894 {
0895 prmsg(1,"LocalOpenClient: calloc(1,%lu) failed\n",
0896 sizeof(struct _XtransConnInfo));
0897 return NULL;
0898 }
0899
0900 ciptr->fd = -1;
0901
0902 TRANS(LocalInitTransports)(protocol);
0903
0904 index = 0;
0905 for(transptr=TRANS(LocalGetNextTransport)();
0906 transptr!=NULL;transptr=TRANS(LocalGetNextTransport)(), index++)
0907 {
0908 switch( type )
0909 {
0910 case XTRANS_OPEN_COTS_CLIENT:
0911 ciptr->fd=transptr->devcotsopenclient(ciptr,port);
0912 break;
0913 case XTRANS_OPEN_COTS_SERVER:
0914 prmsg(1,
0915 "LocalOpenClient: Should not be opening a server with this function\n");
0916 break;
0917 default:
0918 prmsg(1,
0919 "LocalOpenClient: Unknown Open type %d\n",
0920 type);
0921 }
0922 if( ciptr->fd >= 0 )
0923 break;
0924 }
0925
0926 TRANS(LocalEndTransports)();
0927
0928 if( ciptr->fd < 0 )
0929 {
0930 free(ciptr);
0931 return NULL;
0932 }
0933
0934 ciptr->priv=(char *)transptr;
0935 ciptr->index = index;
0936
0937 return ciptr;
0938 }
0939
0940 #endif
0941
0942
0943 #ifdef TRANS_SERVER
0944
0945 static XtransConnInfo
0946 TRANS(LocalOpenServer)(int type, const char *protocol,
0947 const char *host _X_UNUSED, const char *port)
0948
0949 {
0950 XtransConnInfo ciptr;
0951
0952 prmsg(2,"LocalOpenServer(%d,%s,%s)\n", type, protocol, port);
0953
0954 #if defined(X11_t)
0955
0956
0957
0958
0959
0960
0961 #endif
0962
0963 if( (ciptr = calloc(1,sizeof(struct _XtransConnInfo))) == NULL )
0964 {
0965 prmsg(1,"LocalOpenServer: calloc(1,%lu) failed\n",
0966 sizeof(struct _XtransConnInfo));
0967 return NULL;
0968 }
0969
0970 for (unsigned int i = 1; i < NUMTRANSPORTS; i++)
0971 {
0972 if( strcmp(protocol,LOCALtrans2devtab[i].transname) != 0 )
0973 continue;
0974 switch( type )
0975 {
0976 case XTRANS_OPEN_COTS_CLIENT:
0977 prmsg(1,
0978 "LocalOpenServer: Should not be opening a client with this function\n");
0979 break;
0980 case XTRANS_OPEN_COTS_SERVER:
0981 ciptr->fd=LOCALtrans2devtab[i].devcotsopenserver(ciptr,port);
0982 break;
0983 default:
0984 prmsg(1,"LocalOpenServer: Unknown Open type %d\n",
0985 type );
0986 }
0987 if( ciptr->fd >= 0 ) {
0988 ciptr->priv=(char *)&LOCALtrans2devtab[i];
0989 ciptr->index=i;
0990 ciptr->flags = 1 | (ciptr->flags & TRANS_KEEPFLAGS);
0991 return ciptr;
0992 }
0993 }
0994
0995 free(ciptr);
0996 return NULL;
0997 }
0998
0999 #endif
1000
1001
1002 #ifdef TRANS_REOPEN
1003
1004 static XtransConnInfo
1005 TRANS(LocalReopenServer)(int type, int index, int fd, const char *port)
1006
1007 {
1008 XtransConnInfo ciptr;
1009 int stat = 0;
1010
1011 prmsg(2,"LocalReopenServer(%d,%d,%d)\n", type, index, fd);
1012
1013 if( (ciptr = calloc(1,sizeof(struct _XtransConnInfo))) == NULL )
1014 {
1015 prmsg(1,"LocalReopenServer: calloc(1,%lu) failed\n",
1016 sizeof(struct _XtransConnInfo));
1017 return NULL;
1018 }
1019
1020 ciptr->fd = fd;
1021
1022 switch( type )
1023 {
1024 case XTRANS_OPEN_COTS_SERVER:
1025 stat = LOCALtrans2devtab[index].devcotsreopenserver(ciptr,fd,port);
1026 break;
1027 default:
1028 prmsg(1,"LocalReopenServer: Unknown Open type %d\n",
1029 type );
1030 }
1031
1032 if( stat > 0 ) {
1033 ciptr->priv=(char *)&LOCALtrans2devtab[index];
1034 ciptr->index=index;
1035 ciptr->flags = 1 | (ciptr->flags & TRANS_KEEPFLAGS);
1036 return ciptr;
1037 }
1038
1039 free(ciptr);
1040 return NULL;
1041 }
1042
1043 #endif
1044
1045
1046
1047
1048
1049
1050
1051 #ifdef TRANS_CLIENT
1052
1053 static XtransConnInfo
1054 TRANS(LocalOpenCOTSClient)(Xtransport *thistrans _X_UNUSED, const char *protocol,
1055 const char *host, const char *port)
1056
1057 {
1058 prmsg(2,"LocalOpenCOTSClient(%s,%s,%s)\n",protocol,host,port);
1059
1060 return TRANS(LocalOpenClient)(XTRANS_OPEN_COTS_CLIENT, protocol, host, port);
1061 }
1062
1063 #endif
1064
1065
1066 #ifdef TRANS_SERVER
1067
1068 static XtransConnInfo
1069 TRANS(LocalOpenCOTSServer)(Xtransport *thistrans, const char *protocol,
1070 const char *host, const char *port)
1071
1072 {
1073 char *typetocheck = NULL;
1074 int found = 0;
1075
1076 prmsg(2,"LocalOpenCOTSServer(%s,%s,%s)\n",protocol,host,port);
1077
1078
1079 TRANS(LocalInitTransports)("local");
1080 typetocheck = workingXLOCAL;
1081 while (typetocheck && !found) {
1082 #ifndef HAVE_STRCASECMP
1083 int j;
1084 char typebuf[TYPEBUFSIZE];
1085 #endif
1086
1087 workingXLOCAL = strchr(workingXLOCAL, ':');
1088 if (workingXLOCAL && *workingXLOCAL)
1089 *workingXLOCAL++ = '\0';
1090 #ifndef HAVE_STRCASECMP
1091 strncpy(typebuf, typetocheck, TYPEBUFSIZE);
1092 for (j = 0; j < TYPEBUFSIZE; j++)
1093 if (isupper(typebuf[j]))
1094 typebuf[j] = tolower(typebuf[j]);
1095 if (!strcmp(thistrans->TransName, typebuf))
1096 #else
1097 if (!strcasecmp(thistrans->TransName, typetocheck))
1098 #endif
1099 found = 1;
1100 typetocheck = workingXLOCAL;
1101 }
1102 TRANS(LocalEndTransports)();
1103
1104 if (!found) {
1105 prmsg(3,"LocalOpenCOTSServer: disabling %s\n",thistrans->TransName);
1106 thistrans->flags |= TRANS_DISABLED;
1107 return NULL;
1108 }
1109
1110 return TRANS(LocalOpenServer)(XTRANS_OPEN_COTS_SERVER, protocol, host, port);
1111 }
1112
1113 #endif
1114
1115 #ifdef TRANS_REOPEN
1116
1117 static XtransConnInfo
1118 TRANS(LocalReopenCOTSServer)(Xtransport *thistrans, int fd, const char *port)
1119
1120 {
1121 unsigned int index;
1122
1123 prmsg(2,"LocalReopenCOTSServer(%d,%s)\n", fd, port);
1124
1125 for(index=1;index<NUMTRANSPORTS;index++)
1126 {
1127 if( strcmp(thistrans->TransName,
1128 LOCALtrans2devtab[index].transname) == 0 )
1129 break;
1130 }
1131
1132 if (index >= NUMTRANSPORTS)
1133 {
1134 return (NULL);
1135 }
1136
1137 return TRANS(LocalReopenServer)(XTRANS_OPEN_COTS_SERVER,
1138 index, fd, port);
1139 }
1140
1141 #endif
1142
1143
1144
1145 static int
1146 TRANS(LocalSetOption)(XtransConnInfo ciptr, int option, int arg)
1147
1148 {
1149 prmsg(2,"LocalSetOption(%d,%d,%d)\n",ciptr->fd,option,arg);
1150
1151 return -1;
1152 }
1153
1154
1155 #ifdef TRANS_SERVER
1156
1157 static int
1158 TRANS(LocalCreateListener)(XtransConnInfo ciptr, const char *port,
1159 unsigned int flags _X_UNUSED)
1160
1161 {
1162 prmsg(2,"LocalCreateListener(%p->%d,%s)\n",ciptr,ciptr->fd,port);
1163
1164 return 0;
1165 }
1166
1167 static int
1168 TRANS(LocalResetListener)(XtransConnInfo ciptr)
1169
1170 {
1171 LOCALtrans2dev *transptr;
1172
1173 prmsg(2,"LocalResetListener(%p)\n",ciptr);
1174
1175 transptr=(LOCALtrans2dev *)ciptr->priv;
1176 if (transptr->devreset != NULL) {
1177 return transptr->devreset(ciptr);
1178 }
1179 return TRANS_RESET_NOOP;
1180 }
1181
1182
1183 static XtransConnInfo
1184 TRANS(LocalAccept)(XtransConnInfo ciptr, int *status)
1185
1186 {
1187 XtransConnInfo newciptr;
1188 LOCALtrans2dev *transptr;
1189
1190 prmsg(2,"LocalAccept(%p->%d)\n", ciptr, ciptr->fd);
1191
1192 transptr=(LOCALtrans2dev *)ciptr->priv;
1193
1194 if( (newciptr = calloc(1,sizeof(struct _XtransConnInfo)))==NULL )
1195 {
1196 prmsg(1,"LocalAccept: calloc(1,%lu) failed\n",
1197 sizeof(struct _XtransConnInfo));
1198 *status = TRANS_ACCEPT_BAD_MALLOC;
1199 return NULL;
1200 }
1201
1202 newciptr->fd=transptr->devaccept(ciptr,newciptr,status);
1203
1204 if( newciptr->fd < 0 )
1205 {
1206 free(newciptr);
1207 return NULL;
1208 }
1209
1210 newciptr->priv=(char *)transptr;
1211 newciptr->index = ciptr->index;
1212
1213 *status = 0;
1214
1215 return newciptr;
1216 }
1217
1218 #endif
1219
1220
1221 #ifdef TRANS_CLIENT
1222
1223 static int
1224 TRANS(LocalConnect)(XtransConnInfo ciptr,
1225 const char *host _X_UNUSED, const char *port)
1226
1227 {
1228 prmsg(2,"LocalConnect(%p->%d,%s)\n", ciptr, ciptr->fd, port);
1229
1230 return 0;
1231 }
1232
1233 #endif
1234
1235
1236 static int
1237 TRANS(LocalBytesReadable)(XtransConnInfo ciptr, BytesReadable_t *pend )
1238
1239 {
1240 prmsg(2,"LocalBytesReadable(%p->%d,%p)\n", ciptr, ciptr->fd, pend);
1241
1242 return ioctl(ciptr->fd, FIONREAD, (char *)pend);
1243 }
1244
1245 static int
1246 TRANS(LocalRead)(XtransConnInfo ciptr, char *buf, int size)
1247
1248 {
1249 prmsg(2,"LocalRead(%d,%p,%d)\n", ciptr->fd, buf, size );
1250
1251 return read(ciptr->fd,buf,size);
1252 }
1253
1254 static int
1255 TRANS(LocalWrite)(XtransConnInfo ciptr, char *buf, int size)
1256
1257 {
1258 prmsg(2,"LocalWrite(%d,%p,%d)\n", ciptr->fd, buf, size );
1259
1260 return write(ciptr->fd,buf,size);
1261 }
1262
1263 static int
1264 TRANS(LocalReadv)(XtransConnInfo ciptr, struct iovec *buf, int size)
1265
1266 {
1267 prmsg(2,"LocalReadv(%d,%p,%d)\n", ciptr->fd, buf, size );
1268
1269 return READV(ciptr,buf,size);
1270 }
1271
1272 static int
1273 TRANS(LocalWritev)(XtransConnInfo ciptr, struct iovec *buf, int size)
1274
1275 {
1276 prmsg(2,"LocalWritev(%d,%p,%d)\n", ciptr->fd, buf, size );
1277
1278 return WRITEV(ciptr,buf,size);
1279 }
1280
1281 static int
1282 TRANS(LocalDisconnect)(XtransConnInfo ciptr)
1283
1284 {
1285 prmsg(2,"LocalDisconnect(%p->%d)\n", ciptr, ciptr->fd);
1286
1287 return 0;
1288 }
1289
1290 static int
1291 TRANS(LocalClose)(XtransConnInfo ciptr)
1292
1293 {
1294 struct sockaddr_un *sockname=(struct sockaddr_un *) ciptr->addr;
1295 int ret;
1296
1297 prmsg(2,"LocalClose(%p->%d)\n", ciptr, ciptr->fd );
1298
1299 ret=close(ciptr->fd);
1300
1301 if(ciptr->flags
1302 && sockname
1303 && sockname->sun_family == AF_UNIX
1304 && sockname->sun_path[0] )
1305 {
1306 if (!(ciptr->flags & TRANS_NOUNLINK))
1307 unlink(sockname->sun_path);
1308 }
1309
1310 return ret;
1311 }
1312
1313 static int
1314 TRANS(LocalCloseForCloning)(XtransConnInfo ciptr)
1315
1316 {
1317 int ret;
1318
1319 prmsg(2,"LocalCloseForCloning(%p->%d)\n", ciptr, ciptr->fd );
1320
1321
1322
1323 ret=close(ciptr->fd);
1324
1325 return ret;
1326 }
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339 #ifdef TRANS_SERVER
1340 static const char * local_aliases[] = {
1341 "named",
1342 "pipe",
1343 NULL };
1344 #endif
1345
1346 Xtransport TRANS(LocalFuncs) = {
1347
1348 "local",
1349 TRANS_ALIAS | TRANS_LOCAL,
1350 #ifdef TRANS_CLIENT
1351 TRANS(LocalOpenCOTSClient),
1352 #endif
1353 #ifdef TRANS_SERVER
1354 local_aliases,
1355 TRANS(LocalOpenCOTSServer),
1356 #endif
1357 #ifdef TRANS_REOPEN
1358 TRANS(LocalReopenCOTSServer),
1359 #endif
1360 TRANS(LocalSetOption),
1361 #ifdef TRANS_SERVER
1362 TRANS(LocalCreateListener),
1363 TRANS(LocalResetListener),
1364 TRANS(LocalAccept),
1365 #endif
1366 #ifdef TRANS_CLIENT
1367 TRANS(LocalConnect),
1368 #endif
1369 TRANS(LocalBytesReadable),
1370 TRANS(LocalRead),
1371 TRANS(LocalWrite),
1372 TRANS(LocalReadv),
1373 TRANS(LocalWritev),
1374 #if XTRANS_SEND_FDS
1375 TRANS(LocalSendFdInvalid),
1376 TRANS(LocalRecvFdInvalid),
1377 #endif
1378 TRANS(LocalDisconnect),
1379 TRANS(LocalClose),
1380 TRANS(LocalCloseForCloning),
1381 };
1382
1383
1384 #ifdef LOCAL_TRANS_NAMED
1385
1386 Xtransport TRANS(NAMEDFuncs) = {
1387
1388 "named",
1389 TRANS_LOCAL,
1390 #ifdef TRANS_CLIENT
1391 TRANS(LocalOpenCOTSClient),
1392 #endif
1393 #ifdef TRANS_SERVER
1394 NULL,
1395 TRANS(LocalOpenCOTSServer),
1396 #endif
1397 #ifdef TRANS_REOPEN
1398 TRANS(LocalReopenCOTSServer),
1399 #endif
1400 TRANS(LocalSetOption),
1401 #ifdef TRANS_SERVER
1402 TRANS(LocalCreateListener),
1403 TRANS(LocalResetListener),
1404 TRANS(LocalAccept),
1405 #endif
1406 #ifdef TRANS_CLIENT
1407 TRANS(LocalConnect),
1408 #endif
1409 TRANS(LocalBytesReadable),
1410 TRANS(LocalRead),
1411 TRANS(LocalWrite),
1412 TRANS(LocalReadv),
1413 TRANS(LocalWritev),
1414 #if XTRANS_SEND_FDS
1415 TRANS(LocalSendFdInvalid),
1416 TRANS(LocalRecvFdInvalid),
1417 #endif
1418 TRANS(LocalDisconnect),
1419 TRANS(LocalClose),
1420 TRANS(LocalCloseForCloning),
1421 };
1422
1423 Xtransport TRANS(PIPEFuncs) = {
1424
1425 "pipe",
1426 TRANS_ALIAS | TRANS_LOCAL,
1427 #ifdef TRANS_CLIENT
1428 TRANS(LocalOpenCOTSClient),
1429 #endif
1430 #ifdef TRANS_SERVER
1431 NULL,
1432 TRANS(LocalOpenCOTSServer),
1433 #endif
1434 #ifdef TRANS_REOPEN
1435 TRANS(LocalReopenCOTSServer),
1436 #endif
1437 TRANS(LocalSetOption),
1438 #ifdef TRANS_SERVER
1439 TRANS(LocalCreateListener),
1440 TRANS(LocalResetListener),
1441 TRANS(LocalAccept),
1442 #endif
1443 #ifdef TRANS_CLIENT
1444 TRANS(LocalConnect),
1445 #endif
1446 TRANS(LocalBytesReadable),
1447 TRANS(LocalRead),
1448 TRANS(LocalWrite),
1449 TRANS(LocalReadv),
1450 TRANS(LocalWritev),
1451 #if XTRANS_SEND_FDS
1452 TRANS(LocalSendFdInvalid),
1453 TRANS(LocalRecvFdInvalid),
1454 #endif
1455 TRANS(LocalDisconnect),
1456 TRANS(LocalClose),
1457 TRANS(LocalCloseForCloning),
1458 };
1459 #endif
1460
1461