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