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.
56 #include <netconfig.h>
60 * This is the TLI implementation of the X Transport service layer
63 typedef struct _TLItrans2dev {
71 static TLItrans2dev TLItrans2devtab[] = {
72 {"inet","inet","/dev/tcp","/dev/udp",AF_INET},
73 {"tcp","inet","/dev/tcp","/dev/udp",AF_INET},
74 {"tli","loopback","/dev/ticots","/dev/ticlts",AF_UNIX},
77 #define NUMTLIFAMILIES (sizeof(TLItrans2devtab)/sizeof(TLItrans2dev))
80 * The local TLI connection, is a form of a local connection, so use a
81 * sockaddr_un for the address so that it will be treated just like the other
82 * local transports such as UNIX domain sockets, pts, and named.
86 #define TLINODENAME "TLI:xserver"
90 #define TLINODENAME "TLI:xim"
93 #if defined(FS_t) || defined(FONT_t)
94 #define TLINODENAME "TLI:fontserver"
98 #define TLINODENAME "TLI:ICE"
102 #define TLINODENAME "TLI:test"
107 #define PORTBUFSIZE 64
110 #define PORTBUFSIZE 64
117 * These are some utility function used by the real interface function below.
121 TRANS(TLISelectFamily)(char *family)
126 PRMSG(3,"TLISelectFamily(%s)\n", family, 0,0 );
128 for(i=0;i<NUMTLIFAMILIES;i++)
130 if( !strcmp(family,TLItrans2devtab[i].transname) )
138 * This function gets the local address of the transport and stores it in the
139 * XtransConnInfo structure for the connection.
143 TRANS(TLIGetAddr)(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)(XtransConnInfo ciptr)
197 struct netbuf netbuf;
199 PRMSG(3,"TLIGetPeerAddr(%x)\n", ciptr, 0,0 );
201 netbuf.buf=(char *)&sockname;
202 netbuf.len=sizeof(sockname);
203 netbuf.maxlen=sizeof(sockname);
205 if( t_getname(ciptr->fd,&netbuf,REMOTENAME) < 0 )
207 PRMSG(1,"TLIGetPeerAddr: t_getname(REMOTENAME) failed: %d\n",
212 PRMSG(4,"TLIGetPeerAddr: got family %d len %d\n",
213 ((struct sockaddr *) &sockname)->sa_family ,netbuf.len, 0 );
216 * Everything looks good: fill in the XtransConnInfo structure.
219 if( ciptr->peeraddr )
220 xfree(ciptr->peeraddr);
222 if( (ciptr->peeraddr=(char *)xalloc(netbuf.len)) == NULL )
225 "TLIGetPeerAddr: Can't allocate space for the addr\n",
230 ciptr->peeraddrlen=netbuf.len;
231 memcpy(ciptr->peeraddr,&sockname,ciptr->peeraddrlen);
238 * This function will establish a local name for the transport. This function
239 * do extra work for the local tli connection. It must create a sockaddr_un
240 * format address so that it will look like an AF_UNIX connection to the
243 * This function will only be called by the OPENC?TSClient() functions since
244 * the local address is set up in the CreateListner() for the server ends.
248 TRANS(TLITLIBindLocal)(int fd, int family, char *port)
251 struct sockaddr_un *sunaddr=NULL;
252 struct t_bind *req=NULL;
254 PRMSG(2, "TLITLIBindLocal(%d,%d,%s)\n", fd, family, port);
256 if( family == AF_UNIX )
258 if( (req=(struct t_bind *)t_alloc(fd,T_BIND,0)) == NULL )
261 "TLITLIBindLocal() failed to allocate a t_bind\n",
266 if( (sunaddr=(struct sockaddr_un *)
267 malloc(sizeof(struct sockaddr_un))) == NULL )
270 "TLITLIBindLocal: failed to allocate a sockaddr_un\n",
272 t_free((char *)req,T_BIND);
276 sunaddr->sun_family=AF_UNIX;
279 if( *port == '/' ) { /* A full pathname */
280 (void) strcpy(sunaddr->sun_path, port);
282 (void) sprintf(sunaddr->sun_path,"%s%s", TLINODENAME, port );
286 (void) sprintf(sunaddr->sun_path,"%s%d",
287 TLINODENAME, getpid()^time(NULL) );
289 PRMSG(4, "TLITLIBindLocal: binding to %s\n",
290 sunaddr->sun_path, 0,0);
292 req->addr.buf=(char *)sunaddr;
293 req->addr.len=sizeof(*sunaddr);
294 req->addr.maxlen=sizeof(*sunaddr);
297 if( t_bind(fd, req, NULL) < 0 )
300 "TLIBindLocal: Unable to bind TLI device to %s\n",
303 free((char *) sunaddr);
305 t_free((char *)req,T_BIND);
311 static XtransConnInfo
312 TRANS(TLIOpen)(char *device)
315 XtransConnInfo ciptr;
317 PRMSG(3,"TLIOpen(%s)\n", device, 0,0 );
319 if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL )
321 PRMSG(1, "TLIOpen: calloc failed\n", 0,0,0 );
325 if( (ciptr->fd=t_open( device, O_RDWR, NULL )) < 0 )
327 PRMSG(1, "TLIOpen: t_open failed for %s\n", device, 0,0 );
338 static XtransConnInfo
339 TRANS(TLIReopen)(char *device, int fd, char *port)
342 XtransConnInfo ciptr;
344 PRMSG(3,"TLIReopen(%s,%d, %s)\n", device, fd, port );
348 PRMSG(1, "TLIReopen: t_sync failed\n", 0,0,0 );
352 if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL )
354 PRMSG(1, "TLIReopen: calloc failed\n", 0,0,0 );
363 #endif /* TRANS_REOPEN */
367 TRANS(TLIAddrToNetbuf)(int tlifamily, char *host, char *port,
368 struct netbuf *netbufp)
371 struct netconfig *netconfigp;
372 struct nd_hostserv nd_hostserv;
373 struct nd_addrlist *nd_addrlistp = NULL;
377 PRMSG(3,"TLIAddrToNetbuf(%d,%s,%s)\n", tlifamily, host, port );
379 if( (handlep=setnetconfig()) == NULL )
382 lport = strtol (port, (char**)NULL, 10);
383 if (lport < 1024 || lport > USHRT_MAX)
386 nd_hostserv.h_host = host;
387 if( port && *port ) {
388 nd_hostserv.h_serv = port;
390 nd_hostserv.h_serv = NULL;
393 while( (netconfigp=getnetconfig(handlep)) != NULL )
395 if( strcmp(netconfigp->nc_protofmly,
396 TLItrans2devtab[tlifamily].protofamily) != 0 )
398 PRMSG(5,"TLIAddrToNetbuf: Trying to resolve %s.%s for %s\n",
399 host, port, TLItrans2devtab[tlifamily].protofamily );
400 if( netdir_getbyname(netconfigp,&nd_hostserv, &nd_addrlistp) == 0 )
402 /* we have at least one address to use */
404 PRMSG(5, "TLIAddrToNetbuf: found address for %s.%s\n", host, port, 0 );
405 PRMSG(5, "TLIAddrToNetbuf: %s\n",taddr2uaddr(netconfigp,nd_addrlistp->n_addrs),
408 memcpy(netbufp->buf,nd_addrlistp->n_addrs->buf,
409 nd_addrlistp->n_addrs->len);
410 netbufp->len=nd_addrlistp->n_addrs->len;
411 endnetconfig(handlep);
415 endnetconfig(handlep);
421 * These functions are the interface supplied in the Xtransport structure
426 static XtransConnInfo
427 TRANS(TLIOpenCOTSClient)(Xtransport *thistrans, char *protocol,
428 char *host, char *port)
431 XtransConnInfo ciptr;
434 PRMSG(2,"TLIOpenCOTSClient(%s,%s,%s)\n", protocol, host, port );
436 if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
438 PRMSG(1,"TLIOpenCOTSClient: Unable to determine device for %s\n",
439 thistrans->TransName, 0,0 );
443 if( (ciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcotsname)) == NULL )
445 PRMSG(1,"TLIOpenCOTSClient: Unable to open device for %s\n",
446 thistrans->TransName, 0,0 );
450 if( TRANS(TLITLIBindLocal)(ciptr->fd,TLItrans2devtab[i].family,port) < 0 )
453 "TLIOpenCOTSClient: ...TLITLIBindLocal() failed: %d\n",
460 if( TRANS(TLIGetAddr)(ciptr) < 0 )
463 "TLIOpenCOTSClient: ...TLIGetAddr() failed: %d\n",
470 /* Save the TLIFamily for later use in TLIAddrToNetbuf() lookups */
476 #endif /* TRANS_CLIENT */
481 static XtransConnInfo
482 TRANS(TLIOpenCOTSServer)(Xtransport *thistrans, char *protocol,
483 char *host, char *port)
486 XtransConnInfo ciptr;
489 PRMSG(2,"TLIOpenCOTSServer(%s,%s,%s)\n", protocol, host, port );
491 if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
494 "TLIOpenCOTSServer: Unable to determine device for %s\n",
495 thistrans->TransName, 0,0 );
499 if( (ciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcotsname)) == NULL )
502 "TLIOpenCOTSServer: Unable to open device for %s\n",
503 thistrans->TransName, 0,0 );
507 /* Set the family type */
509 ciptr->family = TLItrans2devtab[i].family;
512 /* Save the TLIFamily for later use in TLIAddrToNetbuf() lookups */
519 #endif /* TRANS_SERVER */
524 static XtransConnInfo
525 TRANS(TLIOpenCLTSClient)(Xtransport *thistrans, char *protocol,
526 char *host, char *port)
529 XtransConnInfo ciptr;
532 PRMSG(2,"TLIOpenCLTSClient(%s,%s,%s)\n", protocol, host, port );
534 if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
537 "TLIOpenCLTSClient: Unable to determine device for %s\n",
538 thistrans->TransName, 0,0 );
542 if( (ciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcltsname)) == NULL )
545 "TLIOpenCLTSClient: Unable to open device for %s\n",
546 thistrans->TransName, 0,0 );
550 if( TRANS(TLITLIBindLocal)(ciptr->fd,TLItrans2devtab[i].family,port) < 0 )
553 "TLIOpenCLTSClient: ...TLITLIBindLocal() failed: %d\n",
560 if( TRANS(TLIGetAddr)(ciptr) < 0 )
563 "TLIOpenCLTSClient: ...TLIGetPeerAddr() failed: %d\n",
573 #endif /* TRANS_CLIENT */
578 static XtransConnInfo
579 TRANS(TLIOpenCLTSServer)(Xtransport *thistrans, char *protocol,
580 char *host, char *port)
583 XtransConnInfo ciptr;
586 PRMSG(2,"TLIOpenCLTSServer(%s,%s,%s)\n", protocol, host, port );
588 if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
591 "TLIOpenCLTSServer: Unable to determine device for %s\n",
592 thistrans->TransName, 0,0 );
596 if( (ciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcltsname)) == NULL )
599 "TLIOpenCLTSServer: Unable to open device for %s\n",
600 thistrans->TransName, 0,0 );
607 #endif /* TRANS_SERVER */
612 static XtransConnInfo
613 TRANS(TLIReopenCOTSServer)(Xtransport *thistrans, int fd, char *port)
616 XtransConnInfo ciptr;
619 PRMSG(2,"TLIReopenCOTSServer(%d, %s)\n", fd, port, 0 );
621 if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
624 "TLIReopenCOTSServer: Unable to determine device for %s\n",
625 thistrans->TransName, 0,0 );
629 if( (ciptr=TRANS(TLIReopen)(
630 TLItrans2devtab[i].devcotsname, fd, port)) == NULL )
633 "TLIReopenCOTSServer: Unable to open device for %s\n",
634 thistrans->TransName, 0,0 );
638 /* Save the TLIFamily for later use in TLIAddrToNetbuf() lookups */
646 static XtransConnInfo
647 TRANS(TLIReopenCLTSServer)(Xtransport *thistrans, int fd, char *port)
650 XtransConnInfo ciptr;
653 PRMSG(2,"TLIReopenCLTSServer(%d, %s)\n", fd, port, 0 );
655 if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
658 "TLIReopenCLTSServer: Unable to determine device for %s\n",
659 thistrans->TransName, 0,0 );
663 if( (ciptr=TRANS(TLIReopen)(
664 TLItrans2devtab[i].devcltsname, fd, port)) == NULL )
667 "TLIReopenCLTSServer: Unable to open device for %s\n",
668 thistrans->TransName, 0,0 );
677 #endif /* TRANS_REOPEN */
681 TRANS(TLISetOption)(XtransConnInfo ciptr, int option, int arg)
684 PRMSG(2,"TLISetOption(%d,%d,%d)\n", ciptr->fd, option, arg );
693 TRANS(TLICreateListener)(XtransConnInfo ciptr, struct t_bind *req)
698 PRMSG(2,"TLICreateListener(%x->%d,%x)\n", ciptr, ciptr->fd, req );
700 if( (ret=(struct t_bind *)t_alloc(ciptr->fd,T_BIND,T_ALL)) == NULL )
702 PRMSG(1, "TLICreateListener: failed to allocate a t_bind\n",
704 t_free((char *)req,T_BIND);
705 return TRANS_CREATE_LISTENER_FAILED;
708 if( t_bind(ciptr->fd, req, ret) < 0 )
710 PRMSG(1, "TLICreateListener: t_bind failed\n", 0,0,0 );
711 t_free((char *)req,T_BIND);
712 t_free((char *)ret,T_BIND);
713 return TRANS_CREATE_LISTENER_FAILED;
716 if( memcmp(req->addr.buf,ret->addr.buf,req->addr.len) != 0 )
718 PRMSG(1, "TLICreateListener: unable to bind to %x\n",
720 t_free((char *)req,T_BIND);
721 t_free((char *)ret,T_BIND);
722 return TRANS_ADDR_IN_USE;
726 * Everything looks good: fill in the XtransConnInfo structure.
729 if( (ciptr->addr=(char *)xalloc(ret->addr.len)) == NULL )
732 "TLICreateListener: Unable to allocate space for the address\n",
734 t_free((char *)req,T_BIND);
735 t_free((char *)ret, T_BIND);
736 return TRANS_CREATE_LISTENER_FAILED;
739 ciptr->addrlen=ret->addr.len;
740 memcpy(ciptr->addr,ret->addr.buf,ret->addr.len);
742 t_free((char *)req,T_BIND);
743 t_free((char *)ret, T_BIND);
750 TRANS(TLIINETCreateListener)(XtransConnInfo ciptr, char *port, unsigned int flags)
753 char portbuf[PORTBUFSIZE];
755 struct sockaddr_in *sinaddr;
758 PRMSG(2,"TLIINETCreateListener(%x->%d,%s)\n", ciptr,
759 ciptr->fd, port ? port : "NULL" );
763 * X has a well known port, that is transport dependent. It is easier
764 * to handle it here, than try and come up with a transport independent
765 * representation that can be passed in and resolved the usual way.
767 * The port that is passed here is really a string containing the idisplay
768 * from ConnectDisplay().
771 if (is_numeric (port))
773 tmpport = X_TCP_PORT + strtol (port, (char**)NULL, 10);
774 sprintf(portbuf,"%u", tmpport);
779 if( (req=(struct t_bind *)t_alloc(ciptr->fd,T_BIND,T_ALL)) == NULL )
782 "TLIINETCreateListener: failed to allocate a t_bind\n",
784 return TRANS_CREATE_LISTENER_FAILED;
787 if( port && *port ) {
788 if(TRANS(TLIAddrToNetbuf)(ciptr->index,HOST_SELF,port,&(req->addr)) < 0)
791 "TLIINETCreateListener: can't resolve name:HOST_SELF.%s\n",
793 t_free((char *)req,T_BIND);
794 return TRANS_CREATE_LISTENER_FAILED;
797 sinaddr=(struct sockaddr_in *) req->addr.buf;
798 sinaddr->sin_family=AF_INET;
799 sinaddr->sin_port=htons(0);
800 sinaddr->sin_addr.s_addr=0;
807 return TRANS(TLICreateListener)(ciptr, req);
812 TRANS(TLITLICreateListener)(XtransConnInfo ciptr, char *port, unsigned int flags)
816 struct sockaddr_un *sunaddr;
819 PRMSG(2,"TLITLICreateListener(%x->%d,%s)\n", ciptr, ciptr->fd,
820 port ? port : "NULL");
822 if( (req=(struct t_bind *)t_alloc(ciptr->fd,T_BIND,0)) == NULL )
825 "TLITLICreateListener: failed to allocate a t_bind\n",
827 return TRANS_CREATE_LISTENER_FAILED;
830 if( (sunaddr=(struct sockaddr_un *)
831 malloc(sizeof(struct sockaddr_un))) == NULL )
834 "TLITLICreateListener: failed to allocate a sockaddr_un\n",
836 t_free((char *)req,T_BIND);
837 return TRANS_CREATE_LISTENER_FAILED;
840 sunaddr->sun_family=AF_UNIX;
841 if( port && *port ) {
842 if( *port == '/' ) { /* A full pathname */
843 (void) strcpy(sunaddr->sun_path, port);
845 (void) sprintf(sunaddr->sun_path,"%s%s", TLINODENAME, port );
848 (void) sprintf(sunaddr->sun_path,"%s%d", TLINODENAME, getpid());
851 req->addr.buf=(char *)sunaddr;
852 req->addr.len=sizeof(*sunaddr);
853 req->addr.maxlen=sizeof(*sunaddr);
859 ret_value = TRANS(TLICreateListener)(ciptr, req);
861 free((char *) sunaddr);
867 static XtransConnInfo
868 TRANS(TLIAccept)(XtransConnInfo ciptr, int *status)
872 XtransConnInfo newciptr;
875 PRMSG(2,"TLIAccept(%x->%d)\n", ciptr, ciptr->fd, 0 );
877 if( (call=(struct t_call *)t_alloc(ciptr->fd,T_CALL,T_ALL)) == NULL )
879 PRMSG(1, "TLIAccept() failed to allocate a t_call\n", 0,0,0 );
880 *status = TRANS_ACCEPT_BAD_MALLOC;
884 if( t_listen(ciptr->fd,call) < 0 )
886 extern char *t_errlist[];
888 PRMSG(1, "TLIAccept() t_listen() failed\n", 0,0,0 );
889 PRMSG(1, "TLIAccept: %s\n", t_errlist[t_errno], 0,0 );
890 t_free((char *)call,T_CALL);
891 *status = TRANS_ACCEPT_MISC_ERROR;
896 * Now we need to set up the new endpoint for the incoming connection.
899 i=ciptr->index; /* Makes the next line more readable */
901 if( (newciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcotsname)) == NULL )
903 PRMSG(1, "TLIAccept() failed to open a new endpoint\n", 0,0,0 );
904 t_free((char *)call,T_CALL);
905 *status = TRANS_ACCEPT_MISC_ERROR;
909 if( TRANS(TLITLIBindLocal)(newciptr->fd,TLItrans2devtab[i].family,"") < 0 )
912 "TLIAccept: TRANS(TLITLIBindLocal)() failed: %d\n",
914 t_free((char *)call,T_CALL);
915 t_close(newciptr->fd);
917 *status = TRANS_ACCEPT_MISC_ERROR;
922 if( t_accept(ciptr->fd,newciptr->fd,call) < 0 )
924 extern char *t_errlist[];
926 PRMSG(1, "TLIAccept() t_accept() failed\n", 0,0,0 );
927 PRMSG(1, "TLIAccept: %s\n", t_errlist[t_errno], 0,0 );
928 if( t_errno == TLOOK )
930 int evtype = t_look(ciptr->fd);
931 PRMSG(1, "TLIAccept() t_look() returned %d\n", evtype,0,0 );
935 if( t_rcvdis(ciptr->fd, NULL) < 0 )
937 PRMSG(1, "TLIAccept() t_rcvdis() failed\n", 0,0,0 );
938 PRMSG(1, "TLIAccept: %s\n", t_errlist[t_errno], 0,0 );
945 t_free((char *)call,T_CALL);
946 t_close(newciptr->fd);
948 *status = TRANS_ACCEPT_FAILED;
952 t_free((char *)call,T_CALL);
954 if( TRANS(TLIGetAddr)(newciptr) < 0 )
957 "TLIAccept: TRANS(TLIGetPeerAddr)() failed: %d\n",
959 t_close(newciptr->fd);
961 *status = TRANS_ACCEPT_MISC_ERROR;
965 if( TRANS(TLIGetPeerAddr)(newciptr) < 0 )
968 "TLIAccept: TRANS(TLIGetPeerAddr)() failed: %d\n",
970 t_close(newciptr->fd);
971 xfree(newciptr->addr);
973 *status = TRANS_ACCEPT_MISC_ERROR;
977 if( ioctl(newciptr->fd, I_POP,"timod") < 0 )
979 PRMSG(1, "TLIAccept() ioctl(I_POP, \"timod\") failed %d\n",
981 t_close(newciptr->fd);
982 xfree(newciptr->addr);
984 *status = TRANS_ACCEPT_MISC_ERROR;
988 if( ioctl(newciptr->fd, I_PUSH,"tirdwr") < 0 )
990 PRMSG(1, "TLIAccept() ioctl(I_PUSH,\"tirdwr\") failed %d\n",
992 t_close(newciptr->fd);
993 xfree(newciptr->addr);
995 *status = TRANS_ACCEPT_MISC_ERROR;
1004 #endif /* TRANS_SERVER */
1010 TRANS(TLIConnect)(XtransConnInfo ciptr, struct t_call *sndcall )
1013 PRMSG(2, "TLIConnect(%x->%d,%x)\n", ciptr, ciptr->fd, sndcall);
1015 if( t_connect(ciptr->fd,sndcall,NULL) < 0 )
1017 extern char *t_errlist[];
1019 PRMSG(1, "TLIConnect() t_connect() failed\n", 0,0,0 );
1020 PRMSG(1, "TLIConnect: %s\n", t_errlist[t_errno], 0,0 );
1021 t_free((char *)sndcall,T_CALL);
1022 if (t_errno == TLOOK && t_look(ciptr->fd) == T_DISCONNECT)
1024 t_rcvdis(ciptr->fd,NULL);
1025 return TRANS_TRY_CONNECT_AGAIN;
1028 return TRANS_CONNECT_FAILED;
1031 t_free((char *)sndcall,T_CALL);
1034 * Sync up the address fields of ciptr.
1037 if( TRANS(TLIGetAddr)(ciptr) < 0 )
1040 "TLIConnect: ...TLIGetAddr() failed: %d\n",
1042 return TRANS_CONNECT_FAILED;
1045 if( TRANS(TLIGetPeerAddr)(ciptr) < 0 )
1048 "TLIConnect: ...TLIGetPeerAddr() failed: %d\n",
1050 return TRANS_CONNECT_FAILED;
1053 if( ioctl(ciptr->fd, I_POP,"timod") < 0 )
1055 PRMSG(1, "TLIConnect() ioctl(I_POP,\"timod\") failed %d\n",
1057 return TRANS_CONNECT_FAILED;
1060 if( ioctl(ciptr->fd, I_PUSH,"tirdwr") < 0 )
1062 PRMSG(1, "TLIConnect() ioctl(I_PUSH,\"tirdwr\") failed %d\n",
1064 return TRANS_CONNECT_FAILED;
1072 TRANS(TLIINETConnect)(XtransConnInfo ciptr, char *host, char *port)
1075 char portbuf[PORTBUFSIZE];
1076 struct t_call *sndcall;
1079 PRMSG(2, "TLIINETConnect(%s,%s)\n", host, port, 0);
1083 * X has a well known port, that is transport dependant. It is easier
1084 * to handle it here, than try and come up with a transport independent
1085 * representation that can be passed in and resolved the usual way.
1087 * The port that is passed here is really a string containing the idisplay
1088 * from ConnectDisplay().
1091 if (is_numeric (port))
1093 tmpport = X_TCP_PORT + strtol (port, (char**)NULL, 10);
1094 sprintf(portbuf,"%u", tmpport );
1099 if( (sndcall=(struct t_call *)t_alloc(ciptr->fd,T_CALL,T_ALL)) == NULL )
1101 PRMSG(1, "TLIINETConnect() failed to allocate a t_call\n", 0,0,0 );
1102 return TRANS_CONNECT_FAILED;
1105 if( TRANS(TLIAddrToNetbuf)(ciptr->index, host, port, &(sndcall->addr) ) < 0 )
1107 PRMSG(1, "TLIINETConnect() unable to resolve name:%s.%s\n",
1109 t_free((char *)sndcall,T_CALL);
1110 return TRANS_CONNECT_FAILED;
1113 return TRANS(TLIConnect)(ciptr, sndcall );
1118 TRANS(TLITLIConnect)(XtransConnInfo ciptr, char *host, char *port)
1121 struct t_call *sndcall;
1122 struct sockaddr_un *sunaddr;
1125 PRMSG(2, "TLITLIConnect(%s,%s)\n", host, port, 0);
1127 if( (sndcall=(struct t_call *)t_alloc(ciptr->fd,T_CALL,T_OPT|T_UDATA)) == NULL )
1129 PRMSG(1, "TLITLIConnect() failed to allocate a t_call\n", 0,0,0 );
1130 return TRANS_CONNECT_FAILED;
1133 if( (sunaddr=(struct sockaddr_un *)
1134 malloc(sizeof(struct sockaddr_un))) == NULL )
1137 "TLITLIConnect: failed to allocate a sockaddr_un\n",
1139 t_free((char *)sndcall,T_CALL);
1140 return TRANS_CONNECT_FAILED;
1143 sunaddr->sun_family=AF_UNIX;
1145 strncmp (port, TLINODENAME, strlen (TLINODENAME)) == 0) {
1146 /* Use the port as is */
1147 (void) strcpy(sunaddr->sun_path, port);
1149 (void) sprintf(sunaddr->sun_path,"%s%s", TLINODENAME, port );
1152 sndcall->addr.buf=(char *)sunaddr;
1153 sndcall->addr.len=sizeof(*sunaddr);
1154 sndcall->addr.maxlen=sizeof(*sunaddr);
1156 ret_value = TRANS(TLIConnect)(ciptr, sndcall );
1158 free((char *) sunaddr);
1163 #endif /* TRANS_CLIENT */
1167 TRANS(TLIBytesReadable)(XtransConnInfo ciptr, BytesReadable_t *pend)
1171 struct pollfd filedes;
1173 PRMSG(2, "TLIByteReadable(%x->%d,%x)\n", ciptr, ciptr->fd, pend );
1176 * This function should detect hangup conditions. Use poll to check
1177 * if no data is present. On SVR4, the M_HANGUP message sits on the
1178 * streams head, and ioctl(N_READ) keeps returning 0 because there is
1179 * no data available. The hangup goes undetected, and the client hangs.
1182 ret=ioctl(ciptr->fd, I_NREAD, (char *)pend);
1185 return ret; /* Data present or error */
1188 /* Zero data, or POLLHUP message */
1190 filedes.fd=ciptr->fd;
1191 filedes.events=POLLIN;
1193 ret=poll(&filedes, 1, 0);
1197 return 0; /* Really, no data */
1201 return -1; /* just pass back the error */
1203 if( filedes.revents & (POLLHUP|POLLERR) ) /* check for hangup */
1206 /* Should only get here if data arrived after the first ioctl() */
1207 return ioctl(ciptr->fd, I_NREAD, (char *)pend);
1212 TRANS(TLIRead)(XtransConnInfo ciptr, char *buf, int size)
1215 PRMSG(2, "TLIRead(%d,%x,%d)\n", ciptr->fd, buf, size );
1217 return read(ciptr->fd,buf,size);
1222 TRANS(TLIWrite)(XtransConnInfo ciptr, char *buf, int size)
1225 PRMSG(2, "TLIWrite(%d,%x,%d)\n", ciptr->fd, buf, size );
1227 return write(ciptr->fd,buf,size);
1232 TRANS(TLIReadv)(XtransConnInfo ciptr, struct iovec *buf, int size)
1235 PRMSG(2, "TLIReadv(%d,%x,%d)\n", ciptr->fd, buf, size );
1237 return READV(ciptr,buf,size);
1242 TRANS(TLIWritev)(XtransConnInfo ciptr, struct iovec *buf, int size)
1245 PRMSG(2, "TLIWritev(%d,%x,%d)\n", ciptr->fd, buf, size );
1247 return WRITEV(ciptr,buf,size);
1252 TRANS(TLIDisconnect)(XtransConnInfo ciptr)
1255 PRMSG(2, "TLIDisconnect(%x->%d)\n", ciptr, ciptr->fd, 0 );
1258 * Restore the TLI modules so that the connection can be properly shutdown.
1259 * This avoids the situation where a connection goes into the TIME_WAIT
1260 * state, and the address remains unavailable for a while.
1262 ioctl(ciptr->fd, I_POP,"tirdwr");
1263 ioctl(ciptr->fd, I_PUSH,"timod");
1265 t_snddis(ciptr->fd,NULL);
1272 TRANS(TLIClose)(XtransConnInfo ciptr)
1275 PRMSG(2, "TLIClose(%x->%d)\n", ciptr, ciptr->fd, 0 );
1277 t_unbind(ciptr->fd);
1279 return (t_close(ciptr->fd));
1284 TRANS(TLICloseForCloning)(XtransConnInfo ciptr)
1291 PRMSG(2, "TLICloseForCloning(%x->%d)\n", ciptr, ciptr->fd, 0 );
1293 return (t_close(ciptr->fd));
1297 Xtransport TRANS(TLITCPFuncs) = {
1302 TRANS(TLIOpenCOTSClient),
1303 #endif /* TRANS_CLIENT */
1306 TRANS(TLIOpenCOTSServer),
1307 #endif /* TRANS_SERVER */
1309 TRANS(TLIOpenCLTSClient),
1310 #endif /* TRANS_CLIENT */
1312 TRANS(TLIOpenCLTSServer),
1313 #endif /* TRANS_SERVER */
1315 TRANS(TLIReopenCOTSServer),
1316 TRANS(TLIReopenCLTSServer),
1318 TRANS(TLISetOption),
1320 TRANS(TLIINETCreateListener),
1321 NULL, /* ResetListener */
1323 #endif /* TRANS_SERVER */
1325 TRANS(TLIINETConnect),
1326 #endif /* TRANS_CLIENT */
1327 TRANS(TLIBytesReadable),
1332 TRANS(TLIDisconnect),
1334 TRANS(TLICloseForCloning),
1338 static char * inet_aliases[] = { "tcp", NULL };
1340 Xtransport TRANS(TLIINETFuncs) = {
1345 TRANS(TLIOpenCOTSClient),
1346 #endif /* TRANS_CLIENT */
1349 TRANS(TLIOpenCOTSServer),
1350 #endif /* TRANS_SERVER */
1352 TRANS(TLIOpenCLTSClient),
1353 #endif /* TRANS_CLIENT */
1355 TRANS(TLIOpenCLTSServer),
1356 #endif /* TRANS_SERVER */
1358 TRANS(TLIReopenCOTSServer),
1359 TRANS(TLIReopenCLTSServer),
1361 TRANS(TLISetOption),
1363 TRANS(TLIINETCreateListener),
1364 NULL, /* ResetListener */
1366 #endif /* TRANS_SERVER */
1368 TRANS(TLIINETConnect),
1369 #endif /* TRANS_CLIENT */
1370 TRANS(TLIBytesReadable),
1375 TRANS(TLIDisconnect),
1377 TRANS(TLICloseForCloning),
1380 Xtransport TRANS(TLITLIFuncs) = {
1385 TRANS(TLIOpenCOTSClient),
1386 #endif /* TRANS_CLIENT */
1389 TRANS(TLIOpenCOTSServer),
1390 #endif /* TRANS_SERVER */
1392 TRANS(TLIOpenCLTSClient),
1393 #endif /* TRANS_CLIENT */
1395 TRANS(TLIOpenCLTSServer),
1396 #endif /* TRANS_SERVER */
1398 TRANS(TLIReopenCOTSServer),
1399 TRANS(TLIReopenCLTSServer),
1401 TRANS(TLISetOption),
1403 TRANS(TLITLICreateListener),
1404 NULL, /* ResetListener */
1406 #endif /* TRANS_SERVER */
1408 TRANS(TLITLIConnect),
1409 #endif /* TRANS_CLIENT */
1410 TRANS(TLIBytesReadable),
1415 TRANS(TLIDisconnect),
1417 TRANS(TLICloseForCloning),