3 Copyright 1993, 1994, 1998 The Open Group
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
11 The above copyright notice and this permission notice shall be included
12 in all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 OTHER DEALINGS IN THE SOFTWARE.
22 Except as contained in this notice, the name of The Open Group shall
23 not be used in advertising or otherwise to promote the sale, use or
24 other dealings in this Software without prior written authorization
27 * Copyright 1993, 1994 NCR Corporation - Dayton, Ohio, USA
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.
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.
53 * The transport table contains a definition for every transport (protocol)
54 * family. All operations that can be made on the transport go through this
57 * Each transport is assigned a unique transport id.
59 * New transports can be added by adding an entry in this table.
60 * For compatiblity, the transport ids should never be renumbered.
61 * Always add to the end of the list.
64 #define TRANS_TLI_INET_INDEX 1
65 #define TRANS_TLI_TCP_INDEX 2
66 #define TRANS_TLI_TLI_INDEX 3
67 #define TRANS_SOCKET_UNIX_INDEX 4
68 #define TRANS_SOCKET_LOCAL_INDEX 5
69 #define TRANS_SOCKET_INET_INDEX 6
70 #define TRANS_SOCKET_TCP_INDEX 7
71 #define TRANS_DNET_INDEX 8
72 #define TRANS_LOCAL_LOCAL_INDEX 9
73 #define TRANS_LOCAL_PTS_INDEX 10
74 #define TRANS_LOCAL_NAMED_INDEX 11
75 /* 12 used to be ISC, but that's gone. */
76 #define TRANS_LOCAL_SCO_INDEX 13
77 #define TRANS_SOCKET_INET6_INDEX 14
78 #define TRANS_LOCAL_PIPE_INDEX 15
82 Xtransport_table Xtransports[] = {
83 #if defined(STREAMSCONN)
84 { &TRANS(TLITCPFuncs), TRANS_TLI_TCP_INDEX },
85 { &TRANS(TLIINETFuncs), TRANS_TLI_INET_INDEX },
86 { &TRANS(TLITLIFuncs), TRANS_TLI_TLI_INDEX },
87 #endif /* STREAMSCONN */
89 { &TRANS(SocketTCPFuncs), TRANS_SOCKET_TCP_INDEX },
90 #if defined(IPv6) && defined(AF_INET6)
91 { &TRANS(SocketINET6Funcs), TRANS_SOCKET_INET6_INDEX },
93 { &TRANS(SocketINETFuncs), TRANS_SOCKET_INET_INDEX },
96 #if !defined(LOCALCONN)
97 { &TRANS(SocketLocalFuncs), TRANS_SOCKET_LOCAL_INDEX },
98 #endif /* !LOCALCONN */
99 { &TRANS(SocketUNIXFuncs), TRANS_SOCKET_UNIX_INDEX },
100 #endif /* UNIXCONN */
101 #if defined(LOCALCONN)
102 { &TRANS(LocalFuncs), TRANS_LOCAL_LOCAL_INDEX },
104 { &TRANS(PTSFuncs), TRANS_LOCAL_PTS_INDEX },
106 #if defined(SVR4) || defined(__SVR4)
107 { &TRANS(NAMEDFuncs), TRANS_LOCAL_NAMED_INDEX },
110 { &TRANS(PIPEFuncs), TRANS_LOCAL_PIPE_INDEX },
112 #if defined(__SCO__) || defined(__UNIXWARE__)
113 { &TRANS(SCOFuncs), TRANS_LOCAL_SCO_INDEX },
114 #endif /* __SCO__ || __UNIXWARE__ */
115 #endif /* LOCALCONN */
118 #define NUMTRANS (sizeof(Xtransports)/sizeof(Xtransport_table))
122 #define ioctl ioctlsocket
128 * These are a few utility function used by the public interface functions.
132 TRANS(FreeConnInfo) (XtransConnInfo ciptr)
135 prmsg (3,"FreeConnInfo(%p)\n", ciptr);
141 free (ciptr->peeraddr);
150 #define PROTOBUFSIZE 20
153 TRANS(SelectTransport) (const char *protocol)
156 char protobuf[PROTOBUFSIZE];
159 prmsg (3,"SelectTransport(%s)\n", protocol);
162 * Force Protocol to be lowercase as a way of doing
163 * a case insensitive match.
166 strncpy (protobuf, protocol, PROTOBUFSIZE - 1);
167 protobuf[PROTOBUFSIZE-1] = '\0';
169 for (i = 0; i < PROTOBUFSIZE && protobuf[i] != '\0'; i++)
170 if (isupper (protobuf[i]))
171 protobuf[i] = tolower (protobuf[i]);
173 /* Look at all of the configured protocols */
175 for (i = 0; i < NUMTRANS; i++)
177 if (!strcmp (protobuf, Xtransports[i].transport->TransName))
178 return Xtransports[i].transport;
188 TRANS(ParseAddress) (char *address, char **protocol, char **host, char **port)
192 * For the font library, the address is a string formatted
193 * as "protocol/host:port[/catalogue]". Note that the catologue
194 * is optional. At this time, the catologue info is ignored, but
195 * we have to parse it anyways.
197 * Other than fontlib, the address is a string formatted
198 * as "protocol/host:port".
200 * If the protocol part is missing, then assume TCP.
201 * If the protocol part and host part are missing, then assume local.
202 * If a "::" is found then assume DNET.
205 char *mybuf, *tmpptr;
206 const char *_protocol;
208 char hostnamebuf[256];
211 prmsg (3,"ParseAddress(%s)\n", address);
213 /* Copy the string so it can be changed */
215 tmpptr = mybuf = strdup (address);
217 /* Parse the string to get each component */
219 /* Get the protocol part */
224 if ( ((mybuf = strchr (mybuf,'/')) == NULL) &&
225 ((mybuf = strrchr (tmpptr,':')) == NULL) )
227 /* address is in a bad format */
238 * If there is a hostname, then assume tcp, otherwise
243 /* There is neither a protocol or host specified */
248 /* There is a hostname specified */
250 mybuf = tmpptr; /* reset to the begining of the host ptr */
257 *mybuf ++= '\0'; /* put a null at the end of the protocol */
259 if (strlen(_protocol) == 0)
262 * If there is a hostname, then assume tcp, otherwise
272 /* Get the host part */
276 if ((mybuf = strrchr (mybuf,':')) == NULL)
287 _host_len = strlen(_host);
290 TRANS(GetHostname) (hostnamebuf, sizeof (hostnamebuf));
293 #if defined(IPv6) && defined(AF_INET6)
294 /* hostname in IPv6 [numeric_addr]:0 form? */
295 else if ( (_host_len > 3) &&
296 ((strcmp(_protocol, "tcp") == 0) || (strcmp(_protocol, "inet6") == 0))
297 && (*_host == '[') && (*(_host + _host_len - 1) == ']') ) {
298 struct sockaddr_in6 sin6;
300 *(_host + _host_len - 1) = '\0';
302 /* Verify address is valid IPv6 numeric form */
303 if (inet_pton(AF_INET6, _host + 1, &sin6) == 1) {
304 /* It is. Use it as such. */
308 /* It's not, restore it just in case some other code can use it. */
309 *(_host + _host_len - 1) = ']';
319 #if defined(FONT_t) || defined(FS_t)
321 * Is there an optional catalogue list?
324 if ((mybuf = strchr (mybuf,'/')) != NULL)
328 * The rest, if any, is the (currently unused) catalogue list.
330 * _catalogue = mybuf;
335 /* launchd sockets will look like 'local//tmp/launch-XgkNns/:0' */
336 if(address != NULL && strlen(address)>8 && (!strncmp(address,"local//",7))) {
344 * Now that we have all of the components, allocate new
345 * string space for them.
348 if ((*protocol = strdup (_protocol)) == NULL)
358 if ((*host = strdup (_host)) == NULL)
369 if ((*port = strdup (_port)) == NULL)
388 * TRANS(Open) does all of the real work opening a connection. The only
389 * funny part about this is the type parameter which is used to decide which
390 * type of open to perform.
393 static XtransConnInfo
394 TRANS(Open) (int type, char *address)
397 char *protocol = NULL, *host = NULL, *port = NULL;
398 XtransConnInfo ciptr = NULL;
399 Xtransport *thistrans;
401 prmsg (2,"Open(%d,%s)\n", type, address);
403 #if defined(WIN32) && defined(TCPCONN)
404 if (TRANS(WSAStartup)())
406 prmsg (1,"Open: WSAStartup failed\n");
411 /* Parse the Address */
413 if (TRANS(ParseAddress) (address, &protocol, &host, &port) == 0)
415 prmsg (1,"Open: Unable to Parse address %s\n", address);
419 /* Determine the transport type */
421 if ((thistrans = TRANS(SelectTransport) (protocol)) == NULL)
423 prmsg (1,"Open: Unable to find transport for %s\n",
432 /* Open the transport */
436 case XTRANS_OPEN_COTS_CLIENT:
438 ciptr = thistrans->OpenCOTSClient(thistrans, protocol, host, port);
439 #endif /* TRANS_CLIENT */
441 case XTRANS_OPEN_COTS_SERVER:
443 ciptr = thistrans->OpenCOTSServer(thistrans, protocol, host, port);
444 #endif /* TRANS_SERVER */
446 case XTRANS_OPEN_CLTS_CLIENT:
448 ciptr = thistrans->OpenCLTSClient(thistrans, protocol, host, port);
449 #endif /* TRANS_CLIENT */
451 case XTRANS_OPEN_CLTS_SERVER:
453 ciptr = thistrans->OpenCLTSServer(thistrans, protocol, host, port);
454 #endif /* TRANS_SERVER */
457 prmsg (1,"Open: Unknown Open type %d\n", type);
462 if (!(thistrans->flags & TRANS_DISABLED))
464 prmsg (1,"Open: transport open failed for %s/%s:%s\n",
465 protocol, host, port);
473 ciptr->transptr = thistrans;
474 ciptr->port = port; /* We need this for TRANS(Reopen) */
486 * We might want to create an XtransConnInfo object based on a previously
487 * opened connection. For example, the font server may clone itself and
488 * pass file descriptors to the parent.
491 static XtransConnInfo
492 TRANS(Reopen) (int type, int trans_id, int fd, char *port)
495 XtransConnInfo ciptr = NULL;
496 Xtransport *thistrans = NULL;
500 prmsg (2,"Reopen(%d,%d,%s)\n", trans_id, fd, port);
502 /* Determine the transport type */
504 for (i = 0; i < NUMTRANS; i++)
505 if (Xtransports[i].transport_id == trans_id)
507 thistrans = Xtransports[i].transport;
511 if (thistrans == NULL)
513 prmsg (1,"Reopen: Unable to find transport id %d\n",
519 if ((save_port = strdup (port)) == NULL)
521 prmsg (1,"Reopen: Unable to malloc port string\n");
526 /* Get a new XtransConnInfo object */
530 case XTRANS_OPEN_COTS_SERVER:
531 ciptr = thistrans->ReopenCOTSServer(thistrans, fd, port);
533 case XTRANS_OPEN_CLTS_SERVER:
534 ciptr = thistrans->ReopenCLTSServer(thistrans, fd, port);
537 prmsg (1,"Reopen: Bad Open type %d\n", type);
542 prmsg (1,"Reopen: transport open failed\n");
547 ciptr->transptr = thistrans;
548 ciptr->port = save_port;
553 #endif /* TRANS_REOPEN */
558 * These are the public interfaces to this Transport interface.
559 * These are the only functions that should have knowledge of the transport
566 TRANS(OpenCOTSClient) (char *address)
569 prmsg (2,"OpenCOTSClient(%s)\n", address);
570 return TRANS(Open) (XTRANS_OPEN_COTS_CLIENT, address);
573 #endif /* TRANS_CLIENT */
579 TRANS(OpenCOTSServer) (char *address)
582 prmsg (2,"OpenCOTSServer(%s)\n", address);
583 return TRANS(Open) (XTRANS_OPEN_COTS_SERVER, address);
586 #endif /* TRANS_SERVER */
592 TRANS(OpenCLTSClient) (char *address)
595 prmsg (2,"OpenCLTSClient(%s)\n", address);
596 return TRANS(Open) (XTRANS_OPEN_CLTS_CLIENT, address);
599 #endif /* TRANS_CLIENT */
605 TRANS(OpenCLTSServer) (char *address)
608 prmsg (2,"OpenCLTSServer(%s)\n", address);
609 return TRANS(Open) (XTRANS_OPEN_CLTS_SERVER, address);
612 #endif /* TRANS_SERVER */
618 TRANS(ReopenCOTSServer) (int trans_id, int fd, char *port)
621 prmsg (2,"ReopenCOTSServer(%d, %d, %s)\n", trans_id, fd, port);
622 return TRANS(Reopen) (XTRANS_OPEN_COTS_SERVER, trans_id, fd, port);
626 TRANS(ReopenCLTSServer) (int trans_id, int fd, char *port)
629 prmsg (2,"ReopenCLTSServer(%d, %d, %s)\n", trans_id, fd, port);
630 return TRANS(Reopen) (XTRANS_OPEN_CLTS_SERVER, trans_id, fd, port);
635 TRANS(GetReopenInfo) (XtransConnInfo ciptr,
636 int *trans_id, int *fd, char **port)
641 for (i = 0; i < NUMTRANS; i++)
642 if (Xtransports[i].transport == ciptr->transptr)
644 *trans_id = Xtransports[i].transport_id;
647 if ((*port = strdup (ciptr->port)) == NULL)
656 #endif /* TRANS_REOPEN */
660 TRANS(SetOption) (XtransConnInfo ciptr, int option, int arg)
666 prmsg (2,"SetOption(%d,%d,%d)\n", fd, option, arg);
669 * For now, all transport type use the same stuff for setting options.
670 * As long as this is true, we can put the common code here. Once a more
671 * complicated transport such as shared memory or an OSI implementation
672 * that uses the session and application libraries is implemented, this
673 * code may have to move to a transport dependent function.
675 * ret = ciptr->transptr->SetOption (ciptr, option, arg);
680 case TRANS_NONBLOCKING:
684 /* Set to blocking mode */
686 case 1: /* Set to non-blocking mode */
688 #if defined(O_NONBLOCK) && !defined(SCO325)
689 ret = fcntl (fd, F_GETFL, 0);
691 ret = fcntl (fd, F_SETFL, ret | O_NONBLOCK);
697 ret = ioctl (fd, FIOSNBIO, &arg);
708 /* IBM TCP/IP understands this option too well: it causes TRANS(Read) to fail
709 * eventually with EWOULDBLOCK */
710 ret = ioctl (fd, FIONBIO, &arg);
713 ret = fcntl (fd, F_GETFL, 0);
715 ret = fcntl (fd, F_SETFL, ret | FNDELAY);
717 ret = fcntl (fd, F_SETFL, ret | O_NDELAY);
719 #endif /* AIXV3 || uniosu */
720 #endif /* FIOSNBIO */
721 #endif /* O_NONBLOCK */
728 case TRANS_CLOSEONEXEC:
731 ret = fcntl (fd, F_SETFD, FD_CLOEXEC);
733 ret = fcntl (fd, F_SETFD, 1);
734 #endif /* FD_CLOEXEC */
745 TRANS(CreateListener) (XtransConnInfo ciptr, char *port, unsigned int flags)
748 return ciptr->transptr->CreateListener (ciptr, port, flags);
752 TRANS(NoListen) (const char * protocol)
758 if ((trans = TRANS(SelectTransport)(protocol)) == NULL)
760 prmsg (1,"TransNoListen: unable to find transport: %s\n",
765 if (trans->flags & TRANS_ALIAS) {
767 while (trans->nolisten[i]) {
768 ret |= TRANS(NoListen)(trans->nolisten[i]);
773 trans->flags |= TRANS_NOLISTEN;
778 TRANS(ResetListener) (XtransConnInfo ciptr)
781 if (ciptr->transptr->ResetListener)
782 return ciptr->transptr->ResetListener (ciptr);
784 return TRANS_RESET_NOOP;
789 TRANS(Accept) (XtransConnInfo ciptr, int *status)
792 XtransConnInfo newciptr;
794 prmsg (2,"Accept(%d)\n", ciptr->fd);
796 newciptr = ciptr->transptr->Accept (ciptr, status);
799 newciptr->transptr = ciptr->transptr;
804 #endif /* TRANS_SERVER */
810 TRANS(Connect) (XtransConnInfo ciptr, char *address)
818 prmsg (2,"Connect(%d,%s)\n", ciptr->fd, address);
820 if (TRANS(ParseAddress) (address, &protocol, &host, &port) == 0)
822 prmsg (1,"Connect: Unable to Parse address %s\n",
828 if (!host) host=strdup("");
833 prmsg (1,"Connect: Missing port specification in %s\n",
835 if (protocol) free (protocol);
836 if (host) free (host);
840 ret = ciptr->transptr->Connect (ciptr, host, port);
842 if (protocol) free (protocol);
843 if (host) free (host);
844 if (port) free (port);
849 #endif /* TRANS_CLIENT */
853 TRANS(BytesReadable) (XtransConnInfo ciptr, BytesReadable_t *pend)
856 return ciptr->transptr->BytesReadable (ciptr, pend);
860 TRANS(Read) (XtransConnInfo ciptr, char *buf, int size)
863 return ciptr->transptr->Read (ciptr, buf, size);
867 TRANS(Write) (XtransConnInfo ciptr, char *buf, int size)
870 return ciptr->transptr->Write (ciptr, buf, size);
874 TRANS(Readv) (XtransConnInfo ciptr, struct iovec *buf, int size)
877 return ciptr->transptr->Readv (ciptr, buf, size);
881 TRANS(Writev) (XtransConnInfo ciptr, struct iovec *buf, int size)
884 return ciptr->transptr->Writev (ciptr, buf, size);
888 TRANS(Disconnect) (XtransConnInfo ciptr)
891 return ciptr->transptr->Disconnect (ciptr);
895 TRANS(Close) (XtransConnInfo ciptr)
900 prmsg (2,"Close(%d)\n", ciptr->fd);
902 ret = ciptr->transptr->Close (ciptr);
904 TRANS(FreeConnInfo) (ciptr);
910 TRANS(CloseForCloning) (XtransConnInfo ciptr)
915 prmsg (2,"CloseForCloning(%d)\n", ciptr->fd);
917 ret = ciptr->transptr->CloseForCloning (ciptr);
919 TRANS(FreeConnInfo) (ciptr);
925 TRANS(IsLocal) (XtransConnInfo ciptr)
928 return (ciptr->family == AF_UNIX);
933 TRANS(GetMyAddr) (XtransConnInfo ciptr, int *familyp, int *addrlenp,
937 prmsg (2,"GetMyAddr(%d)\n", ciptr->fd);
939 *familyp = ciptr->family;
940 *addrlenp = ciptr->addrlen;
942 if ((*addrp = malloc (ciptr->addrlen)) == NULL)
944 prmsg (1,"GetMyAddr: malloc failed\n");
947 memcpy(*addrp, ciptr->addr, ciptr->addrlen);
953 TRANS(GetPeerAddr) (XtransConnInfo ciptr, int *familyp, int *addrlenp,
957 prmsg (2,"GetPeerAddr(%d)\n", ciptr->fd);
959 *familyp = ciptr->family;
960 *addrlenp = ciptr->peeraddrlen;
962 if ((*addrp = malloc (ciptr->peeraddrlen)) == NULL)
964 prmsg (1,"GetPeerAddr: malloc failed\n");
967 memcpy(*addrp, ciptr->peeraddr, ciptr->peeraddrlen);
974 TRANS(GetConnectionNumber) (XtransConnInfo ciptr)
982 * These functions are really utility functions, but they require knowledge
983 * of the internal data structures, so they have to be part of the Transport
990 complete_network_count (void)
998 * For a complete network, we only need one LOCALCONN transport to work
1001 for (i = 0; i < NUMTRANS; i++)
1003 if (Xtransports[i].transport->flags & TRANS_ALIAS
1004 || Xtransports[i].transport->flags & TRANS_NOLISTEN)
1007 if (Xtransports[i].transport->flags & TRANS_LOCAL)
1013 return (count + found_local);
1017 #ifdef XQUARTZ_EXPORTS_LAUNCHD_FD
1018 extern int xquartz_launchd_fd;
1022 TRANS(MakeAllCOTSServerListeners) (char *port, int *partial, int *count_ret,
1023 XtransConnInfo **ciptrs_ret)
1026 char buffer[256]; /* ??? What size ?? */
1027 XtransConnInfo ciptr, temp_ciptrs[NUMTRANS];
1030 #if defined(IPv6) && defined(AF_INET6)
1033 prmsg (2,"MakeAllCOTSServerListeners(%s,%p)\n",
1034 port ? port : "NULL", ciptrs_ret);
1038 #ifdef XQUARTZ_EXPORTS_LAUNCHD_FD
1039 fprintf(stderr, "Launchd socket fd: %d\n", xquartz_launchd_fd);
1040 if(xquartz_launchd_fd != -1) {
1041 if((ciptr = TRANS(ReopenCOTSServer(TRANS_SOCKET_LOCAL_INDEX,
1042 xquartz_launchd_fd, getenv("DISPLAY"))))==NULL)
1043 fprintf(stderr,"Got NULL while trying to Reopen launchd port\n");
1045 temp_ciptrs[(*count_ret)++] = ciptr;
1049 for (i = 0; i < NUMTRANS; i++)
1051 Xtransport *trans = Xtransports[i].transport;
1052 unsigned int flags = 0;
1054 if (trans->flags&TRANS_ALIAS || trans->flags&TRANS_NOLISTEN)
1057 snprintf(buffer, sizeof(buffer), "%s/:%s",
1058 trans->TransName, port ? port : "");
1060 prmsg (5,"MakeAllCOTSServerListeners: opening %s\n",
1063 if ((ciptr = TRANS(OpenCOTSServer(buffer))) == NULL)
1065 if (trans->flags & TRANS_DISABLED)
1069 "MakeAllCOTSServerListeners: failed to open listener for %s\n",
1073 #if defined(IPv6) && defined(AF_INET6)
1074 if ((Xtransports[i].transport_id == TRANS_SOCKET_INET_INDEX
1076 flags |= ADDR_IN_USE_ALLOWED;
1079 if ((status = TRANS(CreateListener (ciptr, port, flags))) < 0)
1081 if (status == TRANS_ADDR_IN_USE)
1084 * We failed to bind to the specified address because the
1085 * address is in use. It must be that a server is already
1086 * running at this address, and this function should fail.
1090 "MakeAllCOTSServerListeners: server already running\n");
1092 for (j = 0; j < *count_ret; j++)
1093 TRANS(Close) (temp_ciptrs[j]);
1103 "MakeAllCOTSServerListeners: failed to create listener for %s\n",
1110 #if defined(IPv6) && defined(AF_INET6)
1111 if (Xtransports[i].transport_id == TRANS_SOCKET_INET6_INDEX)
1116 "MakeAllCOTSServerListeners: opened listener for %s, %d\n",
1117 trans->TransName, ciptr->fd);
1119 temp_ciptrs[*count_ret] = ciptr;
1123 *partial = (*count_ret < complete_network_count());
1126 "MakeAllCOTSServerListeners: partial=%d, actual=%d, complete=%d \n",
1127 *partial, *count_ret, complete_network_count());
1131 if ((*ciptrs_ret = malloc (
1132 *count_ret * sizeof (XtransConnInfo))) == NULL)
1137 for (i = 0; i < *count_ret; i++)
1139 (*ciptrs_ret)[i] = temp_ciptrs[i];
1149 TRANS(MakeAllCLTSServerListeners) (char *port, int *partial, int *count_ret,
1150 XtransConnInfo **ciptrs_ret)
1153 char buffer[256]; /* ??? What size ?? */
1154 XtransConnInfo ciptr, temp_ciptrs[NUMTRANS];
1157 prmsg (2,"MakeAllCLTSServerListeners(%s,%p)\n",
1158 port ? port : "NULL", ciptrs_ret);
1162 for (i = 0; i < NUMTRANS; i++)
1164 Xtransport *trans = Xtransports[i].transport;
1166 if (trans->flags&TRANS_ALIAS || trans->flags&TRANS_NOLISTEN)
1169 snprintf(buffer, sizeof(buffer), "%s/:%s",
1170 trans->TransName, port ? port : "");
1172 prmsg (5,"MakeAllCLTSServerListeners: opening %s\n",
1175 if ((ciptr = TRANS(OpenCLTSServer (buffer))) == NULL)
1178 "MakeAllCLTSServerListeners: failed to open listener for %s\n",
1183 if ((status = TRANS(CreateListener (ciptr, port, 0))) < 0)
1185 if (status == TRANS_ADDR_IN_USE)
1188 * We failed to bind to the specified address because the
1189 * address is in use. It must be that a server is already
1190 * running at this address, and this function should fail.
1194 "MakeAllCLTSServerListeners: server already running\n");
1196 for (j = 0; j < *count_ret; j++)
1197 TRANS(Close) (temp_ciptrs[j]);
1207 "MakeAllCLTSServerListeners: failed to create listener for %s\n",
1215 "MakeAllCLTSServerListeners: opened listener for %s, %d\n",
1216 trans->TransName, ciptr->fd);
1217 temp_ciptrs[*count_ret] = ciptr;
1221 *partial = (*count_ret < complete_network_count());
1224 "MakeAllCLTSServerListeners: partial=%d, actual=%d, complete=%d \n",
1225 *partial, *count_ret, complete_network_count());
1229 if ((*ciptrs_ret = malloc (
1230 *count_ret * sizeof (XtransConnInfo))) == NULL)
1235 for (i = 0; i < *count_ret; i++)
1237 (*ciptrs_ret)[i] = temp_ciptrs[i];
1246 #endif /* TRANS_SERVER */
1251 * These routines are not part of the X Transport Interface, but they
1252 * may be used by it.
1256 #if defined(SYSV) && defined(__i386__) && !defined(__SCO__) && !defined(sun) || defined(WIN32)
1262 static int TRANS(ReadV) (XtransConnInfo ciptr, struct iovec *iov, int iovcnt)
1269 for (i = 0, total = 0; i < iovcnt; i++, iov++) {
1271 base = iov->iov_base;
1273 register int nbytes;
1274 nbytes = TRANS(Read) (ciptr, base, len);
1275 if (nbytes < 0 && total == 0) return -1;
1276 if (nbytes <= 0) return total;
1286 #endif /* SYSV && __i386__ || WIN32 || __sxg__ */
1288 #if defined(SYSV) && defined(__i386__) && !defined(__SCO__) && !defined(sun) || defined(WIN32)
1294 static int TRANS(WriteV) (XtransConnInfo ciptr, struct iovec *iov, int iovcnt)
1301 for (i = 0, total = 0; i < iovcnt; i++, iov++) {
1303 base = iov->iov_base;
1305 register int nbytes;
1306 nbytes = TRANS(Write) (ciptr, base, len);
1307 if (nbytes < 0 && total == 0) return -1;
1308 if (nbytes <= 0) return total;
1318 #endif /* SYSV && __i386__ || WIN32 || __sxg__ */
1321 #if defined(_POSIX_SOURCE) || defined(USG) || defined(SVR4) || defined(__SVR4) || defined(__SCO__)
1322 #ifndef NEED_UTSNAME
1323 #define NEED_UTSNAME
1325 #include <sys/utsname.h>
1329 * TRANS(GetHostname) - similar to gethostname but allows special processing.
1332 int TRANS(GetHostname) (char *buf, int maxlen)
1338 struct utsname name;
1341 len = strlen (name.nodename);
1342 if (len >= maxlen) len = maxlen - 1;
1343 strncpy (buf, name.nodename, len);
1347 (void) gethostname (buf, maxlen);
1348 buf [maxlen - 1] = '\0';
1350 #endif /* NEED_UTSNAME */