File indexing completed on 2025-09-17 09:18:46
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 #include <ctype.h>
0051 #include <stdlib.h>
0052 #include <string.h>
0053 #ifdef HAVE_SYSTEMD_DAEMON
0054 #include <systemd/sd-daemon.h>
0055 #endif
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069 #define TRANS_TLI_INET_INDEX 1
0070 #define TRANS_TLI_TCP_INDEX 2
0071 #define TRANS_TLI_TLI_INDEX 3
0072 #define TRANS_SOCKET_UNIX_INDEX 4
0073 #define TRANS_SOCKET_LOCAL_INDEX 5
0074 #define TRANS_SOCKET_INET_INDEX 6
0075 #define TRANS_SOCKET_TCP_INDEX 7
0076 #define TRANS_DNET_INDEX 8
0077 #define TRANS_LOCAL_LOCAL_INDEX 9
0078
0079 #define TRANS_LOCAL_NAMED_INDEX 11
0080
0081
0082 #define TRANS_SOCKET_INET6_INDEX 14
0083 #define TRANS_LOCAL_PIPE_INDEX 15
0084
0085 #if defined(IPv6) && !defined(AF_INET6)
0086 #error "Cannot build IPv6 support without AF_INET6"
0087 #endif
0088
0089 static
0090 Xtransport_table Xtransports[] = {
0091 #if defined(TCPCONN)
0092 { &TRANS(SocketTCPFuncs), TRANS_SOCKET_TCP_INDEX },
0093 #if defined(IPv6)
0094 { &TRANS(SocketINET6Funcs), TRANS_SOCKET_INET6_INDEX },
0095 #endif
0096 { &TRANS(SocketINETFuncs), TRANS_SOCKET_INET_INDEX },
0097 #endif
0098 #if defined(UNIXCONN)
0099 #if !defined(LOCALCONN)
0100 { &TRANS(SocketLocalFuncs), TRANS_SOCKET_LOCAL_INDEX },
0101 #endif
0102 { &TRANS(SocketUNIXFuncs), TRANS_SOCKET_UNIX_INDEX },
0103 #endif
0104 #if defined(LOCALCONN)
0105 { &TRANS(LocalFuncs), TRANS_LOCAL_LOCAL_INDEX },
0106 #if defined(SVR4) || defined(__SVR4)
0107 { &TRANS(NAMEDFuncs), TRANS_LOCAL_NAMED_INDEX },
0108 #endif
0109 #ifdef __sun
0110 { &TRANS(PIPEFuncs), TRANS_LOCAL_PIPE_INDEX },
0111 #endif
0112 #endif
0113 };
0114
0115 #define NUMTRANS (sizeof(Xtransports)/sizeof(Xtransport_table))
0116
0117
0118 #ifdef WIN32
0119 #define ioctl ioctlsocket
0120 #endif
0121
0122
0123
0124
0125
0126
0127
0128 void
0129 TRANS(FreeConnInfo) (XtransConnInfo ciptr)
0130
0131 {
0132 prmsg (3,"FreeConnInfo(%p)\n", (void *) ciptr);
0133
0134 if (ciptr->addr)
0135 free (ciptr->addr);
0136
0137 if (ciptr->peeraddr)
0138 free (ciptr->peeraddr);
0139
0140 if (ciptr->port)
0141 free (ciptr->port);
0142
0143 free (ciptr);
0144 }
0145
0146
0147 #define PROTOBUFSIZE 20
0148
0149 static Xtransport *
0150 TRANS(SelectTransport) (const char *protocol)
0151
0152 {
0153 #ifndef HAVE_STRCASECMP
0154 char protobuf[PROTOBUFSIZE];
0155 #endif
0156
0157 prmsg (3,"SelectTransport(%s)\n", protocol);
0158
0159 #ifndef HAVE_STRCASECMP
0160
0161
0162
0163
0164
0165 strncpy (protobuf, protocol, PROTOBUFSIZE - 1);
0166 protobuf[PROTOBUFSIZE-1] = '\0';
0167
0168 for (unsigned int i = 0; i < PROTOBUFSIZE && protobuf[i] != '\0'; i++)
0169 if (isupper ((unsigned char)protobuf[i]))
0170 protobuf[i] = tolower ((unsigned char)protobuf[i]);
0171 #endif
0172
0173
0174
0175 for (unsigned int i = 0; i < NUMTRANS; i++)
0176 {
0177 #ifndef HAVE_STRCASECMP
0178 if (!strcmp (protobuf, Xtransports[i].transport->TransName))
0179 #else
0180 if (!strcasecmp (protocol, Xtransports[i].transport->TransName))
0181 #endif
0182 return Xtransports[i].transport;
0183 }
0184
0185 return NULL;
0186 }
0187
0188 static int
0189 TRANS(ParseAddress) (const char *address,
0190 char **protocol, char **host, char **port)
0191
0192 {
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207 char *mybuf, *tmpptr = NULL;
0208 const char *_protocol = NULL;
0209 const char *_host, *_port;
0210 char hostnamebuf[256];
0211 char *_host_buf;
0212 int _host_len;
0213
0214 prmsg (3,"ParseAddress(%s)\n", address);
0215
0216
0217 if (address[0] == '/') {
0218 _protocol = "local";
0219 _host = "";
0220 _port = address;
0221 } else
0222 #ifdef HAVE_LAUNCHD
0223
0224 if(!strncmp(address,"local//",7)) {
0225 _protocol="local";
0226 _host="";
0227 _port=address+6;
0228 } else
0229 #endif
0230 if (!strncmp(address, "unix:", 5)) {
0231 _protocol = "local";
0232 _host = "";
0233 _port = address + 5;
0234 }
0235 if (_protocol)
0236 goto done_parsing;
0237
0238
0239
0240 tmpptr = mybuf = strdup (address);
0241
0242
0243
0244
0245
0246 _protocol = mybuf;
0247
0248
0249 if ((mybuf == NULL) ||
0250 ( ((mybuf = strchr (mybuf, '/')) == NULL) &&
0251 ((mybuf = strrchr (tmpptr, ':')) == NULL) ) )
0252 {
0253
0254 *protocol = NULL;
0255 *host = NULL;
0256 *port = NULL;
0257 free (tmpptr);
0258 return 0;
0259 }
0260
0261 if (*mybuf == ':')
0262 {
0263
0264
0265
0266
0267 if (mybuf == tmpptr)
0268 {
0269
0270 _protocol = "local";
0271 }
0272 else
0273 {
0274
0275 _protocol = "tcp";
0276 mybuf = tmpptr;
0277 }
0278 }
0279 else
0280 {
0281
0282
0283 *mybuf ++= '\0';
0284
0285 if (strlen(_protocol) == 0)
0286 {
0287
0288
0289
0290
0291 if (*mybuf != ':')
0292 _protocol = "tcp";
0293 else
0294 _protocol = "local";
0295 }
0296 }
0297
0298
0299
0300 _host = _host_buf = mybuf;
0301
0302 if ((mybuf = strrchr (mybuf,':')) == NULL)
0303 {
0304 *protocol = NULL;
0305 *host = NULL;
0306 *port = NULL;
0307 free (tmpptr);
0308 return 0;
0309 }
0310
0311 *mybuf ++= '\0';
0312
0313 _host_len = strlen(_host);
0314 if (_host_len == 0)
0315 {
0316 TRANS(GetHostname) (hostnamebuf, sizeof (hostnamebuf));
0317 _host = hostnamebuf;
0318 }
0319 #ifdef IPv6
0320
0321 else if ( (_host_len > 3) &&
0322 ((strcmp(_protocol, "tcp") == 0) || (strcmp(_protocol, "inet6") == 0))
0323 && (_host_buf[0] == '[') && (_host_buf[_host_len - 1] == ']') ) {
0324 struct sockaddr_in6 sin6;
0325
0326 _host_buf[_host_len - 1] = '\0';
0327
0328
0329 if (inet_pton(AF_INET6, _host + 1, &sin6) == 1) {
0330
0331 _host++;
0332 _protocol = "inet6";
0333 } else {
0334
0335 _host_buf[_host_len - 1] = ']';
0336 }
0337 }
0338 #endif
0339
0340
0341
0342
0343 _port = mybuf;
0344
0345 #if defined(FONT_t) || defined(FS_t)
0346
0347
0348
0349
0350 if ((mybuf = strchr (mybuf,'/')) != NULL)
0351 *mybuf ++= '\0';
0352
0353
0354
0355
0356
0357
0358 #endif
0359
0360 done_parsing:
0361
0362
0363
0364
0365
0366 if ((*protocol = strdup (_protocol)) == NULL)
0367 {
0368
0369 *port = NULL;
0370 *host = NULL;
0371 *protocol = NULL;
0372 free (tmpptr);
0373 return 0;
0374 }
0375
0376 if ((*host = strdup (_host)) == NULL)
0377 {
0378
0379 *port = NULL;
0380 *host = NULL;
0381 free (*protocol);
0382 *protocol = NULL;
0383 free (tmpptr);
0384 return 0;
0385 }
0386
0387 if ((*port = strdup (_port)) == NULL)
0388 {
0389
0390 *port = NULL;
0391 free (*host);
0392 *host = NULL;
0393 free (*protocol);
0394 *protocol = NULL;
0395 free (tmpptr);
0396 return 0;
0397 }
0398
0399 free (tmpptr);
0400
0401 return 1;
0402 }
0403
0404
0405
0406
0407
0408
0409
0410
0411 static XtransConnInfo
0412 TRANS(Open) (int type, const char *address)
0413
0414 {
0415 char *protocol = NULL, *host = NULL, *port = NULL;
0416 XtransConnInfo ciptr = NULL;
0417 Xtransport *thistrans;
0418
0419 prmsg (2,"Open(%d,%s)\n", type, address);
0420
0421 #if defined(WIN32) && defined(TCPCONN)
0422 if (TRANS(WSAStartup)())
0423 {
0424 prmsg (1,"Open: WSAStartup failed\n");
0425 return NULL;
0426 }
0427 #endif
0428
0429
0430
0431 if (TRANS(ParseAddress) (address, &protocol, &host, &port) == 0)
0432 {
0433 prmsg (1,"Open: Unable to Parse address %s\n", address);
0434 return NULL;
0435 }
0436
0437
0438
0439 if ((thistrans = TRANS(SelectTransport) (protocol)) == NULL)
0440 {
0441 prmsg (1,"Open: Unable to find transport for %s\n",
0442 protocol);
0443
0444 free (protocol);
0445 free (host);
0446 free (port);
0447 return NULL;
0448 }
0449
0450
0451
0452 switch (type)
0453 {
0454 case XTRANS_OPEN_COTS_CLIENT:
0455 #ifdef TRANS_CLIENT
0456 ciptr = thistrans->OpenCOTSClient(thistrans, protocol, host, port);
0457 #endif
0458 break;
0459 case XTRANS_OPEN_COTS_SERVER:
0460 #ifdef TRANS_SERVER
0461 ciptr = thistrans->OpenCOTSServer(thistrans, protocol, host, port);
0462 #endif
0463 break;
0464 default:
0465 prmsg (1,"Open: Unknown Open type %d\n", type);
0466 }
0467
0468 if (ciptr == NULL)
0469 {
0470 if (!(thistrans->flags & TRANS_DISABLED))
0471 {
0472 prmsg (1,"Open: transport open failed for %s/%s:%s\n",
0473 protocol, host, port);
0474 }
0475 free (protocol);
0476 free (host);
0477 free (port);
0478 return NULL;
0479 }
0480
0481 ciptr->transptr = thistrans;
0482 ciptr->port = port;
0483
0484 free (protocol);
0485 free (host);
0486
0487 return ciptr;
0488 }
0489
0490
0491 #ifdef TRANS_REOPEN
0492
0493
0494
0495
0496
0497
0498
0499 static XtransConnInfo
0500 TRANS(Reopen) (int type, int trans_id, int fd, const char *port)
0501
0502 {
0503 XtransConnInfo ciptr = NULL;
0504 Xtransport *thistrans = NULL;
0505 char *save_port;
0506
0507 prmsg (2,"Reopen(%d,%d,%s)\n", trans_id, fd, port);
0508
0509
0510
0511 for (unsigned int i = 0; i < NUMTRANS; i++)
0512 {
0513 if (Xtransports[i].transport_id == trans_id)
0514 {
0515 thistrans = Xtransports[i].transport;
0516 break;
0517 }
0518 }
0519
0520 if (thistrans == NULL)
0521 {
0522 prmsg (1,"Reopen: Unable to find transport id %d\n",
0523 trans_id);
0524
0525 return NULL;
0526 }
0527
0528 if ((save_port = strdup (port)) == NULL)
0529 {
0530 prmsg (1,"Reopen: Unable to malloc port string\n");
0531
0532 return NULL;
0533 }
0534
0535
0536
0537 switch (type)
0538 {
0539 case XTRANS_OPEN_COTS_SERVER:
0540 ciptr = thistrans->ReopenCOTSServer(thistrans, fd, port);
0541 break;
0542 default:
0543 prmsg (1,"Reopen: Bad Open type %d\n", type);
0544 }
0545
0546 if (ciptr == NULL)
0547 {
0548 prmsg (1,"Reopen: transport open failed\n");
0549 free (save_port);
0550 return NULL;
0551 }
0552
0553 ciptr->transptr = thistrans;
0554 ciptr->port = save_port;
0555
0556 return ciptr;
0557 }
0558
0559 #endif
0560
0561
0562
0563
0564
0565
0566
0567
0568
0569 #ifdef TRANS_CLIENT
0570
0571 XtransConnInfo
0572 TRANS(OpenCOTSClient) (const char *address)
0573
0574 {
0575 prmsg (2,"OpenCOTSClient(%s)\n", address);
0576 return TRANS(Open) (XTRANS_OPEN_COTS_CLIENT, address);
0577 }
0578
0579 #endif
0580
0581
0582 #ifdef TRANS_SERVER
0583
0584 XtransConnInfo
0585 TRANS(OpenCOTSServer) (const char *address)
0586
0587 {
0588 prmsg (2,"OpenCOTSServer(%s)\n", address);
0589 return TRANS(Open) (XTRANS_OPEN_COTS_SERVER, address);
0590 }
0591
0592 #endif
0593
0594
0595 #ifdef TRANS_REOPEN
0596
0597 XtransConnInfo
0598 TRANS(ReopenCOTSServer) (int trans_id, int fd, const char *port)
0599
0600 {
0601 prmsg (2,"ReopenCOTSServer(%d, %d, %s)\n", trans_id, fd, port);
0602 return TRANS(Reopen) (XTRANS_OPEN_COTS_SERVER, trans_id, fd, port);
0603 }
0604
0605 int
0606 TRANS(GetReopenInfo) (XtransConnInfo ciptr,
0607 int *trans_id, int *fd, char **port)
0608
0609 {
0610 for (unsigned int i = 0; i < NUMTRANS; i++)
0611 {
0612 if (Xtransports[i].transport == ciptr->transptr)
0613 {
0614 *trans_id = Xtransports[i].transport_id;
0615 *fd = ciptr->fd;
0616
0617 if ((*port = strdup (ciptr->port)) == NULL)
0618 return 0;
0619 else
0620 return 1;
0621 }
0622 }
0623
0624 return 0;
0625 }
0626
0627 #endif
0628
0629
0630 int
0631 TRANS(SetOption) (XtransConnInfo ciptr, int option, int arg)
0632
0633 {
0634 int fd = ciptr->fd;
0635 int ret = 0;
0636
0637 prmsg (2,"SetOption(%d,%d,%d)\n", fd, option, arg);
0638
0639
0640
0641
0642
0643
0644
0645
0646
0647
0648
0649 switch (option)
0650 {
0651 case TRANS_NONBLOCKING:
0652 switch (arg)
0653 {
0654 case 0:
0655
0656 break;
0657 case 1:
0658
0659 #if defined(O_NONBLOCK)
0660 ret = fcntl (fd, F_GETFL, 0);
0661 if (ret != -1)
0662 ret = fcntl (fd, F_SETFL, ret | O_NONBLOCK);
0663 #else
0664 #ifdef FIOSNBIO
0665 {
0666 int arg;
0667 arg = 1;
0668 ret = ioctl (fd, FIOSNBIO, &arg);
0669 }
0670 #else
0671 #if defined(WIN32)
0672 {
0673 #ifdef WIN32
0674 u_long arg;
0675 #else
0676 int arg;
0677 #endif
0678 arg = 1;
0679
0680
0681 ret = ioctl (fd, FIONBIO, &arg);
0682 }
0683 #else
0684 ret = fcntl (fd, F_GETFL, 0);
0685 #ifdef FNDELAY
0686 ret = fcntl (fd, F_SETFL, ret | FNDELAY);
0687 #else
0688 ret = fcntl (fd, F_SETFL, ret | O_NDELAY);
0689 #endif
0690 #endif
0691 #endif
0692 #endif
0693 break;
0694 default:
0695
0696 break;
0697 }
0698 break;
0699 case TRANS_CLOSEONEXEC:
0700 #ifdef F_SETFD
0701 #ifdef FD_CLOEXEC
0702 ret = fcntl (fd, F_SETFD, FD_CLOEXEC);
0703 #else
0704 ret = fcntl (fd, F_SETFD, 1);
0705 #endif
0706 #endif
0707 break;
0708 }
0709
0710 return ret;
0711 }
0712
0713 #ifdef TRANS_SERVER
0714
0715 int
0716 TRANS(CreateListener) (XtransConnInfo ciptr, const char *port, unsigned int flags)
0717
0718 {
0719 return ciptr->transptr->CreateListener (ciptr, port, flags);
0720 }
0721
0722 int
0723 TRANS(Received) (const char * protocol)
0724
0725 {
0726 Xtransport *trans;
0727 int i = 0, ret = 0;
0728
0729 prmsg (5, "Received(%s)\n", protocol);
0730
0731 if ((trans = TRANS(SelectTransport)(protocol)) == NULL)
0732 {
0733 prmsg (1,"Received: unable to find transport: %s\n",
0734 protocol);
0735
0736 return -1;
0737 }
0738 if (trans->flags & TRANS_ALIAS) {
0739 if (trans->nolisten)
0740 while (trans->nolisten[i]) {
0741 ret |= TRANS(Received)(trans->nolisten[i]);
0742 i++;
0743 }
0744 }
0745
0746 trans->flags |= TRANS_RECEIVED;
0747 return ret;
0748 }
0749
0750 int
0751 TRANS(NoListen) (const char * protocol)
0752
0753 {
0754 Xtransport *trans;
0755 int i = 0, ret = 0;
0756
0757 if ((trans = TRANS(SelectTransport)(protocol)) == NULL)
0758 {
0759 prmsg (1,"TransNoListen: unable to find transport: %s\n",
0760 protocol);
0761
0762 return -1;
0763 }
0764 if (trans->flags & TRANS_ALIAS) {
0765 if (trans->nolisten)
0766 while (trans->nolisten[i]) {
0767 ret |= TRANS(NoListen)(trans->nolisten[i]);
0768 i++;
0769 }
0770 }
0771
0772 trans->flags |= TRANS_NOLISTEN;
0773 return ret;
0774 }
0775
0776 int
0777 TRANS(Listen) (const char * protocol)
0778 {
0779 Xtransport *trans;
0780 int i = 0, ret = 0;
0781
0782 if ((trans = TRANS(SelectTransport)(protocol)) == NULL)
0783 {
0784 prmsg (1,"TransListen: unable to find transport: %s\n",
0785 protocol);
0786
0787 return -1;
0788 }
0789 if (trans->flags & TRANS_ALIAS) {
0790 if (trans->nolisten)
0791 while (trans->nolisten[i]) {
0792 ret |= TRANS(Listen)(trans->nolisten[i]);
0793 i++;
0794 }
0795 }
0796
0797 trans->flags &= ~TRANS_NOLISTEN;
0798 return ret;
0799 }
0800
0801 int
0802 TRANS(IsListening) (const char * protocol)
0803 {
0804 Xtransport *trans;
0805
0806 if ((trans = TRANS(SelectTransport)(protocol)) == NULL)
0807 {
0808 prmsg (1,"TransIsListening: unable to find transport: %s\n",
0809 protocol);
0810
0811 return 0;
0812 }
0813
0814 return !(trans->flags & TRANS_NOLISTEN);
0815 }
0816
0817 int
0818 TRANS(ResetListener) (XtransConnInfo ciptr)
0819
0820 {
0821 if (ciptr->transptr->ResetListener)
0822 return ciptr->transptr->ResetListener (ciptr);
0823 else
0824 return TRANS_RESET_NOOP;
0825 }
0826
0827
0828 XtransConnInfo
0829 TRANS(Accept) (XtransConnInfo ciptr, int *status)
0830
0831 {
0832 XtransConnInfo newciptr;
0833
0834 prmsg (2,"Accept(%d)\n", ciptr->fd);
0835
0836 newciptr = ciptr->transptr->Accept (ciptr, status);
0837
0838 if (newciptr)
0839 newciptr->transptr = ciptr->transptr;
0840
0841 return newciptr;
0842 }
0843
0844 #endif
0845
0846
0847 #ifdef TRANS_CLIENT
0848
0849 int
0850 TRANS(Connect) (XtransConnInfo ciptr, const char *address)
0851
0852 {
0853 char *protocol;
0854 char *host;
0855 char *port;
0856 int ret;
0857
0858 prmsg (2,"Connect(%d,%s)\n", ciptr->fd, address);
0859
0860 if (TRANS(ParseAddress) (address, &protocol, &host, &port) == 0)
0861 {
0862 prmsg (1,"Connect: Unable to Parse address %s\n",
0863 address);
0864 return -1;
0865 }
0866
0867 #ifdef HAVE_LAUNCHD
0868 if (!host) host=strdup("");
0869 #endif
0870
0871 if (!port || !*port)
0872 {
0873 prmsg (1,"Connect: Missing port specification in %s\n",
0874 address);
0875 if (protocol) free (protocol);
0876 if (host) free (host);
0877 return -1;
0878 }
0879
0880 ret = ciptr->transptr->Connect (ciptr, host, port);
0881
0882 if (protocol) free (protocol);
0883 if (host) free (host);
0884 if (port) free (port);
0885
0886 return ret;
0887 }
0888
0889 #endif
0890
0891
0892 int
0893 TRANS(BytesReadable) (XtransConnInfo ciptr, BytesReadable_t *pend)
0894
0895 {
0896 return ciptr->transptr->BytesReadable (ciptr, pend);
0897 }
0898
0899 int
0900 TRANS(Read) (XtransConnInfo ciptr, char *buf, int size)
0901
0902 {
0903 return ciptr->transptr->Read (ciptr, buf, size);
0904 }
0905
0906 int
0907 TRANS(Write) (XtransConnInfo ciptr, const char *buf, int size)
0908
0909 {
0910 return ciptr->transptr->Write (ciptr, buf, size);
0911 }
0912
0913 int
0914 TRANS(Readv) (XtransConnInfo ciptr, struct iovec *buf, int size)
0915
0916 {
0917 return ciptr->transptr->Readv (ciptr, buf, size);
0918 }
0919
0920 int
0921 TRANS(Writev) (XtransConnInfo ciptr, struct iovec *buf, int size)
0922
0923 {
0924 return ciptr->transptr->Writev (ciptr, buf, size);
0925 }
0926
0927 #if XTRANS_SEND_FDS
0928 int
0929 TRANS(SendFd) (XtransConnInfo ciptr, int fd, int do_close)
0930 {
0931 return ciptr->transptr->SendFd(ciptr, fd, do_close);
0932 }
0933
0934 int
0935 TRANS(RecvFd) (XtransConnInfo ciptr)
0936 {
0937 return ciptr->transptr->RecvFd(ciptr);
0938 }
0939 #endif
0940
0941 int
0942 TRANS(Disconnect) (XtransConnInfo ciptr)
0943
0944 {
0945 return ciptr->transptr->Disconnect (ciptr);
0946 }
0947
0948 int
0949 TRANS(Close) (XtransConnInfo ciptr)
0950
0951 {
0952 int ret;
0953
0954 prmsg (2,"Close(%d)\n", ciptr->fd);
0955
0956 ret = ciptr->transptr->Close (ciptr);
0957
0958 TRANS(FreeConnInfo) (ciptr);
0959
0960 return ret;
0961 }
0962
0963 int
0964 TRANS(CloseForCloning) (XtransConnInfo ciptr)
0965
0966 {
0967 int ret;
0968
0969 prmsg (2,"CloseForCloning(%d)\n", ciptr->fd);
0970
0971 ret = ciptr->transptr->CloseForCloning (ciptr);
0972
0973 TRANS(FreeConnInfo) (ciptr);
0974
0975 return ret;
0976 }
0977
0978 int
0979 TRANS(IsLocal) (XtransConnInfo ciptr)
0980
0981 {
0982 return (ciptr->family == AF_UNIX);
0983 }
0984
0985 int
0986 TRANS(GetPeerAddr) (XtransConnInfo ciptr, int *familyp, int *addrlenp,
0987 Xtransaddr **addrp)
0988
0989 {
0990 prmsg (2,"GetPeerAddr(%d)\n", ciptr->fd);
0991
0992 *familyp = ciptr->family;
0993 *addrlenp = ciptr->peeraddrlen;
0994
0995 if ((*addrp = malloc (ciptr->peeraddrlen)) == NULL)
0996 {
0997 prmsg (1,"GetPeerAddr: malloc failed\n");
0998 return -1;
0999 }
1000 memcpy(*addrp, ciptr->peeraddr, ciptr->peeraddrlen);
1001
1002 return 0;
1003 }
1004
1005
1006 int
1007 TRANS(GetConnectionNumber) (XtransConnInfo ciptr)
1008
1009 {
1010 return ciptr->fd;
1011 }
1012
1013
1014
1015
1016
1017
1018
1019
1020 #ifdef TRANS_SERVER
1021
1022 static int
1023 complete_network_count (void)
1024
1025 {
1026 int count = 0;
1027 int found_local = 0;
1028
1029
1030
1031
1032
1033 for (unsigned int i = 0; i < NUMTRANS; i++)
1034 {
1035 if (Xtransports[i].transport->flags & TRANS_ALIAS
1036 || Xtransports[i].transport->flags & TRANS_NOLISTEN)
1037 continue;
1038
1039 if (Xtransports[i].transport->flags & TRANS_LOCAL)
1040 found_local = 1;
1041 else
1042 count++;
1043 }
1044
1045 return (count + found_local);
1046 }
1047
1048
1049 static int
1050 receive_listening_fds(const char* port, XtransConnInfo* temp_ciptrs,
1051 int* count_ret)
1052
1053 {
1054 #ifdef HAVE_SYSTEMD_DAEMON
1055 XtransConnInfo ciptr;
1056 int i, systemd_listen_fds;
1057
1058 systemd_listen_fds = sd_listen_fds(1);
1059 if (systemd_listen_fds < 0)
1060 {
1061 prmsg (1, "receive_listening_fds: sd_listen_fds error: %s\n",
1062 strerror(-systemd_listen_fds));
1063 return -1;
1064 }
1065
1066 for (i = 0; i < systemd_listen_fds && *count_ret < (int)NUMTRANS; i++)
1067 {
1068 struct sockaddr_storage a;
1069 int ti;
1070 const char* tn;
1071 socklen_t al;
1072
1073 al = sizeof(a);
1074 if (getsockname(i + SD_LISTEN_FDS_START, (struct sockaddr*)&a, &al) < 0) {
1075 prmsg (1, "receive_listening_fds: getsockname error: %s\n",
1076 strerror(errno));
1077 return -1;
1078 }
1079
1080 switch (a.ss_family)
1081 {
1082 case AF_UNIX:
1083 ti = TRANS_SOCKET_UNIX_INDEX;
1084 if (*((struct sockaddr_un*)&a)->sun_path == '\0' &&
1085 al > sizeof(sa_family_t))
1086 tn = "local";
1087 else
1088 tn = "unix";
1089 break;
1090 case AF_INET:
1091 ti = TRANS_SOCKET_INET_INDEX;
1092 tn = "inet";
1093 break;
1094 #ifdef IPv6
1095 case AF_INET6:
1096 ti = TRANS_SOCKET_INET6_INDEX;
1097 tn = "inet6";
1098 break;
1099 #endif
1100 default:
1101 prmsg (1, "receive_listening_fds:"
1102 "Got unknown socket address family\n");
1103 return -1;
1104 }
1105
1106 ciptr = TRANS(ReopenCOTSServer)(ti, i + SD_LISTEN_FDS_START, port);
1107 if (!ciptr)
1108 {
1109 prmsg (1, "receive_listening_fds:"
1110 "Got NULL while trying to reopen socket received from systemd.\n");
1111 return -1;
1112 }
1113
1114 prmsg (5, "receive_listening_fds: received listener for %s, %d\n",
1115 tn, ciptr->fd);
1116 temp_ciptrs[(*count_ret)++] = ciptr;
1117 TRANS(Received)(tn);
1118 }
1119 #endif
1120 return 0;
1121 }
1122
1123 #ifdef XQUARTZ_EXPORTS_LAUNCHD_FD
1124 extern int xquartz_launchd_fd;
1125 #endif
1126
1127 int
1128 TRANS(MakeAllCOTSServerListeners) (const char *port, int *partial,
1129 int *count_ret, XtransConnInfo **ciptrs_ret)
1130
1131 {
1132 char buffer[256];
1133 XtransConnInfo ciptr, temp_ciptrs[NUMTRANS] = { NULL };
1134 int status, j;
1135
1136 #ifdef IPv6
1137 int ipv6_succ = 0;
1138 #endif
1139 prmsg (2,"MakeAllCOTSServerListeners(%s,%p)\n",
1140 port ? port : "NULL", (void *) ciptrs_ret);
1141
1142 *count_ret = 0;
1143
1144 #ifdef XQUARTZ_EXPORTS_LAUNCHD_FD
1145 fprintf(stderr, "Launchd socket fd: %d\n", xquartz_launchd_fd);
1146 if(xquartz_launchd_fd != -1) {
1147 if((ciptr = TRANS(ReopenCOTSServer(TRANS_SOCKET_LOCAL_INDEX,
1148 xquartz_launchd_fd, getenv("DISPLAY"))))==NULL)
1149 fprintf(stderr,"Got NULL while trying to Reopen launchd port\n");
1150 else
1151 temp_ciptrs[(*count_ret)++] = ciptr;
1152 }
1153 #endif
1154
1155 if (receive_listening_fds(port, temp_ciptrs, count_ret) < 0)
1156 return -1;
1157
1158 for (unsigned int i = 0; i < NUMTRANS; i++)
1159 {
1160 Xtransport *trans = Xtransports[i].transport;
1161 unsigned int flags = 0;
1162
1163 if (trans->flags&TRANS_ALIAS || trans->flags&TRANS_NOLISTEN ||
1164 trans->flags&TRANS_RECEIVED)
1165 continue;
1166
1167 snprintf(buffer, sizeof(buffer), "%s/:%s",
1168 trans->TransName, port ? port : "");
1169
1170 prmsg (5,"MakeAllCOTSServerListeners: opening %s\n",
1171 buffer);
1172
1173 if ((ciptr = TRANS(OpenCOTSServer(buffer))) == NULL)
1174 {
1175 if (trans->flags & TRANS_DISABLED)
1176 continue;
1177
1178 prmsg (1,
1179 "MakeAllCOTSServerListeners: failed to open listener for %s\n",
1180 trans->TransName);
1181 continue;
1182 }
1183 #ifdef IPv6
1184 if ((Xtransports[i].transport_id == TRANS_SOCKET_INET_INDEX
1185 && ipv6_succ))
1186 flags |= ADDR_IN_USE_ALLOWED;
1187 #endif
1188
1189 if ((status = TRANS(CreateListener (ciptr, port, flags))) < 0)
1190 {
1191 if (*partial != 0)
1192 continue;
1193
1194 if (status == TRANS_ADDR_IN_USE)
1195 {
1196
1197
1198
1199
1200
1201
1202 prmsg (1,
1203 "MakeAllCOTSServerListeners: server already running\n");
1204
1205 for (j = 0; j < *count_ret; j++)
1206 if (temp_ciptrs[j] != NULL)
1207 TRANS(Close) (temp_ciptrs[j]);
1208
1209 *count_ret = 0;
1210 *ciptrs_ret = NULL;
1211 *partial = 0;
1212 return -1;
1213 }
1214 else
1215 {
1216 prmsg (1,
1217 "MakeAllCOTSServerListeners: failed to create listener for %s\n",
1218 trans->TransName);
1219
1220 continue;
1221 }
1222 }
1223
1224 #ifdef IPv6
1225 if (Xtransports[i].transport_id == TRANS_SOCKET_INET6_INDEX)
1226 ipv6_succ = 1;
1227 #endif
1228
1229 prmsg (5,
1230 "MakeAllCOTSServerListeners: opened listener for %s, %d\n",
1231 trans->TransName, ciptr->fd);
1232
1233 temp_ciptrs[*count_ret] = ciptr;
1234 (*count_ret)++;
1235 }
1236
1237 *partial = (*count_ret < complete_network_count());
1238
1239 prmsg (5,
1240 "MakeAllCOTSServerListeners: partial=%d, actual=%d, complete=%d \n",
1241 *partial, *count_ret, complete_network_count());
1242
1243 if (*count_ret > 0)
1244 {
1245 if ((*ciptrs_ret = malloc (
1246 *count_ret * sizeof (XtransConnInfo))) == NULL)
1247 {
1248 return -1;
1249 }
1250
1251 for (int i = 0; i < *count_ret; i++)
1252 {
1253 (*ciptrs_ret)[i] = temp_ciptrs[i];
1254 }
1255 }
1256 else
1257 *ciptrs_ret = NULL;
1258
1259 return 0;
1260 }
1261
1262 #endif
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272 #ifdef WIN32
1273
1274
1275
1276
1277
1278 static int TRANS(ReadV) (XtransConnInfo ciptr, struct iovec *iov, int iovcnt)
1279
1280 {
1281 int i, len, total;
1282 char *base;
1283
1284 ESET(0);
1285 for (i = 0, total = 0; i < iovcnt; i++, iov++) {
1286 len = iov->iov_len;
1287 base = iov->iov_base;
1288 while (len > 0) {
1289 register int nbytes;
1290 nbytes = TRANS(Read) (ciptr, base, len);
1291 if (nbytes < 0 && total == 0) return -1;
1292 if (nbytes <= 0) return total;
1293 ESET(0);
1294 len -= nbytes;
1295 total += nbytes;
1296 base += nbytes;
1297 }
1298 }
1299 return total;
1300 }
1301
1302
1303
1304
1305
1306
1307 static int TRANS(WriteV) (XtransConnInfo ciptr, struct iovec *iov, int iovcnt)
1308
1309 {
1310 int i, len, total;
1311 char *base;
1312
1313 ESET(0);
1314 for (i = 0, total = 0; i < iovcnt; i++, iov++) {
1315 len = iov->iov_len;
1316 base = iov->iov_base;
1317 while (len > 0) {
1318 register int nbytes;
1319 nbytes = TRANS(Write) (ciptr, base, len);
1320 if (nbytes < 0 && total == 0) return -1;
1321 if (nbytes <= 0) return total;
1322 ESET(0);
1323 len -= nbytes;
1324 total += nbytes;
1325 base += nbytes;
1326 }
1327 }
1328 return total;
1329 }
1330
1331 #endif
1332
1333
1334 #if defined(_POSIX_SOURCE) || defined(SVR4) || defined(__SVR4)
1335 #ifndef NEED_UTSNAME
1336 #define NEED_UTSNAME
1337 #endif
1338 #include <sys/utsname.h>
1339 #endif
1340
1341
1342
1343
1344
1345 int TRANS(GetHostname) (char *buf, int maxlen)
1346
1347 {
1348 int len;
1349
1350 #ifdef NEED_UTSNAME
1351 struct utsname name;
1352
1353 uname (&name);
1354 len = strlen (name.nodename);
1355 if (len >= maxlen) len = maxlen - 1;
1356 memcpy (buf, name.nodename, len);
1357 buf[len] = '\0';
1358 #else
1359 buf[0] = '\0';
1360 (void) gethostname (buf, maxlen);
1361 buf [maxlen - 1] = '\0';
1362 len = strlen(buf);
1363 #endif
1364 return len;
1365 }