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);
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);
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);
166 * Everything looks good: fill in the XtransConnInfo structure.
172 if( (ciptr->addr = malloc(netbuf.len)) == NULL )
174 prmsg(1, "TLIGetAddr: Can't allocate space for the addr\n");
178 ciptr->family=((struct sockaddr *) &sockname)->sa_family;
179 ciptr->addrlen=netbuf.len;
180 memcpy(ciptr->addr,&sockname,ciptr->addrlen);
187 * This function gets the remote address of the socket and stores it in the
188 * XtransConnInfo structure for the connection.
192 TRANS(TLIGetPeerAddr)(XtransConnInfo ciptr)
196 struct netbuf netbuf;
198 prmsg(3,"TLIGetPeerAddr(%x)\n", ciptr);
200 netbuf.buf=(char *)&sockname;
201 netbuf.len=sizeof(sockname);
202 netbuf.maxlen=sizeof(sockname);
204 if( t_getname(ciptr->fd,&netbuf,REMOTENAME) < 0 )
206 prmsg(1,"TLIGetPeerAddr: t_getname(REMOTENAME) failed: %d\n",
211 prmsg(4,"TLIGetPeerAddr: got family %d len %d\n",
212 ((struct sockaddr *) &sockname)->sa_family ,netbuf.len);
215 * Everything looks good: fill in the XtransConnInfo structure.
218 if( ciptr->peeraddr )
219 free(ciptr->peeraddr);
221 if( (ciptr->peeraddr = malloc(netbuf.len)) == NULL )
224 "TLIGetPeerAddr: Can't allocate space for the addr\n");
228 ciptr->peeraddrlen=netbuf.len;
229 memcpy(ciptr->peeraddr,&sockname,ciptr->peeraddrlen);
236 * This function will establish a local name for the transport. This function
237 * do extra work for the local tli connection. It must create a sockaddr_un
238 * format address so that it will look like an AF_UNIX connection to the
241 * This function will only be called by the OPENC?TSClient() functions since
242 * the local address is set up in the CreateListner() for the server ends.
246 TRANS(TLITLIBindLocal)(int fd, int family, char *port)
249 struct sockaddr_un *sunaddr=NULL;
250 struct t_bind *req=NULL;
252 prmsg(2, "TLITLIBindLocal(%d,%d,%s)\n", fd, family, port);
254 if( family == AF_UNIX )
256 if( (req=(struct t_bind *)t_alloc(fd,T_BIND,0)) == NULL )
259 "TLITLIBindLocal() failed to allocate a t_bind\n");
263 if( (sunaddr=(struct sockaddr_un *)
264 malloc(sizeof(struct sockaddr_un))) == NULL )
267 "TLITLIBindLocal: failed to allocate a sockaddr_un\n");
268 t_free((char *)req,T_BIND);
272 sunaddr->sun_family=AF_UNIX;
275 if( *port == '/' ) { /* A full pathname */
276 (void) strcpy(sunaddr->sun_path, port);
278 (void) sprintf(sunaddr->sun_path,"%s%s", TLINODENAME, port );
282 (void) sprintf(sunaddr->sun_path,"%s%d",
283 TLINODENAME, getpid()^time(NULL) );
285 prmsg(4, "TLITLIBindLocal: binding to %s\n",
288 req->addr.buf=(char *)sunaddr;
289 req->addr.len=sizeof(*sunaddr);
290 req->addr.maxlen=sizeof(*sunaddr);
293 if( t_bind(fd, req, NULL) < 0 )
296 "TLIBindLocal: Unable to bind TLI device to %s\n",
299 free((char *) sunaddr);
301 t_free((char *)req,T_BIND);
307 static XtransConnInfo
308 TRANS(TLIOpen)(char *device)
311 XtransConnInfo ciptr;
313 prmsg(3,"TLIOpen(%s)\n", device);
315 if( (ciptr = calloc(1,sizeof(struct _XtransConnInfo))) == NULL )
317 prmsg(1, "TLIOpen: calloc failed\n");
321 if( (ciptr->fd=t_open( device, O_RDWR, NULL )) < 0 )
323 prmsg(1, "TLIOpen: t_open failed for %s\n", device);
334 static XtransConnInfo
335 TRANS(TLIReopen)(char *device, int fd, char *port)
338 XtransConnInfo ciptr;
340 prmsg(3,"TLIReopen(%s,%d, %s)\n", device, fd, port );
344 prmsg(1, "TLIReopen: t_sync failed\n");
348 if( (ciptr = calloc(1,sizeof(struct _XtransConnInfo))) == NULL )
350 prmsg(1, "TLIReopen: calloc failed\n");
359 #endif /* TRANS_REOPEN */
363 TRANS(TLIAddrToNetbuf)(int tlifamily, char *host, char *port,
364 struct netbuf *netbufp)
367 struct netconfig *netconfigp;
368 struct nd_hostserv nd_hostserv;
369 struct nd_addrlist *nd_addrlistp = NULL;
373 prmsg(3,"TLIAddrToNetbuf(%d,%s,%s)\n", tlifamily, host, port );
375 if( (handlep=setnetconfig()) == NULL )
378 lport = strtol (port, (char**)NULL, 10);
379 if (lport < 1024 || lport > USHRT_MAX)
382 nd_hostserv.h_host = host;
383 if( port && *port ) {
384 nd_hostserv.h_serv = port;
386 nd_hostserv.h_serv = NULL;
389 while( (netconfigp=getnetconfig(handlep)) != NULL )
391 if( strcmp(netconfigp->nc_protofmly,
392 TLItrans2devtab[tlifamily].protofamily) != 0 )
394 prmsg(5,"TLIAddrToNetbuf: Trying to resolve %s.%s for %s\n",
395 host, port, TLItrans2devtab[tlifamily].protofamily );
396 if( netdir_getbyname(netconfigp,&nd_hostserv, &nd_addrlistp) == 0 )
398 /* we have at least one address to use */
400 prmsg(5, "TLIAddrToNetbuf: found address for %s.%s\n", host, port);
401 prmsg(5, "TLIAddrToNetbuf: %s\n",taddr2uaddr(netconfigp,nd_addrlistp->n_addrs));
403 memcpy(netbufp->buf,nd_addrlistp->n_addrs->buf,
404 nd_addrlistp->n_addrs->len);
405 netbufp->len=nd_addrlistp->n_addrs->len;
406 endnetconfig(handlep);
410 endnetconfig(handlep);
416 * These functions are the interface supplied in the Xtransport structure
421 static XtransConnInfo
422 TRANS(TLIOpenCOTSClient)(Xtransport *thistrans, char *protocol,
423 char *host, char *port)
426 XtransConnInfo ciptr;
429 prmsg(2,"TLIOpenCOTSClient(%s,%s,%s)\n", protocol, host, port );
431 if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
433 prmsg(1,"TLIOpenCOTSClient: Unable to determine device for %s\n",
434 thistrans->TransName);
438 if( (ciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcotsname)) == NULL )
440 prmsg(1,"TLIOpenCOTSClient: Unable to open device for %s\n",
441 thistrans->TransName);
445 if( TRANS(TLITLIBindLocal)(ciptr->fd,TLItrans2devtab[i].family,port) < 0 )
448 "TLIOpenCOTSClient: ...TLITLIBindLocal() failed: %d\n",
455 if( TRANS(TLIGetAddr)(ciptr) < 0 )
458 "TLIOpenCOTSClient: ...TLIGetAddr() failed: %d\n",
465 /* Save the TLIFamily for later use in TLIAddrToNetbuf() lookups */
471 #endif /* TRANS_CLIENT */
476 static XtransConnInfo
477 TRANS(TLIOpenCOTSServer)(Xtransport *thistrans, char *protocol,
478 char *host, char *port)
481 XtransConnInfo ciptr;
484 prmsg(2,"TLIOpenCOTSServer(%s,%s,%s)\n", protocol, host, port );
486 if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
489 "TLIOpenCOTSServer: Unable to determine device for %s\n",
490 thistrans->TransName);
494 if( (ciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcotsname)) == NULL )
497 "TLIOpenCOTSServer: Unable to open device for %s\n",
498 thistrans->TransName);
502 /* Set the family type */
504 ciptr->family = TLItrans2devtab[i].family;
507 /* Save the TLIFamily for later use in TLIAddrToNetbuf() lookups */
514 #endif /* TRANS_SERVER */
519 static XtransConnInfo
520 TRANS(TLIOpenCLTSClient)(Xtransport *thistrans, char *protocol,
521 char *host, char *port)
524 XtransConnInfo ciptr;
527 prmsg(2,"TLIOpenCLTSClient(%s,%s,%s)\n", protocol, host, port );
529 if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
532 "TLIOpenCLTSClient: Unable to determine device for %s\n",
533 thistrans->TransName);
537 if( (ciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcltsname)) == NULL )
540 "TLIOpenCLTSClient: Unable to open device for %s\n",
541 thistrans->TransName);
545 if( TRANS(TLITLIBindLocal)(ciptr->fd,TLItrans2devtab[i].family,port) < 0 )
548 "TLIOpenCLTSClient: ...TLITLIBindLocal() failed: %d\n",
555 if( TRANS(TLIGetAddr)(ciptr) < 0 )
558 "TLIOpenCLTSClient: ...TLIGetPeerAddr() failed: %d\n",
568 #endif /* TRANS_CLIENT */
573 static XtransConnInfo
574 TRANS(TLIOpenCLTSServer)(Xtransport *thistrans, char *protocol,
575 char *host, char *port)
578 XtransConnInfo ciptr;
581 prmsg(2,"TLIOpenCLTSServer(%s,%s,%s)\n", protocol, host, port );
583 if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
586 "TLIOpenCLTSServer: Unable to determine device for %s\n",
587 thistrans->TransName);
591 if( (ciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcltsname)) == NULL )
594 "TLIOpenCLTSServer: Unable to open device for %s\n",
595 thistrans->TransName);
602 #endif /* TRANS_SERVER */
607 static XtransConnInfo
608 TRANS(TLIReopenCOTSServer)(Xtransport *thistrans, int fd, char *port)
611 XtransConnInfo ciptr;
614 prmsg(2,"TLIReopenCOTSServer(%d, %s)\n", fd, port);
616 if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
619 "TLIReopenCOTSServer: Unable to determine device for %s\n",
620 thistrans->TransName);
624 if( (ciptr=TRANS(TLIReopen)(
625 TLItrans2devtab[i].devcotsname, fd, port)) == NULL )
628 "TLIReopenCOTSServer: Unable to open device for %s\n",
629 thistrans->TransName);
633 /* Save the TLIFamily for later use in TLIAddrToNetbuf() lookups */
641 static XtransConnInfo
642 TRANS(TLIReopenCLTSServer)(Xtransport *thistrans, int fd, char *port)
645 XtransConnInfo ciptr;
648 prmsg(2,"TLIReopenCLTSServer(%d, %s)\n", fd, port);
650 if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
653 "TLIReopenCLTSServer: Unable to determine device for %s\n",
654 thistrans->TransName);
658 if( (ciptr=TRANS(TLIReopen)(
659 TLItrans2devtab[i].devcltsname, fd, port)) == NULL )
662 "TLIReopenCLTSServer: Unable to open device for %s\n",
663 thistrans->TransName);
672 #endif /* TRANS_REOPEN */
676 TRANS(TLISetOption)(XtransConnInfo ciptr, int option, int arg)
679 prmsg(2,"TLISetOption(%d,%d,%d)\n", ciptr->fd, option, arg );
688 TRANS(TLICreateListener)(XtransConnInfo ciptr, struct t_bind *req)
693 prmsg(2,"TLICreateListener(%x->%d,%x)\n", ciptr, ciptr->fd, req );
695 if( (ret=(struct t_bind *)t_alloc(ciptr->fd,T_BIND,T_ALL)) == NULL )
697 prmsg(1, "TLICreateListener: failed to allocate a t_bind\n");
698 t_free((char *)req,T_BIND);
699 return TRANS_CREATE_LISTENER_FAILED;
702 if( t_bind(ciptr->fd, req, ret) < 0 )
704 prmsg(1, "TLICreateListener: t_bind failed\n");
705 t_free((char *)req,T_BIND);
706 t_free((char *)ret,T_BIND);
707 return TRANS_CREATE_LISTENER_FAILED;
710 if( memcmp(req->addr.buf,ret->addr.buf,req->addr.len) != 0 )
712 prmsg(1, "TLICreateListener: unable to bind to %x\n",
714 t_free((char *)req,T_BIND);
715 t_free((char *)ret,T_BIND);
716 return TRANS_ADDR_IN_USE;
720 * Everything looks good: fill in the XtransConnInfo structure.
723 if( (ciptr->addr = malloc(ret->addr.len)) == NULL )
726 "TLICreateListener: Unable to allocate space for the address\n");
727 t_free((char *)req,T_BIND);
728 t_free((char *)ret, T_BIND);
729 return TRANS_CREATE_LISTENER_FAILED;
732 ciptr->addrlen=ret->addr.len;
733 memcpy(ciptr->addr,ret->addr.buf,ret->addr.len);
735 t_free((char *)req,T_BIND);
736 t_free((char *)ret, T_BIND);
743 TRANS(TLIINETCreateListener)(XtransConnInfo ciptr, char *port, unsigned int flags)
746 char portbuf[PORTBUFSIZE];
748 struct sockaddr_in *sinaddr;
751 prmsg(2,"TLIINETCreateListener(%x->%d,%s)\n", ciptr,
752 ciptr->fd, port ? port : "NULL" );
756 * X has a well known port, that is transport dependent. It is easier
757 * to handle it here, than try and come up with a transport independent
758 * representation that can be passed in and resolved the usual way.
760 * The port that is passed here is really a string containing the idisplay
761 * from ConnectDisplay().
764 if (is_numeric (port))
766 tmpport = X_TCP_PORT + strtol (port, (char**)NULL, 10);
767 sprintf(portbuf,"%u", tmpport);
772 if( (req=(struct t_bind *)t_alloc(ciptr->fd,T_BIND,T_ALL)) == NULL )
775 "TLIINETCreateListener: failed to allocate a t_bind\n");
776 return TRANS_CREATE_LISTENER_FAILED;
779 if( port && *port ) {
780 if(TRANS(TLIAddrToNetbuf)(ciptr->index,HOST_SELF,port,&(req->addr)) < 0)
783 "TLIINETCreateListener: can't resolve name:HOST_SELF.%s\n",
785 t_free((char *)req,T_BIND);
786 return TRANS_CREATE_LISTENER_FAILED;
789 sinaddr=(struct sockaddr_in *) req->addr.buf;
790 sinaddr->sin_family=AF_INET;
791 sinaddr->sin_port=htons(0);
792 sinaddr->sin_addr.s_addr=0;
799 return TRANS(TLICreateListener)(ciptr, req);
804 TRANS(TLITLICreateListener)(XtransConnInfo ciptr, char *port, unsigned int flags)
808 struct sockaddr_un *sunaddr;
811 prmsg(2,"TLITLICreateListener(%x->%d,%s)\n", ciptr, ciptr->fd,
812 port ? port : "NULL");
814 if( (req=(struct t_bind *)t_alloc(ciptr->fd,T_BIND,0)) == NULL )
817 "TLITLICreateListener: failed to allocate a t_bind\n");
818 return TRANS_CREATE_LISTENER_FAILED;
821 if( (sunaddr=(struct sockaddr_un *)
822 malloc(sizeof(struct sockaddr_un))) == NULL )
825 "TLITLICreateListener: failed to allocate a sockaddr_un\n");
826 t_free((char *)req,T_BIND);
827 return TRANS_CREATE_LISTENER_FAILED;
830 sunaddr->sun_family=AF_UNIX;
831 if( port && *port ) {
832 if( *port == '/' ) { /* A full pathname */
833 (void) strcpy(sunaddr->sun_path, port);
835 (void) sprintf(sunaddr->sun_path,"%s%s", TLINODENAME, port );
838 (void) sprintf(sunaddr->sun_path,"%s%d", TLINODENAME, getpid());
841 req->addr.buf=(char *)sunaddr;
842 req->addr.len=sizeof(*sunaddr);
843 req->addr.maxlen=sizeof(*sunaddr);
849 ret_value = TRANS(TLICreateListener)(ciptr, req);
851 free((char *) sunaddr);
857 static XtransConnInfo
858 TRANS(TLIAccept)(XtransConnInfo ciptr, int *status)
862 XtransConnInfo newciptr;
865 prmsg(2,"TLIAccept(%x->%d)\n", ciptr, ciptr->fd);
867 if( (call=(struct t_call *)t_alloc(ciptr->fd,T_CALL,T_ALL)) == NULL )
869 prmsg(1, "TLIAccept() failed to allocate a t_call\n");
870 *status = TRANS_ACCEPT_BAD_MALLOC;
874 if( t_listen(ciptr->fd,call) < 0 )
876 extern char *t_errlist[];
878 prmsg(1, "TLIAccept() t_listen() failed\n");
879 prmsg(1, "TLIAccept: %s\n", t_errlist[t_errno]);
880 t_free((char *)call,T_CALL);
881 *status = TRANS_ACCEPT_MISC_ERROR;
886 * Now we need to set up the new endpoint for the incoming connection.
889 i=ciptr->index; /* Makes the next line more readable */
891 if( (newciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcotsname)) == NULL )
893 prmsg(1, "TLIAccept() failed to open a new endpoint\n");
894 t_free((char *)call,T_CALL);
895 *status = TRANS_ACCEPT_MISC_ERROR;
899 if( TRANS(TLITLIBindLocal)(newciptr->fd,TLItrans2devtab[i].family,"") < 0 )
902 "TLIAccept: TRANS(TLITLIBindLocal)() failed: %d\n",
904 t_free((char *)call,T_CALL);
905 t_close(newciptr->fd);
907 *status = TRANS_ACCEPT_MISC_ERROR;
912 if( t_accept(ciptr->fd,newciptr->fd,call) < 0 )
914 extern char *t_errlist[];
916 prmsg(1, "TLIAccept() t_accept() failed\n");
917 prmsg(1, "TLIAccept: %s\n", t_errlist[t_errno]);
918 if( t_errno == TLOOK )
920 int evtype = t_look(ciptr->fd);
921 prmsg(1, "TLIAccept() t_look() returned %d\n", evtype);
925 if( t_rcvdis(ciptr->fd, NULL) < 0 )
927 prmsg(1, "TLIAccept() t_rcvdis() failed\n");
928 prmsg(1, "TLIAccept: %s\n", t_errlist[t_errno]);
935 t_free((char *)call,T_CALL);
936 t_close(newciptr->fd);
938 *status = TRANS_ACCEPT_FAILED;
942 t_free((char *)call,T_CALL);
944 if( TRANS(TLIGetAddr)(newciptr) < 0 )
947 "TLIAccept: TRANS(TLIGetPeerAddr)() failed: %d\n",
949 t_close(newciptr->fd);
951 *status = TRANS_ACCEPT_MISC_ERROR;
955 if( TRANS(TLIGetPeerAddr)(newciptr) < 0 )
958 "TLIAccept: TRANS(TLIGetPeerAddr)() failed: %d\n",
960 t_close(newciptr->fd);
961 free(newciptr->addr);
963 *status = TRANS_ACCEPT_MISC_ERROR;
967 if( ioctl(newciptr->fd, I_POP,"timod") < 0 )
969 prmsg(1, "TLIAccept() ioctl(I_POP, \"timod\") failed %d\n",
971 t_close(newciptr->fd);
972 free(newciptr->addr);
974 *status = TRANS_ACCEPT_MISC_ERROR;
978 if( ioctl(newciptr->fd, I_PUSH,"tirdwr") < 0 )
980 prmsg(1, "TLIAccept() ioctl(I_PUSH,\"tirdwr\") failed %d\n",
982 t_close(newciptr->fd);
983 free(newciptr->addr);
985 *status = TRANS_ACCEPT_MISC_ERROR;
994 #endif /* TRANS_SERVER */
1000 TRANS(TLIConnect)(XtransConnInfo ciptr, struct t_call *sndcall )
1003 prmsg(2, "TLIConnect(%x->%d,%x)\n", ciptr, ciptr->fd, sndcall);
1005 if( t_connect(ciptr->fd,sndcall,NULL) < 0 )
1007 extern char *t_errlist[];
1009 prmsg(1, "TLIConnect() t_connect() failed\n");
1010 prmsg(1, "TLIConnect: %s\n", t_errlist[t_errno]);
1011 t_free((char *)sndcall,T_CALL);
1012 if (t_errno == TLOOK && t_look(ciptr->fd) == T_DISCONNECT)
1014 t_rcvdis(ciptr->fd,NULL);
1015 return TRANS_TRY_CONNECT_AGAIN;
1018 return TRANS_CONNECT_FAILED;
1021 t_free((char *)sndcall,T_CALL);
1024 * Sync up the address fields of ciptr.
1027 if( TRANS(TLIGetAddr)(ciptr) < 0 )
1030 "TLIConnect: ...TLIGetAddr() failed: %d\n",
1032 return TRANS_CONNECT_FAILED;
1035 if( TRANS(TLIGetPeerAddr)(ciptr) < 0 )
1038 "TLIConnect: ...TLIGetPeerAddr() failed: %d\n",
1040 return TRANS_CONNECT_FAILED;
1043 if( ioctl(ciptr->fd, I_POP,"timod") < 0 )
1045 prmsg(1, "TLIConnect() ioctl(I_POP,\"timod\") failed %d\n",
1047 return TRANS_CONNECT_FAILED;
1050 if( ioctl(ciptr->fd, I_PUSH,"tirdwr") < 0 )
1052 prmsg(1, "TLIConnect() ioctl(I_PUSH,\"tirdwr\") failed %d\n",
1054 return TRANS_CONNECT_FAILED;
1062 TRANS(TLIINETConnect)(XtransConnInfo ciptr, char *host, char *port)
1065 char portbuf[PORTBUFSIZE];
1066 struct t_call *sndcall;
1069 prmsg(2, "TLIINETConnect(%s,%s)\n", host, port);
1073 * X has a well known port, that is transport dependant. It is easier
1074 * to handle it here, than try and come up with a transport independent
1075 * representation that can be passed in and resolved the usual way.
1077 * The port that is passed here is really a string containing the idisplay
1078 * from ConnectDisplay().
1081 if (is_numeric (port))
1083 tmpport = X_TCP_PORT + strtol (port, (char**)NULL, 10);
1084 sprintf(portbuf,"%u", tmpport );
1089 if( (sndcall=(struct t_call *)t_alloc(ciptr->fd,T_CALL,T_ALL)) == NULL )
1091 prmsg(1, "TLIINETConnect() failed to allocate a t_call\n");
1092 return TRANS_CONNECT_FAILED;
1095 if( TRANS(TLIAddrToNetbuf)(ciptr->index, host, port, &(sndcall->addr) ) < 0 )
1097 prmsg(1, "TLIINETConnect() unable to resolve name:%s.%s\n",
1099 t_free((char *)sndcall,T_CALL);
1100 return TRANS_CONNECT_FAILED;
1103 return TRANS(TLIConnect)(ciptr, sndcall );
1108 TRANS(TLITLIConnect)(XtransConnInfo ciptr, char *host, char *port)
1111 struct t_call *sndcall;
1112 struct sockaddr_un *sunaddr;
1115 prmsg(2, "TLITLIConnect(%s,%s)\n", host, port);
1117 if( (sndcall=(struct t_call *)t_alloc(ciptr->fd,T_CALL,T_OPT|T_UDATA)) == NULL )
1119 prmsg(1, "TLITLIConnect() failed to allocate a t_call\n");
1120 return TRANS_CONNECT_FAILED;
1123 if( (sunaddr=(struct sockaddr_un *)
1124 malloc(sizeof(struct sockaddr_un))) == NULL )
1127 "TLITLIConnect: failed to allocate a sockaddr_un\n");
1128 t_free((char *)sndcall,T_CALL);
1129 return TRANS_CONNECT_FAILED;
1132 sunaddr->sun_family=AF_UNIX;
1134 strncmp (port, TLINODENAME, strlen (TLINODENAME)) == 0) {
1135 /* Use the port as is */
1136 (void) strcpy(sunaddr->sun_path, port);
1138 (void) sprintf(sunaddr->sun_path,"%s%s", TLINODENAME, port );
1141 sndcall->addr.buf=(char *)sunaddr;
1142 sndcall->addr.len=sizeof(*sunaddr);
1143 sndcall->addr.maxlen=sizeof(*sunaddr);
1145 ret_value = TRANS(TLIConnect)(ciptr, sndcall );
1147 free((char *) sunaddr);
1152 #endif /* TRANS_CLIENT */
1156 TRANS(TLIBytesReadable)(XtransConnInfo ciptr, BytesReadable_t *pend)
1160 struct pollfd filedes;
1162 prmsg(2, "TLIByteReadable(%x->%d,%x)\n", ciptr, ciptr->fd, pend );
1165 * This function should detect hangup conditions. Use poll to check
1166 * if no data is present. On SVR4, the M_HANGUP message sits on the
1167 * streams head, and ioctl(N_READ) keeps returning 0 because there is
1168 * no data available. The hangup goes undetected, and the client hangs.
1171 ret=ioctl(ciptr->fd, I_NREAD, (char *)pend);
1174 return ret; /* Data present or error */
1177 /* Zero data, or POLLHUP message */
1179 filedes.fd=ciptr->fd;
1180 filedes.events=POLLIN;
1182 ret=poll(&filedes, 1, 0);
1186 return 0; /* Really, no data */
1190 return -1; /* just pass back the error */
1192 if( filedes.revents & (POLLHUP|POLLERR) ) /* check for hangup */
1195 /* Should only get here if data arrived after the first ioctl() */
1196 return ioctl(ciptr->fd, I_NREAD, (char *)pend);
1201 TRANS(TLIRead)(XtransConnInfo ciptr, char *buf, int size)
1204 prmsg(2, "TLIRead(%d,%x,%d)\n", ciptr->fd, buf, size );
1206 return read(ciptr->fd,buf,size);
1211 TRANS(TLIWrite)(XtransConnInfo ciptr, char *buf, int size)
1214 prmsg(2, "TLIWrite(%d,%x,%d)\n", ciptr->fd, buf, size );
1216 return write(ciptr->fd,buf,size);
1221 TRANS(TLIReadv)(XtransConnInfo ciptr, struct iovec *buf, int size)
1224 prmsg(2, "TLIReadv(%d,%x,%d)\n", ciptr->fd, buf, size );
1226 return READV(ciptr,buf,size);
1231 TRANS(TLIWritev)(XtransConnInfo ciptr, struct iovec *buf, int size)
1234 prmsg(2, "TLIWritev(%d,%x,%d)\n", ciptr->fd, buf, size );
1236 return WRITEV(ciptr,buf,size);
1241 TRANS(TLIDisconnect)(XtransConnInfo ciptr)
1244 prmsg(2, "TLIDisconnect(%x->%d)\n", ciptr, ciptr->fd);
1247 * Restore the TLI modules so that the connection can be properly shutdown.
1248 * This avoids the situation where a connection goes into the TIME_WAIT
1249 * state, and the address remains unavailable for a while.
1251 ioctl(ciptr->fd, I_POP,"tirdwr");
1252 ioctl(ciptr->fd, I_PUSH,"timod");
1254 t_snddis(ciptr->fd,NULL);
1261 TRANS(TLIClose)(XtransConnInfo ciptr)
1264 prmsg(2, "TLIClose(%x->%d)\n", ciptr, ciptr->fd);
1266 t_unbind(ciptr->fd);
1268 return (t_close(ciptr->fd));
1273 TRANS(TLICloseForCloning)(XtransConnInfo ciptr)
1280 prmsg(2, "TLICloseForCloning(%x->%d)\n", ciptr, ciptr->fd);
1282 return (t_close(ciptr->fd));
1286 Xtransport TRANS(TLITCPFuncs) = {
1291 TRANS(TLIOpenCOTSClient),
1292 #endif /* TRANS_CLIENT */
1295 TRANS(TLIOpenCOTSServer),
1296 #endif /* TRANS_SERVER */
1298 TRANS(TLIOpenCLTSClient),
1299 #endif /* TRANS_CLIENT */
1301 TRANS(TLIOpenCLTSServer),
1302 #endif /* TRANS_SERVER */
1304 TRANS(TLIReopenCOTSServer),
1305 TRANS(TLIReopenCLTSServer),
1307 TRANS(TLISetOption),
1309 TRANS(TLIINETCreateListener),
1310 NULL, /* ResetListener */
1312 #endif /* TRANS_SERVER */
1314 TRANS(TLIINETConnect),
1315 #endif /* TRANS_CLIENT */
1316 TRANS(TLIBytesReadable),
1321 TRANS(TLIDisconnect),
1323 TRANS(TLICloseForCloning),
1327 static char * inet_aliases[] = { "tcp", NULL };
1329 Xtransport TRANS(TLIINETFuncs) = {
1334 TRANS(TLIOpenCOTSClient),
1335 #endif /* TRANS_CLIENT */
1338 TRANS(TLIOpenCOTSServer),
1339 #endif /* TRANS_SERVER */
1341 TRANS(TLIOpenCLTSClient),
1342 #endif /* TRANS_CLIENT */
1344 TRANS(TLIOpenCLTSServer),
1345 #endif /* TRANS_SERVER */
1347 TRANS(TLIReopenCOTSServer),
1348 TRANS(TLIReopenCLTSServer),
1350 TRANS(TLISetOption),
1352 TRANS(TLIINETCreateListener),
1353 NULL, /* ResetListener */
1355 #endif /* TRANS_SERVER */
1357 TRANS(TLIINETConnect),
1358 #endif /* TRANS_CLIENT */
1359 TRANS(TLIBytesReadable),
1364 TRANS(TLIDisconnect),
1366 TRANS(TLICloseForCloning),
1369 Xtransport TRANS(TLITLIFuncs) = {
1374 TRANS(TLIOpenCOTSClient),
1375 #endif /* TRANS_CLIENT */
1378 TRANS(TLIOpenCOTSServer),
1379 #endif /* TRANS_SERVER */
1381 TRANS(TLIOpenCLTSClient),
1382 #endif /* TRANS_CLIENT */
1384 TRANS(TLIOpenCLTSServer),
1385 #endif /* TRANS_SERVER */
1387 TRANS(TLIReopenCOTSServer),
1388 TRANS(TLIReopenCLTSServer),
1390 TRANS(TLISetOption),
1392 TRANS(TLITLICreateListener),
1393 NULL, /* ResetListener */
1395 #endif /* TRANS_SERVER */
1397 TRANS(TLITLIConnect),
1398 #endif /* TRANS_CLIENT */
1399 TRANS(TLIBytesReadable),
1404 TRANS(TLIDisconnect),
1406 TRANS(TLICloseForCloning),