1 /* $XConsortium: Xtrans.c,v 1.31 95/03/28 19:49:02 mor Exp $ */
2 /* $XFree86: xc/lib/xtrans/Xtrans.c,v 3.15.2.2 1997/07/19 04:59:16 dawes Exp $ */
5 Copyright (c) 1993, 1994 X Consortium
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
15 The above copyright notice and this permission notice shall be included
16 in all copies or substantial portions of the Software.
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 OTHER DEALINGS IN THE SOFTWARE.
26 Except as contained in this notice, the name of the X Consortium shall
27 not be used in advertising or otherwise to promote the sale, use or
28 other dealings in this Software without prior written authorization
29 from the X Consortium.
33 /* Copyright (c) 1993, 1994 NCR Corporation - Dayton, Ohio, USA
37 * Permission to use, copy, modify, and distribute this software and its
38 * documentation for any purpose and without fee is hereby granted, provided
39 * that the above copyright notice appear in all copies and that both that
40 * copyright notice and this permission notice appear in supporting
41 * documentation, and that the name NCR not be used in advertising
42 * or publicity pertaining to distribution of the software without specific,
43 * written prior permission. NCR makes no representations about the
44 * suitability of this software for any purpose. It is provided "as is"
45 * without express or implied warranty.
47 * NCR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
48 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
49 * NO EVENT SHALL NCR BE LIABLE FOR ANY SPECIAL, INDIRECT OR
50 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
51 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
52 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
53 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
59 * The transport table contains a definition for every transport (protocol)
60 * family. All operations that can be made on the transport go through this
63 * Each transport is assigned a unique transport id.
65 * New transports can be added by adding an entry in this table.
66 * For compatiblity, the transport ids should never be renumbered.
67 * Always add to the end of the list.
70 #define TRANS_TLI_INET_INDEX 1
71 #define TRANS_TLI_TCP_INDEX 2
72 #define TRANS_TLI_TLI_INDEX 3
73 #define TRANS_SOCKET_UNIX_INDEX 4
74 #define TRANS_SOCKET_LOCAL_INDEX 5
75 #define TRANS_SOCKET_INET_INDEX 6
76 #define TRANS_SOCKET_TCP_INDEX 7
77 #define TRANS_DNET_INDEX 8
78 #define TRANS_LOCAL_LOCAL_INDEX 9
79 #define TRANS_LOCAL_PTS_INDEX 10
80 #define TRANS_LOCAL_NAMED_INDEX 11
81 #define TRANS_LOCAL_ISC_INDEX 12
82 #define TRANS_LOCAL_SCO_INDEX 13
83 #define TRANS_AMOEBA_INDEX 14
84 #define TRANS_MNX_INET_INDEX 15
85 #define TRANS_MNX_TCP_INDEX 16
89 Xtransport_table Xtransports[] = {
90 #if defined(STREAMSCONN)
91 &TRANS(TLITCPFuncs), TRANS_TLI_TCP_INDEX,
92 &TRANS(TLIINETFuncs), TRANS_TLI_INET_INDEX,
93 &TRANS(TLITLIFuncs), TRANS_TLI_TLI_INDEX,
94 #endif /* STREAMSCONN */
96 &TRANS(SocketTCPFuncs), TRANS_SOCKET_TCP_INDEX,
97 &TRANS(SocketINETFuncs), TRANS_SOCKET_INET_INDEX,
100 &TRANS(DNETFuncs), TRANS_DNET_INDEX,
101 #endif /* DNETCONN */
102 #if defined(UNIXCONN)
103 #if !defined(LOCALCONN)
104 &TRANS(SocketLocalFuncs), TRANS_SOCKET_LOCAL_INDEX,
105 #endif /* !LOCALCONN */
106 &TRANS(SocketUNIXFuncs), TRANS_SOCKET_UNIX_INDEX,
107 #endif /* UNIXCONN */
108 #if defined(OS2PIPECONN)
109 &TRANS(OS2LocalFuncs), TRANS_LOCAL_LOCAL_INDEX,
110 #endif /* OS2PIPECONN */
111 #if defined(LOCALCONN)
112 &TRANS(LocalFuncs), TRANS_LOCAL_LOCAL_INDEX,
113 &TRANS(PTSFuncs), TRANS_LOCAL_PTS_INDEX,
115 &TRANS(NAMEDFuncs), TRANS_LOCAL_NAMED_INDEX,
117 &TRANS(ISCFuncs), TRANS_LOCAL_ISC_INDEX,
118 &TRANS(SCOFuncs), TRANS_LOCAL_SCO_INDEX,
119 #endif /* LOCALCONN */
120 #if defined(AMRPCCONN) || defined(AMTCPCONN)
121 &TRANS(AmConnFuncs), TRANS_AMOEBA_INDEX,
122 #endif /* AMRPCCONN || AMTCPCONN */
123 #if defined(MNX_TCPCONN)
124 &TRANS(MnxINETFuncs), TRANS_MNX_INET_INDEX,
125 &TRANS(MnxTCPFuncs), TRANS_MNX_TCP_INDEX,
126 #endif /* MNX_TCPCONN */
129 #define NUMTRANS (sizeof(Xtransports)/sizeof(Xtransport_table))
133 #define ioctl ioctlsocket
139 * These are a few utility function used by the public interface functions.
143 TRANS(FreeConnInfo) (ciptr)
145 XtransConnInfo ciptr;
148 PRMSG (3,"FreeConnInfo(%x)\n", ciptr, 0, 0);
154 xfree (ciptr->peeraddr);
159 xfree ((char *) ciptr);
163 #define PROTOBUFSIZE 20
166 TRANS(SelectTransport) (protocol)
171 char protobuf[PROTOBUFSIZE];
174 PRMSG (3,"SelectTransport(%s)\n", protocol, 0, 0);
177 * Force Protocol to be lowercase as a way of doing
178 * a case insensitive match.
181 strncpy (protobuf, protocol, PROTOBUFSIZE);
183 for (i = 0; i < PROTOBUFSIZE && protobuf[i] != '\0'; i++)
184 if (isupper (protobuf[i]))
185 protobuf[i] = tolower (protobuf[i]);
187 /* Look at all of the configured protocols */
189 for (i = 0; i < NUMTRANS; i++)
191 if (!strcmp (protobuf, Xtransports[i].transport->TransName))
192 return Xtransports[i].transport;
202 TRANS(ParseAddress) (address, protocol, host, port)
211 * For the font library, the address is a string formatted
212 * as "protocol/host:port[/catalogue]". Note that the catologue
213 * is optional. At this time, the catologue info is ignored, but
214 * we have to parse it anyways.
216 * Other than fontlib, the address is a string formatted
217 * as "protocol/host:port".
219 * If the protocol part is missing, then assume INET.
220 * If the protocol part and host part are missing, then assume local.
221 * If a "::" is found then assume DNET.
224 char *mybuf, *tmpptr;
225 char *_protocol, *_host, *_port;
226 char hostnamebuf[256];
228 PRMSG (3,"ParseAddress(%s)\n", address, 0, 0);
230 /* Copy the string so it can be changed */
232 tmpptr = mybuf = (char *) xalloc (strlen (address) + 1);
233 strcpy (mybuf, address);
235 /* Parse the string to get each component */
237 /* Get the protocol part */
241 if ((mybuf = strpbrk (mybuf,"/:")) == NULL)
243 /* adress is in a bad format */
254 * If there is a hostname, then assume inet, otherwise
259 /* There is neither a protocol or host specified */
264 /* Ther is a hostname specified */
266 mybuf = tmpptr; /* reset to the begining of the host ptr */
273 *mybuf ++= '\0'; /* put a null at the end of the protocol */
275 if (strlen(_protocol) == 0)
278 * If there is a hostname, then assume inet, otherwise
288 /* Get the host part */
292 if ((mybuf = strchr (mybuf,':')) == NULL)
303 if (strlen(_host) == 0)
305 TRANS(GetHostname) (hostnamebuf, sizeof (hostnamebuf));
309 /* Check for DECnet */
323 #if defined(FONT_t) || defined(FS_t)
325 * Is there an optional catalogue list?
328 if ((mybuf = strchr (mybuf,'/')) != NULL)
332 * The rest, if any, is the (currently unused) catalogue list.
334 * _catalogue = mybuf;
339 * Now that we have all of the components, allocate new
340 * string space for them.
343 if ((*protocol = (char *) xalloc(strlen (_protocol) + 1)) == NULL)
353 strcpy (*protocol, _protocol);
355 if ((*host = (char *) xalloc (strlen (_host) + 1)) == NULL)
366 strcpy (*host, _host);
368 if ((*port = (char *) xalloc (strlen (_port) + 1)) == NULL)
380 strcpy (*port, _port);
389 * TRANS(Open) does all of the real work opening a connection. The only
390 * funny part about this is the type parameter which is used to decide which
391 * type of open to perform.
394 static XtransConnInfo
395 TRANS(Open) (type, address)
401 char *protocol = NULL, *host = NULL, *port = NULL;
402 XtransConnInfo ciptr = NULL;
403 Xtransport *thistrans;
405 PRMSG (2,"Open(%d,%s)\n", type, address, 0);
407 #if defined(WIN32) && (defined(TCPCONN) || defined(DNETCONN))
408 if (TRANS(WSAStartup)())
410 PRMSG (1,"Open: WSAStartup failed\n", 0, 0, 0);
415 /* Parse the Address */
417 if (TRANS(ParseAddress) (address, &protocol, &host, &port) == 0)
419 PRMSG (1,"Open: Unable to Parse address %s\n", address, 0, 0);
423 /* Determine the transport type */
425 if ((thistrans = TRANS(SelectTransport) (protocol)) == NULL)
427 PRMSG (1,"Open: Unable to find transport for %s\n",
436 /* Open the transport */
440 case XTRANS_OPEN_COTS_CLIENT:
442 ciptr = thistrans->OpenCOTSClient(thistrans, protocol, host, port);
443 #endif /* TRANS_CLIENT */
445 case XTRANS_OPEN_COTS_SERVER:
447 ciptr = thistrans->OpenCOTSServer(thistrans, protocol, host, port);
448 #endif /* TRANS_SERVER */
450 case XTRANS_OPEN_CLTS_CLIENT:
452 ciptr = thistrans->OpenCLTSClient(thistrans, protocol, host, port);
453 #endif /* TRANS_CLIENT */
455 case XTRANS_OPEN_CLTS_SERVER:
457 ciptr = thistrans->OpenCLTSServer(thistrans, protocol, host, port);
458 #endif /* TRANS_SERVER */
461 PRMSG (1,"Open: Unknown Open type %d\n", type, 0, 0);
466 if (!(thistrans->flags & TRANS_DISABLED))
467 PRMSG (1,"Open: transport open failed for %s/%s:%s\n",
468 protocol, host, port);
475 ciptr->transptr = thistrans;
476 ciptr->port = port; /* We need this for TRANS(Reopen) */
488 * We might want to create an XtransConnInfo object based on a previously
489 * opened connection. For example, the font server may clone itself and
490 * pass file descriptors to the parent.
493 static XtransConnInfo
494 TRANS(Reopen) (type, trans_id, fd, port)
502 XtransConnInfo ciptr = NULL;
503 Xtransport *thistrans = NULL;
507 PRMSG (2,"Reopen(%d,%d,%s)\n", trans_id, fd, port);
509 /* Determine the transport type */
511 for (i = 0; i < NUMTRANS; i++)
512 if (Xtransports[i].transport_id == trans_id)
514 thistrans = Xtransports[i].transport;
518 if (thistrans == NULL)
520 PRMSG (1,"Reopen: Unable to find transport id %d\n",
526 if ((save_port = (char *) xalloc (strlen (port) + 1)) == NULL)
528 PRMSG (1,"Reopen: Unable to malloc port string\n", 0, 0, 0);
533 strcpy (save_port, port);
535 /* Get a new XtransConnInfo object */
539 case XTRANS_OPEN_COTS_SERVER:
540 ciptr = thistrans->ReopenCOTSServer(thistrans, fd, port);
542 case XTRANS_OPEN_CLTS_SERVER:
543 ciptr = thistrans->ReopenCLTSServer(thistrans, fd, port);
546 PRMSG (1,"Reopen: Bad Open type %d\n", type, 0, 0);
551 PRMSG (1,"Reopen: transport open failed\n", 0, 0, 0);
555 ciptr->transptr = thistrans;
556 ciptr->port = save_port;
561 #endif /* TRANS_REOPEN */
566 * These are the public interfaces to this Transport interface.
567 * These are the only functions that should have knowledge of the transport
574 TRANS(OpenCOTSClient) (address)
579 PRMSG (2,"OpenCOTSClient(%s)\n", address, 0, 0);
580 return TRANS(Open) (XTRANS_OPEN_COTS_CLIENT, address);
583 #endif /* TRANS_CLIENT */
589 TRANS(OpenCOTSServer) (address)
594 PRMSG (2,"OpenCOTSServer(%s)\n", address, 0, 0);
595 return TRANS(Open) (XTRANS_OPEN_COTS_SERVER, address);
598 #endif /* TRANS_SERVER */
604 TRANS(OpenCLTSClient) (address)
608 PRMSG (2,"OpenCLTSClient(%s)\n", address, 0, 0);
609 return TRANS(Open) (XTRANS_OPEN_CLTS_CLIENT, address);
612 #endif /* TRANS_CLIENT */
618 TRANS(OpenCLTSServer) (address)
623 PRMSG (2,"OpenCLTSServer(%s)\n", address, 0, 0);
624 return TRANS(Open) (XTRANS_OPEN_CLTS_SERVER, address);
627 #endif /* TRANS_SERVER */
633 TRANS(ReopenCOTSServer) (trans_id, fd, port)
640 PRMSG (2,"ReopenCOTSServer(%d, %d, %s)\n", trans_id, fd, port);
641 return TRANS(Reopen) (XTRANS_OPEN_COTS_SERVER, trans_id, fd, port);
645 TRANS(ReopenCLTSServer) (trans_id, fd, 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) (ciptr, trans_id, fd, port)
660 XtransConnInfo ciptr;
668 for (i = 0; i < NUMTRANS; i++)
669 if (Xtransports[i].transport == ciptr->transptr)
671 *trans_id = Xtransports[i].transport_id;
674 if ((*port = (char *) xalloc (strlen (ciptr->port) + 1)) == NULL)
678 strcpy (*port, ciptr->port);
686 #endif /* TRANS_REOPEN */
690 TRANS(SetOption) (ciptr, option, arg)
692 XtransConnInfo ciptr;
700 PRMSG (2,"SetOption(%d,%d,%d)\n", fd, option, arg);
703 * For now, all transport type use the same stuff for setting options.
704 * As long as this is true, we can put the common code here. Once a more
705 * complicated transport such as shared memory or an OSI implementation
706 * that uses the session and application libraries is implemented, this
707 * code may have to move to a transport dependent function.
709 * ret = ciptr->transptr->SetOption (ciptr, option, arg);
713 return ciptr->transptr->SetOption(ciptr, option, arg);
718 case TRANS_NONBLOCKING:
722 /* Set to blocking mode */
724 case 1: /* Set to non-blocking mode */
726 #if defined(O_NONBLOCK) && (!defined(ultrix) && !defined(hpux) && !defined(AIXV3) && !defined(uniosu) && !defined(__EMX__) && !defined(SCO))
727 ret = fcntl (fd, F_SETFL, O_NONBLOCK);
733 ret = ioctl (fd, FIOSNBIO, &arg);
736 #if (defined(AIXV3) || defined(uniosu) || defined(WIN32) || defined(__EMX__)) && defined(FIONBIO)
740 /* IBM TCP/IP understands this option too well: it causes TRANS(Read) to fail
741 * eventually with EWOULDBLOCK */
743 ret = ioctl (fd, FIONBIO, &arg);
745 /* ret = ioctl(fd, FIONBIO, &arg, sizeof(int));*/
750 ret = fcntl (fd, F_SETFL, FNDELAY);
752 ret = fcntl (fd, F_SETFL, O_NDELAY);
754 #endif /* AIXV3 || uniosu */
755 #endif /* FIOSNBIO */
756 #endif /* O_NONBLOCK */
763 case TRANS_CLOSEONEXEC:
766 ret = fcntl (fd, F_SETFD, FD_CLOEXEC);
768 ret = fcntl (fd, F_SETFD, 1);
769 #endif /* FD_CLOEXEC */
781 TRANS(CreateListener) (ciptr, port)
783 XtransConnInfo ciptr;
787 return ciptr->transptr->CreateListener (ciptr, port);
791 TRANS(NoListen) (char * protocol)
796 if ((trans = TRANS(SelectTransport)(protocol)) == NULL)
798 PRMSG (1,"TRANS(TransNoListen): unable to find transport: %s\n",
804 trans->flags |= TRANS_NOLISTEN;
809 TRANS(ResetListener) (ciptr)
811 XtransConnInfo ciptr;
814 if (ciptr->transptr->ResetListener)
815 return ciptr->transptr->ResetListener (ciptr);
817 return TRANS_RESET_NOOP;
822 TRANS(Accept) (ciptr, status)
824 XtransConnInfo ciptr;
828 XtransConnInfo newciptr;
830 PRMSG (2,"Accept(%d)\n", ciptr->fd, 0, 0);
832 newciptr = ciptr->transptr->Accept (ciptr, status);
835 newciptr->transptr = ciptr->transptr;
840 #endif /* TRANS_SERVER */
846 TRANS(Connect) (ciptr, address)
848 XtransConnInfo ciptr;
857 PRMSG (2,"Connect(%d,%s)\n", ciptr->fd, address, 0);
859 if (TRANS(ParseAddress) (address, &protocol, &host, &port) == 0)
861 PRMSG (1,"Connect: Unable to Parse address %s\n",
868 PRMSG (1,"Connect: Missing port specification in %s\n",
870 if (protocol) xfree (protocol);
871 if (host) xfree (host);
875 ret = ciptr->transptr->Connect (ciptr, host, port);
877 if (protocol) xfree (protocol);
878 if (host) xfree (host);
879 if (port) xfree (port);
884 #endif /* TRANS_CLIENT */
888 TRANS(BytesReadable) (ciptr, pend)
890 XtransConnInfo ciptr;
891 BytesReadable_t *pend;
894 return ciptr->transptr->BytesReadable (ciptr, pend);
898 TRANS(Read) (ciptr, buf, size)
900 XtransConnInfo ciptr;
905 return ciptr->transptr->Read (ciptr, buf, size);
909 TRANS(Write) (ciptr, buf, size)
911 XtransConnInfo ciptr;
916 return ciptr->transptr->Write (ciptr, buf, size);
920 TRANS(Readv) (ciptr, buf, size)
922 XtransConnInfo ciptr;
926 return ciptr->transptr->Readv (ciptr, buf, size);
930 TRANS(Writev) (ciptr, buf, size)
932 XtransConnInfo ciptr;
937 return ciptr->transptr->Writev (ciptr, buf, size);
941 TRANS(Disconnect) (ciptr)
943 XtransConnInfo ciptr;
946 return ciptr->transptr->Disconnect (ciptr);
952 XtransConnInfo ciptr;
957 PRMSG (2,"Close(%d)\n", ciptr->fd, 0, 0);
959 ret = ciptr->transptr->Close (ciptr);
961 TRANS(FreeConnInfo) (ciptr);
967 TRANS(CloseForCloning) (ciptr)
969 XtransConnInfo ciptr;
974 PRMSG (2,"CloseForCloning(%d)\n", ciptr->fd, 0, 0);
976 ret = ciptr->transptr->CloseForCloning (ciptr);
978 TRANS(FreeConnInfo) (ciptr);
984 TRANS(IsLocal) (ciptr)
986 XtransConnInfo ciptr;
989 return (ciptr->family == AF_UNIX);
994 TRANS(GetMyAddr) (ciptr, familyp, addrlenp, addrp)
996 XtransConnInfo ciptr;
1002 PRMSG (2,"GetMyAddr(%d)\n", ciptr->fd, 0, 0);
1004 *familyp = ciptr->family;
1005 *addrlenp = ciptr->addrlen;
1007 if ((*addrp = (Xtransaddr *) xalloc (ciptr->addrlen)) == NULL)
1009 PRMSG (1,"GetMyAddr: malloc failed\n", 0, 0, 0);
1012 memcpy(*addrp, ciptr->addr, ciptr->addrlen);
1018 TRANS(GetPeerAddr) (ciptr, familyp, addrlenp, addrp)
1020 XtransConnInfo ciptr;
1026 PRMSG (2,"GetPeerAddr(%d)\n", ciptr->fd, 0, 0);
1028 *familyp = ciptr->family;
1029 *addrlenp = ciptr->peeraddrlen;
1031 if ((*addrp = (Xtransaddr *) xalloc (ciptr->peeraddrlen)) == NULL)
1033 PRMSG (1,"GetPeerAddr: malloc failed\n", 0, 0, 0);
1036 memcpy(*addrp, ciptr->peeraddr, ciptr->peeraddrlen);
1043 TRANS(GetConnectionNumber) (ciptr)
1045 XtransConnInfo ciptr;
1053 * These functions are really utility functions, but they require knowledge
1054 * of the internal data structures, so they have to be part of the Transport
1059 complete_network_count ()
1063 int found_local = 0;
1067 * For a complete network, we only need one LOCALCONN transport to work
1070 for (i = 0; i < NUMTRANS; i++)
1072 if (Xtransports[i].transport->flags & TRANS_ALIAS
1073 || Xtransports[i].transport->flags & TRANS_NOLISTEN)
1076 if (Xtransports[i].transport->flags & TRANS_LOCAL)
1082 return (count + found_local);
1089 TRANS(MakeAllCOTSServerListeners) (port, partial, count_ret, ciptrs_ret)
1094 XtransConnInfo **ciptrs_ret;
1097 char buffer[256]; /* ??? What size ?? */
1098 XtransConnInfo ciptr, temp_ciptrs[NUMTRANS];
1101 PRMSG (2,"MakeAllCOTSServerListeners(%s,%x)\n",
1102 port ? port : "NULL", ciptrs_ret, 0);
1106 for (i = 0; i < NUMTRANS; i++)
1108 Xtransport *trans = Xtransports[i].transport;
1110 if (trans->flags&TRANS_ALIAS || trans->flags&TRANS_NOLISTEN)
1113 sprintf(buffer,"%s/:%s", trans->TransName, port ? port : "");
1115 PRMSG (5,"MakeAllCOTSServerListeners: opening %s\n",
1118 if ((ciptr = TRANS(OpenCOTSServer(buffer))) == NULL)
1120 if (trans->flags & TRANS_DISABLED)
1124 "MakeAllCOTSServerListeners: failed to open listener for %s\n",
1125 trans->TransName, 0, 0);
1129 if ((status = TRANS(CreateListener (ciptr, port))) < 0)
1131 if (status == TRANS_ADDR_IN_USE)
1134 * We failed to bind to the specified address because the
1135 * address is in use. It must be that a server is already
1136 * running at this address, and this function should fail.
1140 "MakeAllCOTSServerListeners: server already running\n",
1143 for (j = 0; j < *count_ret; j++)
1144 TRANS(Close) (temp_ciptrs[j]);
1154 "MakeAllCOTSServerListeners: failed to create listener for %s\n",
1155 trans->TransName, 0, 0);
1162 "MakeAllCOTSServerListeners: opened listener for %s, %d\n",
1163 trans->TransName, ciptr->fd, 0);
1165 temp_ciptrs[*count_ret] = ciptr;
1169 *partial = (*count_ret < complete_network_count());
1172 "MakeAllCLTSServerListeners: partial=%d, actual=%d, complete=%d \n",
1173 *partial, *count_ret, complete_network_count());
1177 if ((*ciptrs_ret = (XtransConnInfo *) xalloc (
1178 *count_ret * sizeof (XtransConnInfo))) == NULL)
1183 for (i = 0; i < *count_ret; i++)
1185 (*ciptrs_ret)[i] = temp_ciptrs[i];
1195 TRANS(MakeAllCLTSServerListeners) (port, partial, count_ret, ciptrs_ret)
1200 XtransConnInfo **ciptrs_ret;
1203 char buffer[256]; /* ??? What size ?? */
1204 XtransConnInfo ciptr, temp_ciptrs[NUMTRANS];
1207 PRMSG (2,"MakeAllCLTSServerListeners(%s,%x)\n",
1208 port ? port : "NULL", ciptrs_ret, 0);
1212 for (i = 0; i < NUMTRANS; i++)
1214 Xtransport *trans = Xtransports[i].transport;
1216 if (trans->flags&TRANS_ALIAS || trans->flags&TRANS_NOLISTEN)
1219 sprintf(buffer,"%s/:%s", trans->TransName, port ? port : "");
1221 PRMSG (5,"MakeAllCLTSServerListeners: opening %s\n",
1224 if ((ciptr = TRANS(OpenCLTSServer (buffer))) == NULL)
1227 "MakeAllCLTSServerListeners: failed to open listener for %s\n",
1228 trans->TransName, 0, 0);
1232 if ((status = TRANS(CreateListener (ciptr, port))) < 0)
1234 if (status == TRANS_ADDR_IN_USE)
1237 * We failed to bind to the specified address because the
1238 * address is in use. It must be that a server is already
1239 * running at this address, and this function should fail.
1243 "MakeAllCLTSServerListeners: server already running\n",
1246 for (j = 0; j < *count_ret; j++)
1247 TRANS(Close) (temp_ciptrs[j]);
1257 "MakeAllCLTSServerListeners: failed to create listener for %s\n",
1258 trans->TransName, 0, 0);
1265 "MakeAllCLTSServerListeners: opened listener for %s, %d\n",
1266 trans->TransName, ciptr->fd, 0);
1267 temp_ciptrs[*count_ret] = ciptr;
1271 *partial = (*count_ret < complete_network_count());
1274 "MakeAllCLTSServerListeners: partial=%d, actual=%d, complete=%d \n",
1275 *partial, *count_ret, complete_network_count());
1279 if ((*ciptrs_ret = (XtransConnInfo *) xalloc (
1280 *count_ret * sizeof (XtransConnInfo))) == NULL)
1285 for (i = 0; i < *count_ret; i++)
1287 (*ciptrs_ret)[i] = temp_ciptrs[i];
1296 #endif /* TRANS_SERVER */
1301 * These routines are not part of the X Transport Interface, but they
1302 * may be used by it.
1308 * Cray UniCOS does not have readv and writev so we emulate
1311 static int TRANS(ReadV) (ciptr, iov, iovcnt)
1313 XtransConnInfo ciptr;
1321 hdr.msg_iovlen = iovcnt;
1322 hdr.msg_accrights = 0;
1323 hdr.msg_accrightslen = 0;
1325 hdr.msg_namelen = 0;
1327 return (recvmsg (ciptr->fd, &hdr, 0));
1330 static int TRANS(WriteV) (ciptr, iov, iovcnt)
1332 XtransConnInfo ciptr;
1340 hdr.msg_iovlen = iovcnt;
1341 hdr.msg_accrights = 0;
1342 hdr.msg_accrightslen = 0;
1344 hdr.msg_namelen = 0;
1346 return (sendmsg (ciptr->fd, &hdr, 0));
1351 #if (defined(SYSV) && defined(i386) && !defined(SCO325)) || defined(WIN32) || defined(__sxg__) || defined(__EMX__)
1357 static int TRANS(ReadV) (ciptr, iov, iovcnt)
1359 XtransConnInfo ciptr;
1368 for (i = 0, total = 0; i < iovcnt; i++, iov++) {
1370 base = iov->iov_base;
1372 register int nbytes;
1373 nbytes = TRANS(Read) (ciptr, base, len);
1374 if (nbytes < 0 && total == 0) return -1;
1375 if (nbytes <= 0) return total;
1385 #endif /* SYSV && i386 || WIN32 || __sxg__ */
1387 #if (defined(SYSV) && defined(i386) && !defined(SCO325)) || defined(WIN32) || defined(__sxg__) || defined(__EMX__)
1393 static int TRANS(WriteV) (ciptr, iov, iovcnt)
1395 XtransConnInfo ciptr;
1404 for (i = 0, total = 0; i < iovcnt; i++, iov++) {
1406 base = iov->iov_base;
1408 register int nbytes;
1409 nbytes = TRANS(Write) (ciptr, base, len);
1410 if (nbytes < 0 && total == 0) return -1;
1411 if (nbytes <= 0) return total;
1421 #endif /* SYSV && i386 || WIN32 || __sxg__ */
1424 #if (defined(_POSIX_SOURCE) && !defined(AIXV3)) || defined(hpux) || defined(USG) || defined(SVR4) || defined(SCO)
1425 #ifndef NEED_UTSNAME
1426 #define NEED_UTSNAME
1428 #include <sys/utsname.h>
1432 * TRANS(GetHostname) - similar to gethostname but allows special processing.
1435 int TRANS(GetHostname) (buf, maxlen)
1444 struct utsname name;
1447 len = strlen (name.nodename);
1448 if (len >= maxlen) len = maxlen - 1;
1449 strncpy (buf, name.nodename, len);
1453 (void) gethostname (buf, maxlen);
1454 buf [maxlen - 1] = '\0';
1456 #endif /* NEED_UTSNAME */