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, 0, 0);
141 xfree (ciptr->peeraddr);
146 xfree ((char *) ciptr);
150 #define PROTOBUFSIZE 20
153 TRANS(SelectTransport) (char *protocol)
156 char protobuf[PROTOBUFSIZE];
159 PRMSG (3,"SelectTransport(%s)\n", protocol, 0, 0);
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 char *_protocol, *_host, *_port;
207 char hostnamebuf[256];
210 PRMSG (3,"ParseAddress(%s)\n", address, 0, 0);
212 /* Copy the string so it can be changed */
214 tmpptr = mybuf = (char *) xalloc (strlen (address) + 1);
215 strcpy (mybuf, 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)
285 /* Check for DECnet */
287 if ((mybuf != _host) && (*(mybuf - 1) == ':')
288 #if defined(IPv6) && defined(AF_INET6)
289 /* An IPv6 address can end in :: so three : in a row is assumed to be
290 an IPv6 host and not a DECnet node with a : in it's name, unless
291 DECnet is specifically requested */
292 && ( ((mybuf - 1) == _host) || (*(mybuf - 2) != ':') ||
293 ((_protocol != NULL) && (strcmp(_protocol, "dnet") == 0)) )
303 _host_len = strlen(_host);
306 TRANS(GetHostname) (hostnamebuf, sizeof (hostnamebuf));
309 #if defined(IPv6) && defined(AF_INET6)
310 /* hostname in IPv6 [numeric_addr]:0 form? */
311 else if ( (_host_len > 3) &&
312 ((strcmp(_protocol, "tcp") == 0) || (strcmp(_protocol, "inet6") == 0))
313 && (*_host == '[') && (*(_host + _host_len - 1) == ']') ) {
314 struct sockaddr_in6 sin6;
316 *(_host + _host_len - 1) = '\0';
318 /* Verify address is valid IPv6 numeric form */
319 if (inet_pton(AF_INET6, _host + 1, &sin6) == 1) {
320 /* It is. Use it as such. */
324 /* It's not, restore it just in case some other code can use it. */
325 *(_host + _host_len - 1) = ']';
335 #if defined(FONT_t) || defined(FS_t)
337 * Is there an optional catalogue list?
340 if ((mybuf = strchr (mybuf,'/')) != NULL)
344 * The rest, if any, is the (currently unused) catalogue list.
346 * _catalogue = mybuf;
351 /* launchd sockets will look like 'local//tmp/launch-XgkNns/:0' */
352 if(address != NULL && strlen(address)>8 && (!strncmp(address,"local//",7))) {
360 * Now that we have all of the components, allocate new
361 * string space for them.
364 if ((*protocol = (char *) xalloc(strlen (_protocol) + 1)) == NULL)
374 strcpy (*protocol, _protocol);
376 if ((*host = (char *) xalloc (strlen (_host) + 1)) == NULL)
387 strcpy (*host, _host);
389 if ((*port = (char *) xalloc (strlen (_port) + 1)) == NULL)
401 strcpy (*port, _port);
410 * TRANS(Open) does all of the real work opening a connection. The only
411 * funny part about this is the type parameter which is used to decide which
412 * type of open to perform.
415 static XtransConnInfo
416 TRANS(Open) (int type, char *address)
419 char *protocol = NULL, *host = NULL, *port = NULL;
420 XtransConnInfo ciptr = NULL;
421 Xtransport *thistrans;
423 PRMSG (2,"Open(%d,%s)\n", type, address, 0);
425 #if defined(WIN32) && defined(TCPCONN)
426 if (TRANS(WSAStartup)())
428 PRMSG (1,"Open: WSAStartup failed\n", 0, 0, 0);
433 /* Parse the Address */
435 if (TRANS(ParseAddress) (address, &protocol, &host, &port) == 0)
437 PRMSG (1,"Open: Unable to Parse address %s\n", address, 0, 0);
441 /* Determine the transport type */
443 if ((thistrans = TRANS(SelectTransport) (protocol)) == NULL)
445 PRMSG (1,"Open: Unable to find transport for %s\n",
454 /* Open the transport */
458 case XTRANS_OPEN_COTS_CLIENT:
460 ciptr = thistrans->OpenCOTSClient(thistrans, protocol, host, port);
461 #endif /* TRANS_CLIENT */
463 case XTRANS_OPEN_COTS_SERVER:
465 ciptr = thistrans->OpenCOTSServer(thistrans, protocol, host, port);
466 #endif /* TRANS_SERVER */
468 case XTRANS_OPEN_CLTS_CLIENT:
470 ciptr = thistrans->OpenCLTSClient(thistrans, protocol, host, port);
471 #endif /* TRANS_CLIENT */
473 case XTRANS_OPEN_CLTS_SERVER:
475 ciptr = thistrans->OpenCLTSServer(thistrans, protocol, host, port);
476 #endif /* TRANS_SERVER */
479 PRMSG (1,"Open: Unknown Open type %d\n", type, 0, 0);
484 if (!(thistrans->flags & TRANS_DISABLED))
486 PRMSG (1,"Open: transport open failed for %s/%s:%s\n",
487 protocol, host, port);
495 ciptr->transptr = thistrans;
496 ciptr->port = port; /* We need this for TRANS(Reopen) */
508 * We might want to create an XtransConnInfo object based on a previously
509 * opened connection. For example, the font server may clone itself and
510 * pass file descriptors to the parent.
513 static XtransConnInfo
514 TRANS(Reopen) (int type, int trans_id, int fd, char *port)
517 XtransConnInfo ciptr = NULL;
518 Xtransport *thistrans = NULL;
522 PRMSG (2,"Reopen(%d,%d,%s)\n", trans_id, fd, port);
524 /* Determine the transport type */
526 for (i = 0; i < NUMTRANS; i++)
527 if (Xtransports[i].transport_id == trans_id)
529 thistrans = Xtransports[i].transport;
533 if (thistrans == NULL)
535 PRMSG (1,"Reopen: Unable to find transport id %d\n",
541 if ((save_port = (char *) xalloc (strlen (port) + 1)) == NULL)
543 PRMSG (1,"Reopen: Unable to malloc port string\n", 0, 0, 0);
548 strcpy (save_port, port);
550 /* Get a new XtransConnInfo object */
554 case XTRANS_OPEN_COTS_SERVER:
555 ciptr = thistrans->ReopenCOTSServer(thistrans, fd, port);
557 case XTRANS_OPEN_CLTS_SERVER:
558 ciptr = thistrans->ReopenCLTSServer(thistrans, fd, port);
561 PRMSG (1,"Reopen: Bad Open type %d\n", type, 0, 0);
566 PRMSG (1,"Reopen: transport open failed\n", 0, 0, 0);
570 ciptr->transptr = thistrans;
571 ciptr->port = save_port;
576 #endif /* TRANS_REOPEN */
581 * These are the public interfaces to this Transport interface.
582 * These are the only functions that should have knowledge of the transport
589 TRANS(OpenCOTSClient) (char *address)
592 PRMSG (2,"OpenCOTSClient(%s)\n", address, 0, 0);
593 return TRANS(Open) (XTRANS_OPEN_COTS_CLIENT, address);
596 #endif /* TRANS_CLIENT */
602 TRANS(OpenCOTSServer) (char *address)
605 PRMSG (2,"OpenCOTSServer(%s)\n", address, 0, 0);
606 return TRANS(Open) (XTRANS_OPEN_COTS_SERVER, address);
609 #endif /* TRANS_SERVER */
615 TRANS(OpenCLTSClient) (char *address)
618 PRMSG (2,"OpenCLTSClient(%s)\n", address, 0, 0);
619 return TRANS(Open) (XTRANS_OPEN_CLTS_CLIENT, address);
622 #endif /* TRANS_CLIENT */
628 TRANS(OpenCLTSServer) (char *address)
631 PRMSG (2,"OpenCLTSServer(%s)\n", address, 0, 0);
632 return TRANS(Open) (XTRANS_OPEN_CLTS_SERVER, address);
635 #endif /* TRANS_SERVER */
641 TRANS(ReopenCOTSServer) (int trans_id, int fd, char *port)
644 PRMSG (2,"ReopenCOTSServer(%d, %d, %s)\n", trans_id, fd, port);
645 return TRANS(Reopen) (XTRANS_OPEN_COTS_SERVER, trans_id, fd, port);
649 TRANS(ReopenCLTSServer) (int trans_id, int fd, char *port)
652 PRMSG (2,"ReopenCLTSServer(%d, %d, %s)\n", trans_id, fd, port);
653 return TRANS(Reopen) (XTRANS_OPEN_CLTS_SERVER, trans_id, fd, port);
658 TRANS(GetReopenInfo) (XtransConnInfo ciptr,
659 int *trans_id, int *fd, char **port)
664 for (i = 0; i < NUMTRANS; i++)
665 if (Xtransports[i].transport == ciptr->transptr)
667 *trans_id = Xtransports[i].transport_id;
670 if ((*port = (char *) xalloc (strlen (ciptr->port) + 1)) == NULL)
674 strcpy (*port, ciptr->port);
682 #endif /* TRANS_REOPEN */
686 TRANS(SetOption) (XtransConnInfo ciptr, int option, int arg)
692 PRMSG (2,"SetOption(%d,%d,%d)\n", fd, option, arg);
695 * For now, all transport type use the same stuff for setting options.
696 * As long as this is true, we can put the common code here. Once a more
697 * complicated transport such as shared memory or an OSI implementation
698 * that uses the session and application libraries is implemented, this
699 * code may have to move to a transport dependent function.
701 * ret = ciptr->transptr->SetOption (ciptr, option, arg);
706 case TRANS_NONBLOCKING:
710 /* Set to blocking mode */
712 case 1: /* Set to non-blocking mode */
714 #if defined(O_NONBLOCK) && !defined(SCO325)
715 ret = fcntl (fd, F_GETFL, 0);
717 ret = fcntl (fd, F_SETFL, ret | O_NONBLOCK);
723 ret = ioctl (fd, FIOSNBIO, &arg);
734 /* IBM TCP/IP understands this option too well: it causes TRANS(Read) to fail
735 * eventually with EWOULDBLOCK */
736 ret = ioctl (fd, FIONBIO, &arg);
739 ret = fcntl (fd, F_GETFL, 0);
741 ret = fcntl (fd, F_SETFL, ret | FNDELAY);
743 ret = fcntl (fd, F_SETFL, ret | O_NDELAY);
745 #endif /* AIXV3 || uniosu */
746 #endif /* FIOSNBIO */
747 #endif /* O_NONBLOCK */
754 case TRANS_CLOSEONEXEC:
757 ret = fcntl (fd, F_SETFD, FD_CLOEXEC);
759 ret = fcntl (fd, F_SETFD, 1);
760 #endif /* FD_CLOEXEC */
771 TRANS(CreateListener) (XtransConnInfo ciptr, char *port, unsigned int flags)
774 return ciptr->transptr->CreateListener (ciptr, port, flags);
778 TRANS(NoListen) (char * protocol)
784 if ((trans = TRANS(SelectTransport)(protocol)) == NULL)
786 PRMSG (1,"TransNoListen: unable to find transport: %s\n",
791 if (trans->flags & TRANS_ALIAS) {
793 while (trans->nolisten[i]) {
794 ret |= TRANS(NoListen)(trans->nolisten[i]);
799 trans->flags |= TRANS_NOLISTEN;
804 TRANS(ResetListener) (XtransConnInfo ciptr)
807 if (ciptr->transptr->ResetListener)
808 return ciptr->transptr->ResetListener (ciptr);
810 return TRANS_RESET_NOOP;
815 TRANS(Accept) (XtransConnInfo ciptr, int *status)
818 XtransConnInfo newciptr;
820 PRMSG (2,"Accept(%d)\n", ciptr->fd, 0, 0);
822 newciptr = ciptr->transptr->Accept (ciptr, status);
825 newciptr->transptr = ciptr->transptr;
830 #endif /* TRANS_SERVER */
836 TRANS(Connect) (XtransConnInfo ciptr, char *address)
844 PRMSG (2,"Connect(%d,%s)\n", ciptr->fd, address, 0);
846 if (TRANS(ParseAddress) (address, &protocol, &host, &port) == 0)
848 PRMSG (1,"Connect: Unable to Parse address %s\n",
854 if (!host) host=strdup("");
859 PRMSG (1,"Connect: Missing port specification in %s\n",
861 if (protocol) xfree (protocol);
862 if (host) xfree (host);
866 ret = ciptr->transptr->Connect (ciptr, host, port);
868 if (protocol) xfree (protocol);
869 if (host) xfree (host);
870 if (port) xfree (port);
875 #endif /* TRANS_CLIENT */
879 TRANS(BytesReadable) (XtransConnInfo ciptr, BytesReadable_t *pend)
882 return ciptr->transptr->BytesReadable (ciptr, pend);
886 TRANS(Read) (XtransConnInfo ciptr, char *buf, int size)
889 return ciptr->transptr->Read (ciptr, buf, size);
893 TRANS(Write) (XtransConnInfo ciptr, char *buf, int size)
896 return ciptr->transptr->Write (ciptr, buf, size);
900 TRANS(Readv) (XtransConnInfo ciptr, struct iovec *buf, int size)
903 return ciptr->transptr->Readv (ciptr, buf, size);
907 TRANS(Writev) (XtransConnInfo ciptr, struct iovec *buf, int size)
910 return ciptr->transptr->Writev (ciptr, buf, size);
914 TRANS(Disconnect) (XtransConnInfo ciptr)
917 return ciptr->transptr->Disconnect (ciptr);
921 TRANS(Close) (XtransConnInfo ciptr)
926 PRMSG (2,"Close(%d)\n", ciptr->fd, 0, 0);
928 ret = ciptr->transptr->Close (ciptr);
930 TRANS(FreeConnInfo) (ciptr);
936 TRANS(CloseForCloning) (XtransConnInfo ciptr)
941 PRMSG (2,"CloseForCloning(%d)\n", ciptr->fd, 0, 0);
943 ret = ciptr->transptr->CloseForCloning (ciptr);
945 TRANS(FreeConnInfo) (ciptr);
951 TRANS(IsLocal) (XtransConnInfo ciptr)
954 return (ciptr->family == AF_UNIX);
959 TRANS(GetMyAddr) (XtransConnInfo ciptr, int *familyp, int *addrlenp,
963 PRMSG (2,"GetMyAddr(%d)\n", ciptr->fd, 0, 0);
965 *familyp = ciptr->family;
966 *addrlenp = ciptr->addrlen;
968 if ((*addrp = (Xtransaddr *) xalloc (ciptr->addrlen)) == NULL)
970 PRMSG (1,"GetMyAddr: malloc failed\n", 0, 0, 0);
973 memcpy(*addrp, ciptr->addr, ciptr->addrlen);
979 TRANS(GetPeerAddr) (XtransConnInfo ciptr, int *familyp, int *addrlenp,
983 PRMSG (2,"GetPeerAddr(%d)\n", ciptr->fd, 0, 0);
985 *familyp = ciptr->family;
986 *addrlenp = ciptr->peeraddrlen;
988 if ((*addrp = (Xtransaddr *) xalloc (ciptr->peeraddrlen)) == NULL)
990 PRMSG (1,"GetPeerAddr: malloc failed\n", 0, 0, 0);
993 memcpy(*addrp, ciptr->peeraddr, ciptr->peeraddrlen);
1000 TRANS(GetConnectionNumber) (XtransConnInfo ciptr)
1008 * These functions are really utility functions, but they require knowledge
1009 * of the internal data structures, so they have to be part of the Transport
1016 complete_network_count (void)
1020 int found_local = 0;
1024 * For a complete network, we only need one LOCALCONN transport to work
1027 for (i = 0; i < NUMTRANS; i++)
1029 if (Xtransports[i].transport->flags & TRANS_ALIAS
1030 || Xtransports[i].transport->flags & TRANS_NOLISTEN)
1033 if (Xtransports[i].transport->flags & TRANS_LOCAL)
1039 return (count + found_local);
1043 #ifdef XQUARTZ_EXPORTS_LAUNCHD_FD
1044 extern int xquartz_launchd_fd;
1048 TRANS(MakeAllCOTSServerListeners) (char *port, int *partial, int *count_ret,
1049 XtransConnInfo **ciptrs_ret)
1052 char buffer[256]; /* ??? What size ?? */
1053 XtransConnInfo ciptr, temp_ciptrs[NUMTRANS];
1056 #if defined(IPv6) && defined(AF_INET6)
1059 PRMSG (2,"MakeAllCOTSServerListeners(%s,%p)\n",
1060 port ? port : "NULL", ciptrs_ret, 0);
1064 #ifdef XQUARTZ_EXPORTS_LAUNCHD_FD
1065 fprintf(stderr, "Launchd socket fd: %d\n", xquartz_launchd_fd);
1066 if(xquartz_launchd_fd != -1) {
1067 if((ciptr = TRANS(ReopenCOTSServer(TRANS_SOCKET_LOCAL_INDEX,
1068 xquartz_launchd_fd, getenv("DISPLAY"))))==NULL)
1069 fprintf(stderr,"Got NULL while trying to Reopen launchd port\n");
1071 temp_ciptrs[(*count_ret)++] = ciptr;
1075 for (i = 0; i < NUMTRANS; i++)
1077 Xtransport *trans = Xtransports[i].transport;
1078 unsigned int flags = 0;
1080 if (trans->flags&TRANS_ALIAS || trans->flags&TRANS_NOLISTEN)
1083 snprintf(buffer, sizeof(buffer), "%s/:%s",
1084 trans->TransName, port ? port : "");
1086 PRMSG (5,"MakeAllCOTSServerListeners: opening %s\n",
1089 if ((ciptr = TRANS(OpenCOTSServer(buffer))) == NULL)
1091 if (trans->flags & TRANS_DISABLED)
1095 "MakeAllCOTSServerListeners: failed to open listener for %s\n",
1096 trans->TransName, 0, 0);
1099 #if defined(IPv6) && defined(AF_INET6)
1100 if ((Xtransports[i].transport_id == TRANS_SOCKET_INET_INDEX
1102 flags |= ADDR_IN_USE_ALLOWED;
1105 if ((status = TRANS(CreateListener (ciptr, port, flags))) < 0)
1107 if (status == TRANS_ADDR_IN_USE)
1110 * We failed to bind to the specified address because the
1111 * address is in use. It must be that a server is already
1112 * running at this address, and this function should fail.
1116 "MakeAllCOTSServerListeners: server already running\n",
1119 for (j = 0; j < *count_ret; j++)
1120 TRANS(Close) (temp_ciptrs[j]);
1130 "MakeAllCOTSServerListeners: failed to create listener for %s\n",
1131 trans->TransName, 0, 0);
1137 #if defined(IPv6) && defined(AF_INET6)
1138 if (Xtransports[i].transport_id == TRANS_SOCKET_INET6_INDEX)
1143 "MakeAllCOTSServerListeners: opened listener for %s, %d\n",
1144 trans->TransName, ciptr->fd, 0);
1146 temp_ciptrs[*count_ret] = ciptr;
1150 *partial = (*count_ret < complete_network_count());
1153 "MakeAllCOTSServerListeners: partial=%d, actual=%d, complete=%d \n",
1154 *partial, *count_ret, complete_network_count());
1158 if ((*ciptrs_ret = (XtransConnInfo *) xalloc (
1159 *count_ret * sizeof (XtransConnInfo))) == NULL)
1164 for (i = 0; i < *count_ret; i++)
1166 (*ciptrs_ret)[i] = temp_ciptrs[i];
1176 TRANS(MakeAllCLTSServerListeners) (char *port, int *partial, int *count_ret,
1177 XtransConnInfo **ciptrs_ret)
1180 char buffer[256]; /* ??? What size ?? */
1181 XtransConnInfo ciptr, temp_ciptrs[NUMTRANS];
1184 PRMSG (2,"MakeAllCLTSServerListeners(%s,%p)\n",
1185 port ? port : "NULL", ciptrs_ret, 0);
1189 for (i = 0; i < NUMTRANS; i++)
1191 Xtransport *trans = Xtransports[i].transport;
1193 if (trans->flags&TRANS_ALIAS || trans->flags&TRANS_NOLISTEN)
1196 snprintf(buffer, sizeof(buffer), "%s/:%s",
1197 trans->TransName, port ? port : "");
1199 PRMSG (5,"MakeAllCLTSServerListeners: opening %s\n",
1202 if ((ciptr = TRANS(OpenCLTSServer (buffer))) == NULL)
1205 "MakeAllCLTSServerListeners: failed to open listener for %s\n",
1206 trans->TransName, 0, 0);
1210 if ((status = TRANS(CreateListener (ciptr, port, 0))) < 0)
1212 if (status == TRANS_ADDR_IN_USE)
1215 * We failed to bind to the specified address because the
1216 * address is in use. It must be that a server is already
1217 * running at this address, and this function should fail.
1221 "MakeAllCLTSServerListeners: server already running\n",
1224 for (j = 0; j < *count_ret; j++)
1225 TRANS(Close) (temp_ciptrs[j]);
1235 "MakeAllCLTSServerListeners: failed to create listener for %s\n",
1236 trans->TransName, 0, 0);
1243 "MakeAllCLTSServerListeners: opened listener for %s, %d\n",
1244 trans->TransName, ciptr->fd, 0);
1245 temp_ciptrs[*count_ret] = ciptr;
1249 *partial = (*count_ret < complete_network_count());
1252 "MakeAllCLTSServerListeners: partial=%d, actual=%d, complete=%d \n",
1253 *partial, *count_ret, complete_network_count());
1257 if ((*ciptrs_ret = (XtransConnInfo *) xalloc (
1258 *count_ret * sizeof (XtransConnInfo))) == NULL)
1263 for (i = 0; i < *count_ret; i++)
1265 (*ciptrs_ret)[i] = temp_ciptrs[i];
1274 #endif /* TRANS_SERVER */
1279 * These routines are not part of the X Transport Interface, but they
1280 * may be used by it.
1284 #if defined(SYSV) && defined(__i386__) && !defined(__SCO__) && !defined(sun) || defined(WIN32)
1290 static int TRANS(ReadV) (XtransConnInfo ciptr, struct iovec *iov, int iovcnt)
1297 for (i = 0, total = 0; i < iovcnt; i++, iov++) {
1299 base = iov->iov_base;
1301 register int nbytes;
1302 nbytes = TRANS(Read) (ciptr, base, len);
1303 if (nbytes < 0 && total == 0) return -1;
1304 if (nbytes <= 0) return total;
1314 #endif /* SYSV && __i386__ || WIN32 || __sxg__ */
1316 #if defined(SYSV) && defined(__i386__) && !defined(__SCO__) && !defined(sun) || defined(WIN32)
1322 static int TRANS(WriteV) (XtransConnInfo ciptr, struct iovec *iov, int iovcnt)
1329 for (i = 0, total = 0; i < iovcnt; i++, iov++) {
1331 base = iov->iov_base;
1333 register int nbytes;
1334 nbytes = TRANS(Write) (ciptr, base, len);
1335 if (nbytes < 0 && total == 0) return -1;
1336 if (nbytes <= 0) return total;
1346 #endif /* SYSV && __i386__ || WIN32 || __sxg__ */
1349 #if defined(_POSIX_SOURCE) || defined(USG) || defined(SVR4) || defined(__SVR4) || defined(__SCO__)
1350 #ifndef NEED_UTSNAME
1351 #define NEED_UTSNAME
1353 #include <sys/utsname.h>
1357 * TRANS(GetHostname) - similar to gethostname but allows special processing.
1360 int TRANS(GetHostname) (char *buf, int maxlen)
1366 struct utsname name;
1369 len = strlen (name.nodename);
1370 if (len >= maxlen) len = maxlen - 1;
1371 strncpy (buf, name.nodename, len);
1375 (void) gethostname (buf, maxlen);
1376 buf [maxlen - 1] = '\0';
1378 #endif /* NEED_UTSNAME */