1 /* $XConsortium: Xtranstli.c /main/26 1995/12/13 18:07:13 kaleb $ */
2 /* $XFree86: xc/lib/xtrans/Xtranstli.c,v 3.5 1996/09/01 04:14:14 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.
62 #include <netconfig.h>
66 * This is the TLI implementation of the X Transport service layer
69 typedef struct _TLItrans2dev {
77 static TLItrans2dev TLItrans2devtab[] = {
78 {"inet","inet","/dev/tcp","/dev/udp",AF_INET},
79 {"tcp","inet","/dev/tcp","/dev/udp",AF_INET},
80 {"tli","loopback","/dev/ticots","/dev/ticlts",AF_UNIX},
83 #define NUMTLIFAMILIES (sizeof(TLItrans2devtab)/sizeof(TLItrans2dev))
86 * The local TLI connection, is a form of a local connection, so use a
87 * sockaddr_un for the address so that it will be treated just like the other
88 * local transports such as UNIX domain sockets, pts, and named.
92 #define TLINODENAME "TLI:xserver"
96 #define TLINODENAME "TLI:xim"
99 #if defined(FS_t) || defined(FONT_t)
100 #define TLINODENAME "TLI:fontserver"
104 #define TLINODENAME "TLI:ICE"
108 #define TLINODENAME "TLI:test"
113 * These are some utility function used by the real interface function below.
117 TRANS(TLISelectFamily)(family)
124 PRMSG(3,"TLISelectFamily(%s)\n", family, 0,0 );
126 for(i=0;i<NUMTLIFAMILIES;i++)
128 if( !strcmp(family,TLItrans2devtab[i].transname) )
136 * This function gets the local address of the transport and stores it in the
137 * XtransConnInfo structure for the connection.
141 TRANS(TLIGetAddr)(ciptr)
143 XtransConnInfo ciptr;
147 struct netbuf netbuf;
149 PRMSG(3,"TLIGetAddr(%x)\n", ciptr, 0,0 );
151 netbuf.buf=(char *)&sockname;
152 netbuf.len=sizeof(sockname);
153 netbuf.maxlen=sizeof(sockname);
155 if( t_getname(ciptr->fd,&netbuf,LOCALNAME) < 0 )
157 PRMSG(1,"TLIGetAddr: t_getname(LOCALNAME) failed: %d\n",
162 PRMSG(4,"TLIGetAddr: got family %d len %d\n",
163 ((struct sockaddr *) &sockname)->sa_family ,netbuf.len, 0 );
166 * Everything looks good: fill in the XtransConnInfo structure.
172 if( (ciptr->addr=(char *)xalloc(netbuf.len)) == NULL )
174 PRMSG(1, "TLIGetAddr: Can't allocate space for the addr\n",
179 ciptr->family=((struct sockaddr *) &sockname)->sa_family;
180 ciptr->addrlen=netbuf.len;
181 memcpy(ciptr->addr,&sockname,ciptr->addrlen);
188 * This function gets the remote address of the socket and stores it in the
189 * XtransConnInfo structure for the connection.
193 TRANS(TLIGetPeerAddr)(ciptr)
195 XtransConnInfo ciptr;
199 struct netbuf netbuf;
201 PRMSG(3,"TLIGetPeerAddr(%x)\n", ciptr, 0,0 );
203 netbuf.buf=(char *)&sockname;
204 netbuf.len=sizeof(sockname);
205 netbuf.maxlen=sizeof(sockname);
207 if( t_getname(ciptr->fd,&netbuf,REMOTENAME) < 0 )
209 PRMSG(1,"TLIGetPeerAddr: t_getname(REMOTENAME) failed: %d\n",
214 PRMSG(4,"TLIGetPeerAddr: got family %d len %d\n",
215 ((struct sockaddr *) &sockname)->sa_family ,netbuf.len, 0 );
218 * Everything looks good: fill in the XtransConnInfo structure.
221 if( ciptr->peeraddr )
222 xfree(ciptr->peeraddr);
224 if( (ciptr->peeraddr=(char *)xalloc(netbuf.len)) == NULL )
227 "TLIGetPeerAddr: Can't allocate space for the addr\n",
232 ciptr->peeraddrlen=netbuf.len;
233 memcpy(ciptr->peeraddr,&sockname,ciptr->peeraddrlen);
240 * This function will establish a local name for the transport. This function
241 * do extra work for the local tli connection. It must create a sockaddr_un
242 * format address so that it will look like an AF_UNIX connection to the
245 * This function will only be called by the OPENC?TSClient() functions since
246 * the local address is set up in the CreateListner() for the server ends.
250 TRANS(TLITLIBindLocal)(fd,family,port)
257 struct sockaddr_un *sunaddr;
258 struct t_bind *req=NULL;
260 PRMSG(2, "TLITLIBindLocal(%d,%d,%s)\n", fd, family, port);
262 if( family == AF_UNIX )
264 if( (req=(struct t_bind *)t_alloc(fd,T_BIND,0)) == NULL )
267 "TLITLIBindLocal() failed to allocate a t_bind\n",
272 if( (sunaddr=(struct sockaddr_un *)
273 malloc(sizeof(struct sockaddr_un))) == NULL )
276 "TLITLIBindLocal: failed to allocate a sockaddr_un\n",
278 t_free((char *)req,T_BIND);
282 sunaddr->sun_family=AF_UNIX;
285 if( *port == '/' ) { /* A full pathname */
286 (void) strcpy(sunaddr->sun_path, port);
288 (void) sprintf(sunaddr->sun_path,"%s%s", TLINODENAME, port );
292 (void) sprintf(sunaddr->sun_path,"%s%d",
293 TLINODENAME, getpid()^time(NULL) );
295 PRMSG(4, "TLITLIBindLocal: binding to %s\n",
296 sunaddr->sun_path, 0,0);
298 req->addr.buf=(char *)sunaddr;
299 req->addr.len=sizeof(*sunaddr);
300 req->addr.maxlen=sizeof(*sunaddr);
303 if( t_bind(fd, req, NULL) < 0 )
306 "TLIBindLocal: Unable to bind TLI device to %s\n",
313 static XtransConnInfo
314 TRANS(TLIOpen)(device)
319 XtransConnInfo ciptr;
321 PRMSG(3,"TLIOpen(%s)\n", device, 0,0 );
323 if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL )
325 PRMSG(1, "TLIOpen: calloc failed\n", 0,0,0 );
329 if( (ciptr->fd=t_open( device, O_RDWR, NULL )) < 0 )
331 PRMSG(1, "TLIOpen: t_open failed for %s\n", device, 0,0 );
341 static XtransConnInfo
342 TRANS(TLIReopen)(device, fd, port)
349 XtransConnInfo ciptr;
351 PRMSG(3,"TLIReopen(%s,%d, %s)\n", device, fd, port );
355 PRMSG(1, "TLIReopen: t_sync failed\n", 0,0,0 );
359 if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL )
361 PRMSG(1, "TLIReopen: calloc failed\n", 0,0,0 );
370 #endif /* TRANS_REOPEN */
374 TRANS(TLIAddrToNetbuf)(tlifamily, host, port, netbufp)
379 struct netbuf *netbufp;
382 struct netconfig *netconfigp;
383 struct nd_hostserv nd_hostserv;
384 struct nd_addrlist *nd_addrlistp = NULL;
387 PRMSG(3,"TLIAddrToNetbuf(%d,%s,%s)\n", tlifamily, host, port );
389 if( (handlep=setnetconfig()) == NULL )
392 nd_hostserv.h_host = host;
393 if( port && *port ) {
394 nd_hostserv.h_serv = port;
396 nd_hostserv.h_serv = NULL;
399 while( (netconfigp=getnetconfig(handlep)) != NULL )
401 if( strcmp(netconfigp->nc_protofmly,
402 TLItrans2devtab[tlifamily].protofamily) != 0 )
404 PRMSG(5,"TLIAddrToNetbuf: Trying to resolve %s.%s for %s\n",
405 host, port, TLItrans2devtab[tlifamily].protofamily );
406 if( netdir_getbyname(netconfigp,&nd_hostserv, &nd_addrlistp) == 0 )
408 /* we have at least one address to use */
410 PRMSG(5, "TLIAddrToNetbuf: found address for %s.%s\n", host, port, 0 );
411 PRMSG(5, "TLIAddrToNetbuf: %s\n",taddr2uaddr(netconfigp,nd_addrlistp->n_addrs),
414 memcpy(netbufp->buf,nd_addrlistp->n_addrs->buf,
415 nd_addrlistp->n_addrs->len);
416 netbufp->len=nd_addrlistp->n_addrs->len;
417 endnetconfig(handlep);
421 endnetconfig(handlep);
427 * These functions are the interface supplied in the Xtransport structure
432 static XtransConnInfo
433 TRANS(TLIOpenCOTSClient)(thistrans, protocol, host, port)
435 Xtransport *thistrans;
441 XtransConnInfo ciptr;
444 PRMSG(2,"TLIOpenCOTSClient(%s,%s,%s)\n", protocol, host, port );
446 if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
448 PRMSG(1,"TLIOpenCOTSClient: Unable to determine device for %s\n",
449 thistrans->TransName, 0,0 );
453 if( (ciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcotsname)) == NULL )
455 PRMSG(1,"TLIOpenCOTSClient: Unable to open device for %s\n",
456 thistrans->TransName, 0,0 );
460 if( TRANS(TLITLIBindLocal)(ciptr->fd,TLItrans2devtab[i].family,port) < 0 )
463 "TLIOpenCOTSClient: ...TLITLIBindLocal() failed: %d\n",
470 if( TRANS(TLIGetAddr)(ciptr) < 0 )
473 "TLIOpenCOTSClient: ...TLIGetAddr() failed: %d\n",
480 /* Save the TLIFamily for later use in TLIAddrToNetbuf() lookups */
486 #endif /* TRANS_CLIENT */
491 static XtransConnInfo
492 TRANS(TLIOpenCOTSServer)(thistrans, protocol, host, port)
494 Xtransport *thistrans;
500 XtransConnInfo ciptr;
503 PRMSG(2,"TLIOpenCOTSServer(%s,%s,%s)\n", protocol, host, port );
505 if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
508 "TLIOpenCOTSServer: Unable to determine device for %s\n",
509 thistrans->TransName, 0,0 );
513 if( (ciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcotsname)) == NULL )
516 "TLIOpenCOTSServer: Unable to open device for %s\n",
517 thistrans->TransName, 0,0 );
521 /* Set the family type */
523 ciptr->family = TLItrans2devtab[i].family;
526 /* Save the TLIFamily for later use in TLIAddrToNetbuf() lookups */
533 #endif /* TRANS_SERVER */
538 static XtransConnInfo
539 TRANS(TLIOpenCLTSClient)(thistrans, protocol, host, port)
541 Xtransport *thistrans;
547 XtransConnInfo ciptr;
550 PRMSG(2,"TLIOpenCLTSClient(%s,%s,%s)\n", protocol, host, port );
552 if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
555 "TLIOpenCLTSClient: Unable to determine device for %s\n",
556 thistrans->TransName, 0,0 );
560 if( (ciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcltsname)) == NULL )
563 "TLIOpenCLTSClient: Unable to open device for %s\n",
564 thistrans->TransName, 0,0 );
568 if( TRANS(TLITLIBindLocal)(ciptr->fd,TLItrans2devtab[i].family,port) < 0 )
571 "TLIOpenCLTSClient: ...TLITLIBindLocal() failed: %d\n",
578 if( TRANS(TLIGetAddr)(ciptr) < 0 )
581 "TLIOpenCLTSClient: ...TLIGetPeerAddr() failed: %d\n",
591 #endif /* TRANS_CLIENT */
596 static XtransConnInfo
597 TRANS(TLIOpenCLTSServer)(thistrans, protocol, host, port)
599 Xtransport *thistrans;
605 XtransConnInfo ciptr;
608 PRMSG(2,"TLIOpenCLTSServer(%s,%s,%s)\n", protocol, host, port );
610 if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
613 "TLIOpenCLTSServer: Unable to determine device for %s\n",
614 thistrans->TransName, 0,0 );
618 if( (ciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcltsname)) == NULL )
621 "TLIOpenCLTSServer: Unable to open device for %s\n",
622 thistrans->TransName, 0,0 );
629 #endif /* TRANS_SERVER */
634 static XtransConnInfo
635 TRANS(TLIReopenCOTSServer)(thistrans, fd, port)
637 Xtransport *thistrans;
642 XtransConnInfo ciptr;
645 PRMSG(2,"TLIReopenCOTSServer(%d, %s)\n", fd, port, 0 );
647 if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
650 "TLIReopenCOTSServer: Unable to determine device for %s\n",
651 thistrans->TransName, 0,0 );
655 if( (ciptr=TRANS(TLIReopen)(
656 TLItrans2devtab[i].devcotsname, fd, port)) == NULL )
659 "TLIReopenCOTSServer: Unable to open device for %s\n",
660 thistrans->TransName, 0,0 );
664 /* Save the TLIFamily for later use in TLIAddrToNetbuf() lookups */
672 static XtransConnInfo
673 TRANS(TLIReopenCLTSServer)(thistrans, fd, port)
675 Xtransport *thistrans;
680 XtransConnInfo ciptr;
683 PRMSG(2,"TLIReopenCLTSServer(%d, %s)\n", fd, port, 0 );
685 if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
688 "TLIReopenCLTSServer: Unable to determine device for %s\n",
689 thistrans->TransName, 0,0 );
693 if( (ciptr=TRANS(TLIReopen)(
694 TLItrans2devtab[i].devcltsname, fd, port)) == NULL )
697 "TLIReopenCLTSServer: Unable to open device for %s\n",
698 thistrans->TransName, 0,0 );
707 #endif /* TRANS_REOPEN */
711 TRANS(TLISetOption)(ciptr, option, arg)
713 XtransConnInfo ciptr;
718 PRMSG(2,"TLISetOption(%d,%d,%d)\n", ciptr->fd, option, arg );
727 TRANS(TLICreateListener)(ciptr, req)
729 XtransConnInfo ciptr;
735 PRMSG(2,"TLICreateListener(%x->%d,%x)\n", ciptr, ciptr->fd, req );
737 if( (ret=(struct t_bind *)t_alloc(ciptr->fd,T_BIND,T_ALL)) == NULL )
739 PRMSG(1, "TLICreateListener: failed to allocate a t_bind\n",
741 return TRANS_CREATE_LISTENER_FAILED;
744 if( t_bind(ciptr->fd, req, ret) < 0 )
746 PRMSG(1, "TLICreateListener: t_bind failed\n", 0,0,0 );
747 t_free((char *)req,T_BIND);
748 t_free((char *)ret,T_BIND);
749 return TRANS_CREATE_LISTENER_FAILED;
752 if( memcmp(req->addr.buf,ret->addr.buf,req->addr.len) != 0 )
754 PRMSG(1, "TLICreateListener: unable to bind to %x\n",
756 t_free((char *)req,T_BIND);
757 t_free((char *)ret,T_BIND);
758 return TRANS_ADDR_IN_USE;
762 * Everything looks good: fill in the XtransConnInfo structure.
765 if( (ciptr->addr=(char *)xalloc(ret->addr.len)) == NULL )
768 "TLICreateListener: Unable to allocate space for the address\n",
770 t_free((char *)req,T_BIND);
771 t_free((char *)ret, T_BIND);
772 return TRANS_CREATE_LISTENER_FAILED;
775 ciptr->addrlen=ret->addr.len;
776 memcpy(ciptr->addr,ret->addr.buf,ret->addr.len);
778 t_free((char *)req,T_BIND);
779 t_free((char *)ret, T_BIND);
786 TRANS(TLIINETCreateListener)(ciptr, port)
788 XtransConnInfo ciptr;
792 #define PORTBUFSIZE 64 /* what is a real size for this? */
793 char portbuf[PORTBUFSIZE];
795 struct sockaddr_in *sinaddr;
797 PRMSG(2,"TLIINETCreateListener(%x->%d,%s)\n", ciptr,
798 ciptr->fd, port ? port : "NULL" );
802 * X has a well known port, that is transport dependent. It is easier
803 * to handle it here, than try and come up with a transport independent
804 * representation that can be passed in and resolved the usual way.
806 * The port that is passed here is really a string containing the idisplay
807 * from ConnectDisplay().
810 if (is_numeric (port))
812 short tmpport = (short) atoi (port);
814 sprintf(portbuf,"%d", X_TCP_PORT+tmpport );
817 strncpy(portbuf,port,PORTBUFSIZE);
821 if( (req=(struct t_bind *)t_alloc(ciptr->fd,T_BIND,T_ALL)) == NULL )
824 "TLIINETCreateListener: failed to allocate a t_bind\n",
826 return TRANS_CREATE_LISTENER_FAILED;
829 if( port && *port ) {
830 if(TRANS(TLIAddrToNetbuf)(ciptr->index,HOST_SELF,port,&(req->addr)) < 0)
833 "TLIINETCreateListener: can't resolve name:HOST_SELF.%s\n",
835 t_free((char *)req,T_BIND);
836 return TRANS_CREATE_LISTENER_FAILED;
839 sinaddr=(struct sockaddr_in *)req->addr.buf;
840 sinaddr->sin_family=AF_INET;
842 sinaddr->sin_addr.s_addr=0;
849 return TRANS(TLICreateListener)(ciptr, req);
854 TRANS(TLITLICreateListener)(ciptr, port)
856 XtransConnInfo ciptr;
861 struct sockaddr_un *sunaddr;
863 PRMSG(2,"TLITLICreateListener(%x->%d,%s)\n", ciptr, ciptr->fd,
864 port ? port : "NULL");
866 if( (req=(struct t_bind *)t_alloc(ciptr->fd,T_BIND,0)) == NULL )
869 "TLITLICreateListener: failed to allocate a t_bind\n",
871 return TRANS_CREATE_LISTENER_FAILED;
874 if( (sunaddr=(struct sockaddr_un *)
875 malloc(sizeof(struct sockaddr_un))) == NULL )
878 "TLITLICreateListener: failed to allocate a sockaddr_un\n",
880 t_free((char *)req,T_BIND);
881 return TRANS_CREATE_LISTENER_FAILED;
884 sunaddr->sun_family=AF_UNIX;
885 if( port && *port ) {
886 if( *port == '/' ) { /* A full pathname */
887 (void) strcpy(sunaddr->sun_path, port);
889 (void) sprintf(sunaddr->sun_path,"%s%s", TLINODENAME, port );
892 (void) sprintf(sunaddr->sun_path,"%s%d", TLINODENAME, getpid());
895 req->addr.buf=(char *)sunaddr;
896 req->addr.len=sizeof(*sunaddr);
897 req->addr.maxlen=sizeof(*sunaddr);
903 return TRANS(TLICreateListener)(ciptr, req);
907 static XtransConnInfo
908 TRANS(TLIAccept)(ciptr, status)
910 XtransConnInfo ciptr;
915 XtransConnInfo newciptr;
918 PRMSG(2,"TLIAccept(%x->%d)\n", ciptr, ciptr->fd, 0 );
920 if( (call=(struct t_call *)t_alloc(ciptr->fd,T_CALL,T_ALL)) == NULL )
922 PRMSG(1, "TLIAccept() failed to allocate a t_call\n", 0,0,0 );
923 *status = TRANS_ACCEPT_BAD_MALLOC;
927 if( t_listen(ciptr->fd,call) < 0 )
929 extern char *t_errlist[];
931 PRMSG(1, "TLIAccept() t_listen() failed\n", 0,0,0 );
932 PRMSG(1, "TLIAccept: %s\n", t_errlist[t_errno], 0,0 );
933 t_free((char *)call,T_CALL);
934 *status = TRANS_ACCEPT_MISC_ERROR;
939 * Now we need to set up the new endpoint for the incoming connection.
942 i=ciptr->index; /* Makes the next line more readable */
944 if( (newciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcotsname)) == NULL )
946 PRMSG(1, "TLIAccept() failed to open a new endpoint\n", 0,0,0 );
947 t_free((char *)call,T_CALL);
948 *status = TRANS_ACCEPT_MISC_ERROR;
952 if( TRANS(TLITLIBindLocal)(newciptr->fd,TLItrans2devtab[i].family,"") < 0 )
955 "TLIAccept: TRANS(TLITLIBindLocal)() failed: %d\n",
957 t_free((char *)call,T_CALL);
958 t_close(newciptr->fd);
960 *status = TRANS_ACCEPT_MISC_ERROR;
965 if( t_accept(ciptr->fd,newciptr->fd,call) < 0 )
967 extern char *t_errlist[];
969 PRMSG(1, "TLIAccept() t_accept() failed\n", 0,0,0 );
970 PRMSG(1, "TLIAccept: %s\n", t_errlist[t_errno], 0,0 );
971 t_free((char *)call,T_CALL);
972 t_close(newciptr->fd);
973 xfree(newciptr->addr);
975 *status = TRANS_ACCEPT_FAILED;
979 t_free((char *)call,T_CALL);
981 if( TRANS(TLIGetAddr)(newciptr) < 0 )
984 "TLIAccept: TRANS(TLIGetPeerAddr)() failed: %d\n",
986 t_close(newciptr->fd);
988 *status = TRANS_ACCEPT_MISC_ERROR;
992 if( TRANS(TLIGetPeerAddr)(newciptr) < 0 )
995 "TLIAccept: TRANS(TLIGetPeerAddr)() failed: %d\n",
997 t_close(newciptr->fd);
998 xfree(newciptr->addr);
1000 *status = TRANS_ACCEPT_MISC_ERROR;
1004 if( ioctl(newciptr->fd, I_POP,"timod") < 0 )
1006 PRMSG(1, "TLIAccept() ioctl(I_POP, \"timod\") failed %d\n",
1008 t_close(newciptr->fd);
1009 xfree(newciptr->addr);
1011 *status = TRANS_ACCEPT_MISC_ERROR;
1015 if( ioctl(newciptr->fd, I_PUSH,"tirdwr") < 0 )
1017 PRMSG(1, "TLIAccept() ioctl(I_PUSH,\"tirdwr\") failed %d\n",
1019 t_close(newciptr->fd);
1020 xfree(newciptr->addr);
1022 *status = TRANS_ACCEPT_MISC_ERROR;
1031 #endif /* TRANS_SERVER */
1037 TRANS(TLIConnect)(ciptr, sndcall )
1039 XtransConnInfo ciptr;
1040 struct t_call *sndcall;
1043 PRMSG(2, "TLIConnect(%x->%d,%x)\n", ciptr, ciptr->fd, sndcall);
1045 if( t_connect(ciptr->fd,sndcall,NULL) < 0 )
1047 extern char *t_errlist[];
1049 PRMSG(1, "TLIConnect() t_connect() failed\n", 0,0,0 );
1050 PRMSG(1, "TLIConnect: %s\n", t_errlist[t_errno], 0,0 );
1051 t_free((char *)sndcall,T_CALL);
1052 if (t_errno == TLOOK && t_look(ciptr->fd) == T_DISCONNECT)
1054 t_rcvdis(ciptr->fd,NULL);
1055 return TRANS_TRY_CONNECT_AGAIN;
1058 return TRANS_CONNECT_FAILED;
1061 t_free((char *)sndcall,T_CALL);
1064 * Sync up the address fields of ciptr.
1067 if( TRANS(TLIGetAddr)(ciptr) < 0 )
1070 "TLIConnect: ...TLIGetAddr() failed: %d\n",
1072 return TRANS_CONNECT_FAILED;
1075 if( TRANS(TLIGetPeerAddr)(ciptr) < 0 )
1078 "TLIConnect: ...TLIGetPeerAddr() failed: %d\n",
1080 return TRANS_CONNECT_FAILED;
1083 if( ioctl(ciptr->fd, I_POP,"timod") < 0 )
1085 PRMSG(1, "TLIConnect() ioctl(I_POP,\"timod\") failed %d\n",
1087 return TRANS_CONNECT_FAILED;
1090 if( ioctl(ciptr->fd, I_PUSH,"tirdwr") < 0 )
1092 PRMSG(1, "TLIConnect() ioctl(I_PUSH,\"tirdwr\") failed %d\n",
1094 return TRANS_CONNECT_FAILED;
1102 TRANS(TLIINETConnect)(ciptr, host, port)
1104 XtransConnInfo ciptr;
1109 #define PORTBUFSIZE 64 /* what is a real size for this? */
1110 char portbuf[PORTBUFSIZE];
1111 struct t_call *sndcall;
1113 PRMSG(2, "TLIINETConnect(%s,%s)\n", host, port, 0);
1117 * X has a well known port, that is transport dependant. It is easier
1118 * to handle it here, than try and come up with a transport independent
1119 * representation that can be passed in and resolved the usual way.
1121 * The port that is passed here is really a string containing the idisplay
1122 * from ConnectDisplay().
1125 if (is_numeric (port))
1127 short tmpport = (short) atoi (port);
1129 sprintf(portbuf,"%d", X_TCP_PORT+tmpport );
1133 strncpy(portbuf,port,PORTBUFSIZE);
1135 if( (sndcall=(struct t_call *)t_alloc(ciptr->fd,T_CALL,T_ALL)) == NULL )
1137 PRMSG(1, "TLIINETConnect() failed to allocate a t_call\n", 0,0,0 );
1138 return TRANS_CONNECT_FAILED;
1141 if( TRANS(TLIAddrToNetbuf)(ciptr->index, host, portbuf, &(sndcall->addr) ) < 0 )
1143 PRMSG(1, "TLIINETConnect() unable to resolve name:%s.%s\n",
1145 t_free((char *)sndcall,T_CALL);
1146 return TRANS_CONNECT_FAILED;
1149 return TRANS(TLIConnect)(ciptr, sndcall );
1154 TRANS(TLITLIConnect)(ciptr, host, port)
1156 XtransConnInfo ciptr;
1161 struct t_call *sndcall;
1162 struct sockaddr_un *sunaddr;
1164 PRMSG(2, "TLITLIConnect(%s,%s)\n", host, port, 0);
1166 if( (sndcall=(struct t_call *)t_alloc(ciptr->fd,T_CALL,T_OPT|T_UDATA)) == NULL )
1168 PRMSG(1, "TLITLIConnect() failed to allocate a t_call\n", 0,0,0 );
1169 return TRANS_CONNECT_FAILED;
1172 if( (sunaddr=(struct sockaddr_un *)
1173 malloc(sizeof(struct sockaddr_un))) == NULL )
1176 "TLITLIConnect: failed to allocate a sockaddr_un\n",
1178 t_free((char *)sndcall,T_CALL);
1179 return TRANS_CONNECT_FAILED;
1182 sunaddr->sun_family=AF_UNIX;
1184 strncmp (port, TLINODENAME, strlen (TLINODENAME)) == 0) {
1185 /* Use the port as is */
1186 (void) strcpy(sunaddr->sun_path, port);
1188 (void) sprintf(sunaddr->sun_path,"%s%s", TLINODENAME, port );
1191 sndcall->addr.buf=(char *)sunaddr;
1192 sndcall->addr.len=sizeof(*sunaddr);
1193 sndcall->addr.maxlen=sizeof(*sunaddr);
1195 return TRANS(TLIConnect)(ciptr, sndcall );
1198 #endif /* TRANS_CLIENT */
1202 TRANS(TLIBytesReadable)(ciptr, pend)
1204 XtransConnInfo ciptr;
1205 BytesReadable_t *pend;
1209 struct pollfd filedes;
1211 PRMSG(2, "TLIByteReadable(%x->%d,%x)\n", ciptr, ciptr->fd, pend );
1214 * This function should detect hangup conditions. Use poll to check
1215 * if no data is present. On SVR4, the M_HANGUP message sits on the
1216 * streams head, and ioctl(N_READ) keeps returning 0 because there is
1217 * no data available. The hangup goes undetected, and the client hangs.
1220 ret=ioctl(ciptr->fd, I_NREAD, (char *)pend);
1223 return ret; /* Data present or error */
1226 /* Zero data, or POLLHUP message */
1228 filedes.fd=ciptr->fd;
1229 filedes.events=POLLIN;
1231 ret=poll(&filedes, 1, 0);
1235 return 0; /* Really, no data */
1239 return -1; /* just pass back the error */
1241 if( filedes.revents & (POLLHUP|POLLERR) ) /* check for hangup */
1244 /* Should only get here if data arrived after the first ioctl() */
1245 return ioctl(ciptr->fd, I_NREAD, (char *)pend);
1250 TRANS(TLIRead)(ciptr, buf, size)
1252 XtransConnInfo ciptr;
1257 PRMSG(2, "TLIRead(%d,%x,%d)\n", ciptr->fd, buf, size );
1259 return read(ciptr->fd,buf,size);
1264 TRANS(TLIWrite)(ciptr, buf, size)
1266 XtransConnInfo ciptr;
1271 PRMSG(2, "TLIWrite(%d,%x,%d)\n", ciptr->fd, buf, size );
1273 return write(ciptr->fd,buf,size);
1278 TRANS(TLIReadv)(ciptr, buf, size)
1280 XtransConnInfo ciptr;
1285 PRMSG(2, "TLIReadv(%d,%x,%d)\n", ciptr->fd, buf, size );
1287 return READV(ciptr,buf,size);
1292 TRANS(TLIWritev)(ciptr, buf, size)
1294 XtransConnInfo ciptr;
1299 PRMSG(2, "TLIWritev(%d,%x,%d)\n", ciptr->fd, buf, size );
1301 return WRITEV(ciptr,buf,size);
1306 TRANS(TLIDisconnect)(ciptr)
1308 XtransConnInfo ciptr;
1311 PRMSG(2, "TLIDisconnect(%x->%d)\n", ciptr, ciptr->fd, 0 );
1314 * Restore the TLI modules so that the connection can be properly shutdown.
1315 * This avoids the situation where a connection goes into the TIME_WAIT
1316 * state, and the address remains unavailable for a while.
1318 ioctl(ciptr->fd, I_POP,"tirdwr");
1319 ioctl(ciptr->fd, I_PUSH,"timod");
1321 t_snddis(ciptr->fd,NULL);
1328 TRANS(TLIClose)(ciptr)
1330 XtransConnInfo ciptr;
1333 PRMSG(2, "TLIClose(%x->%d)\n", ciptr, ciptr->fd, 0 );
1335 t_unbind(ciptr->fd);
1337 return (t_close(ciptr->fd));
1342 TRANS(TLICloseForCloning)(ciptr)
1344 XtransConnInfo ciptr;
1351 PRMSG(2, "TLICloseForCloning(%x->%d)\n", ciptr, ciptr->fd, 0 );
1353 return (t_close(ciptr->fd));
1357 Xtransport TRANS(TLITCPFuncs) = {
1362 TRANS(TLIOpenCOTSClient),
1363 #endif /* TRANS_CLIENT */
1365 TRANS(TLIOpenCOTSServer),
1366 #endif /* TRANS_SERVER */
1368 TRANS(TLIOpenCLTSClient),
1369 #endif /* TRANS_CLIENT */
1371 TRANS(TLIOpenCLTSServer),
1372 #endif /* TRANS_SERVER */
1374 TRANS(TLIReopenCOTSServer),
1375 TRANS(TLIReopenCLTSServer),
1377 TRANS(TLISetOption),
1379 TRANS(TLIINETCreateListener),
1380 NULL, /* ResetListener */
1382 #endif /* TRANS_SERVER */
1384 TRANS(TLIINETConnect),
1385 #endif /* TRANS_CLIENT */
1386 TRANS(TLIBytesReadable),
1391 TRANS(TLIDisconnect),
1393 TRANS(TLICloseForCloning),
1396 Xtransport TRANS(TLIINETFuncs) = {
1401 TRANS(TLIOpenCOTSClient),
1402 #endif /* TRANS_CLIENT */
1404 TRANS(TLIOpenCOTSServer),
1405 #endif /* TRANS_SERVER */
1407 TRANS(TLIOpenCLTSClient),
1408 #endif /* TRANS_CLIENT */
1410 TRANS(TLIOpenCLTSServer),
1411 #endif /* TRANS_SERVER */
1413 TRANS(TLIReopenCOTSServer),
1414 TRANS(TLIReopenCLTSServer),
1416 TRANS(TLISetOption),
1418 TRANS(TLIINETCreateListener),
1419 NULL, /* ResetListener */
1421 #endif /* TRANS_SERVER */
1423 TRANS(TLIINETConnect),
1424 #endif /* TRANS_CLIENT */
1425 TRANS(TLIBytesReadable),
1430 TRANS(TLIDisconnect),
1432 TRANS(TLICloseForCloning),
1435 Xtransport TRANS(TLITLIFuncs) = {
1440 TRANS(TLIOpenCOTSClient),
1441 #endif /* TRANS_CLIENT */
1443 TRANS(TLIOpenCOTSServer),
1444 #endif /* TRANS_SERVER */
1446 TRANS(TLIOpenCLTSClient),
1447 #endif /* TRANS_CLIENT */
1449 TRANS(TLIOpenCLTSServer),
1450 #endif /* TRANS_SERVER */
1452 TRANS(TLIReopenCOTSServer),
1453 TRANS(TLIReopenCLTSServer),
1455 TRANS(TLISetOption),
1457 TRANS(TLITLICreateListener),
1458 NULL, /* ResetListener */
1460 #endif /* TRANS_SERVER */
1462 TRANS(TLITLIConnect),
1463 #endif /* TRANS_CLIENT */
1464 TRANS(TLIBytesReadable),
1469 TRANS(TLIDisconnect),
1471 TRANS(TLICloseForCloning),