1
/* $Xorg: Xtranstli.c,v 1.4 2001/02/09 02:04:07 xorgcvs Exp $ */
4
Copyright 1993, 1994, 1998 The Open Group
6
Permission to use, copy, modify, distribute, and sell this software and its
7
documentation for any purpose is hereby granted without fee, provided that
8
the above copyright notice appear in all copies and that both that
9
copyright notice and this permission notice appear in supporting
12
The above copyright notice and this permission notice shall be included
13
in all copies or substantial portions of the Software.
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
19
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21
OTHER DEALINGS IN THE SOFTWARE.
23
Except as contained in this notice, the name of The Open Group shall
24
not be used in advertising or otherwise to promote the sale, use or
25
other dealings in this Software without prior written authorization
29
/* $XFree86: xc/lib/xtrans/Xtranstli.c,v 3.11 2002/12/15 01:28:33 dawes Exp $ */
31
/* Copyright 1993, 1994 NCR Corporation - Dayton, Ohio, USA
35
* Permission to use, copy, modify, and distribute this software and its
36
* documentation for any purpose and without fee is hereby granted, provided
37
* that the above copyright notice appear in all copies and that both that
38
* copyright notice and this permission notice appear in supporting
39
* documentation, and that the name NCR not be used in advertising
40
* or publicity pertaining to distribution of the software without specific,
41
* written prior permission. NCR makes no representations about the
42
* suitability of this software for any purpose. It is provided "as is"
43
* without express or implied warranty.
45
* NCR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
46
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
47
* NO EVENT SHALL NCR BE LIABLE FOR ANY SPECIAL, INDIRECT OR
48
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
49
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
50
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
51
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
60
#include <netconfig.h>
64
* This is the TLI implementation of the X Transport service layer
67
typedef struct _TLItrans2dev {
75
static TLItrans2dev TLItrans2devtab[] = {
76
{"inet","inet","/dev/tcp","/dev/udp",AF_INET},
77
{"tcp","inet","/dev/tcp","/dev/udp",AF_INET},
78
{"tli","loopback","/dev/ticots","/dev/ticlts",AF_UNIX},
81
#define NUMTLIFAMILIES (sizeof(TLItrans2devtab)/sizeof(TLItrans2dev))
84
* The local TLI connection, is a form of a local connection, so use a
85
* sockaddr_un for the address so that it will be treated just like the other
86
* local transports such as UNIX domain sockets, pts, and named.
90
#define TLINODENAME "TLI:xserver"
94
#define TLINODENAME "TLI:xim"
97
#if defined(FS_t) || defined(FONT_t)
98
#define TLINODENAME "TLI:fontserver"
102
#define TLINODENAME "TLI:ICE"
106
#define TLINODENAME "TLI:test"
111
#define PORTBUFSIZE 64
114
#define PORTBUFSIZE 64
121
* These are some utility function used by the real interface function below.
125
TRANS(TLISelectFamily)(char *family)
130
PRMSG(3,"TLISelectFamily(%s)\n", family, 0,0 );
132
for(i=0;i<NUMTLIFAMILIES;i++)
134
if( !strcmp(family,TLItrans2devtab[i].transname) )
142
* This function gets the local address of the transport and stores it in the
143
* XtransConnInfo structure for the connection.
147
TRANS(TLIGetAddr)(XtransConnInfo ciptr)
151
struct netbuf netbuf;
153
PRMSG(3,"TLIGetAddr(%x)\n", ciptr, 0,0 );
155
netbuf.buf=(char *)&sockname;
156
netbuf.len=sizeof(sockname);
157
netbuf.maxlen=sizeof(sockname);
159
if( t_getname(ciptr->fd,&netbuf,LOCALNAME) < 0 )
161
PRMSG(1,"TLIGetAddr: t_getname(LOCALNAME) failed: %d\n",
166
PRMSG(4,"TLIGetAddr: got family %d len %d\n",
167
((struct sockaddr *) &sockname)->sa_family ,netbuf.len, 0 );
170
* Everything looks good: fill in the XtransConnInfo structure.
176
if( (ciptr->addr=(char *)xalloc(netbuf.len)) == NULL )
178
PRMSG(1, "TLIGetAddr: Can't allocate space for the addr\n",
183
ciptr->family=((struct sockaddr *) &sockname)->sa_family;
184
ciptr->addrlen=netbuf.len;
185
memcpy(ciptr->addr,&sockname,ciptr->addrlen);
192
* This function gets the remote address of the socket and stores it in the
193
* XtransConnInfo structure for the connection.
197
TRANS(TLIGetPeerAddr)(XtransConnInfo ciptr)
201
struct netbuf netbuf;
203
PRMSG(3,"TLIGetPeerAddr(%x)\n", ciptr, 0,0 );
205
netbuf.buf=(char *)&sockname;
206
netbuf.len=sizeof(sockname);
207
netbuf.maxlen=sizeof(sockname);
209
if( t_getname(ciptr->fd,&netbuf,REMOTENAME) < 0 )
211
PRMSG(1,"TLIGetPeerAddr: t_getname(REMOTENAME) failed: %d\n",
216
PRMSG(4,"TLIGetPeerAddr: got family %d len %d\n",
217
((struct sockaddr *) &sockname)->sa_family ,netbuf.len, 0 );
220
* Everything looks good: fill in the XtransConnInfo structure.
223
if( ciptr->peeraddr )
224
xfree(ciptr->peeraddr);
226
if( (ciptr->peeraddr=(char *)xalloc(netbuf.len)) == NULL )
229
"TLIGetPeerAddr: Can't allocate space for the addr\n",
234
ciptr->peeraddrlen=netbuf.len;
235
memcpy(ciptr->peeraddr,&sockname,ciptr->peeraddrlen);
242
* This function will establish a local name for the transport. This function
243
* do extra work for the local tli connection. It must create a sockaddr_un
244
* format address so that it will look like an AF_UNIX connection to the
247
* This function will only be called by the OPENC?TSClient() functions since
248
* the local address is set up in the CreateListner() for the server ends.
252
TRANS(TLITLIBindLocal)(int fd, int family, char *port)
255
struct sockaddr_un *sunaddr=NULL;
256
struct t_bind *req=NULL;
258
PRMSG(2, "TLITLIBindLocal(%d,%d,%s)\n", fd, family, port);
260
if( family == AF_UNIX )
262
if( (req=(struct t_bind *)t_alloc(fd,T_BIND,0)) == NULL )
265
"TLITLIBindLocal() failed to allocate a t_bind\n",
270
if( (sunaddr=(struct sockaddr_un *)
271
malloc(sizeof(struct sockaddr_un))) == NULL )
274
"TLITLIBindLocal: failed to allocate a sockaddr_un\n",
276
t_free((char *)req,T_BIND);
280
sunaddr->sun_family=AF_UNIX;
283
if( *port == '/' ) { /* A full pathname */
284
(void) strcpy(sunaddr->sun_path, port);
286
(void) sprintf(sunaddr->sun_path,"%s%s", TLINODENAME, port );
290
(void) sprintf(sunaddr->sun_path,"%s%d",
291
TLINODENAME, getpid()^time(NULL) );
293
PRMSG(4, "TLITLIBindLocal: binding to %s\n",
294
sunaddr->sun_path, 0,0);
296
req->addr.buf=(char *)sunaddr;
297
req->addr.len=sizeof(*sunaddr);
298
req->addr.maxlen=sizeof(*sunaddr);
301
if( t_bind(fd, req, NULL) < 0 )
304
"TLIBindLocal: Unable to bind TLI device to %s\n",
307
free((char *) sunaddr);
309
t_free((char *)req,T_BIND);
315
static XtransConnInfo
316
TRANS(TLIOpen)(char *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 );
342
static XtransConnInfo
343
TRANS(TLIReopen)(char *device, int fd, char *port)
346
XtransConnInfo ciptr;
348
PRMSG(3,"TLIReopen(%s,%d, %s)\n", device, fd, port );
352
PRMSG(1, "TLIReopen: t_sync failed\n", 0,0,0 );
356
if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL )
358
PRMSG(1, "TLIReopen: calloc failed\n", 0,0,0 );
367
#endif /* TRANS_REOPEN */
371
TRANS(TLIAddrToNetbuf)(int tlifamily, char *host, char *port,
372
struct netbuf *netbufp)
375
struct netconfig *netconfigp;
376
struct nd_hostserv nd_hostserv;
377
struct nd_addrlist *nd_addrlistp = NULL;
381
PRMSG(3,"TLIAddrToNetbuf(%d,%s,%s)\n", tlifamily, host, port );
383
if( (handlep=setnetconfig()) == NULL )
386
lport = strtol (port, (char**)NULL, 10);
387
if (lport < 1024 || lport > USHRT_MAX)
390
nd_hostserv.h_host = host;
391
if( port && *port ) {
392
nd_hostserv.h_serv = port;
394
nd_hostserv.h_serv = NULL;
397
while( (netconfigp=getnetconfig(handlep)) != NULL )
399
if( strcmp(netconfigp->nc_protofmly,
400
TLItrans2devtab[tlifamily].protofamily) != 0 )
402
PRMSG(5,"TLIAddrToNetbuf: Trying to resolve %s.%s for %s\n",
403
host, port, TLItrans2devtab[tlifamily].protofamily );
404
if( netdir_getbyname(netconfigp,&nd_hostserv, &nd_addrlistp) == 0 )
406
/* we have at least one address to use */
408
PRMSG(5, "TLIAddrToNetbuf: found address for %s.%s\n", host, port, 0 );
409
PRMSG(5, "TLIAddrToNetbuf: %s\n",taddr2uaddr(netconfigp,nd_addrlistp->n_addrs),
412
memcpy(netbufp->buf,nd_addrlistp->n_addrs->buf,
413
nd_addrlistp->n_addrs->len);
414
netbufp->len=nd_addrlistp->n_addrs->len;
415
endnetconfig(handlep);
419
endnetconfig(handlep);
425
* These functions are the interface supplied in the Xtransport structure
430
static XtransConnInfo
431
TRANS(TLIOpenCOTSClient)(Xtransport *thistrans, char *protocol,
432
char *host, char *port)
435
XtransConnInfo ciptr;
438
PRMSG(2,"TLIOpenCOTSClient(%s,%s,%s)\n", protocol, host, port );
440
if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
442
PRMSG(1,"TLIOpenCOTSClient: Unable to determine device for %s\n",
443
thistrans->TransName, 0,0 );
447
if( (ciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcotsname)) == NULL )
449
PRMSG(1,"TLIOpenCOTSClient: Unable to open device for %s\n",
450
thistrans->TransName, 0,0 );
454
if( TRANS(TLITLIBindLocal)(ciptr->fd,TLItrans2devtab[i].family,port) < 0 )
457
"TLIOpenCOTSClient: ...TLITLIBindLocal() failed: %d\n",
464
if( TRANS(TLIGetAddr)(ciptr) < 0 )
467
"TLIOpenCOTSClient: ...TLIGetAddr() failed: %d\n",
474
/* Save the TLIFamily for later use in TLIAddrToNetbuf() lookups */
480
#endif /* TRANS_CLIENT */
485
static XtransConnInfo
486
TRANS(TLIOpenCOTSServer)(Xtransport *thistrans, char *protocol,
487
char *host, char *port)
490
XtransConnInfo ciptr;
493
PRMSG(2,"TLIOpenCOTSServer(%s,%s,%s)\n", protocol, host, port );
495
if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
498
"TLIOpenCOTSServer: Unable to determine device for %s\n",
499
thistrans->TransName, 0,0 );
503
if( (ciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcotsname)) == NULL )
506
"TLIOpenCOTSServer: Unable to open device for %s\n",
507
thistrans->TransName, 0,0 );
511
/* Set the family type */
513
ciptr->family = TLItrans2devtab[i].family;
516
/* Save the TLIFamily for later use in TLIAddrToNetbuf() lookups */
523
#endif /* TRANS_SERVER */
528
static XtransConnInfo
529
TRANS(TLIOpenCLTSClient)(Xtransport *thistrans, char *protocol,
530
char *host, char *port)
533
XtransConnInfo ciptr;
536
PRMSG(2,"TLIOpenCLTSClient(%s,%s,%s)\n", protocol, host, port );
538
if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
541
"TLIOpenCLTSClient: Unable to determine device for %s\n",
542
thistrans->TransName, 0,0 );
546
if( (ciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcltsname)) == NULL )
549
"TLIOpenCLTSClient: Unable to open device for %s\n",
550
thistrans->TransName, 0,0 );
554
if( TRANS(TLITLIBindLocal)(ciptr->fd,TLItrans2devtab[i].family,port) < 0 )
557
"TLIOpenCLTSClient: ...TLITLIBindLocal() failed: %d\n",
564
if( TRANS(TLIGetAddr)(ciptr) < 0 )
567
"TLIOpenCLTSClient: ...TLIGetPeerAddr() failed: %d\n",
577
#endif /* TRANS_CLIENT */
582
static XtransConnInfo
583
TRANS(TLIOpenCLTSServer)(Xtransport *thistrans, char *protocol,
584
char *host, char *port)
587
XtransConnInfo ciptr;
590
PRMSG(2,"TLIOpenCLTSServer(%s,%s,%s)\n", protocol, host, port );
592
if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
595
"TLIOpenCLTSServer: Unable to determine device for %s\n",
596
thistrans->TransName, 0,0 );
600
if( (ciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcltsname)) == NULL )
603
"TLIOpenCLTSServer: Unable to open device for %s\n",
604
thistrans->TransName, 0,0 );
611
#endif /* TRANS_SERVER */
616
static XtransConnInfo
617
TRANS(TLIReopenCOTSServer)(Xtransport *thistrans, int fd, char *port)
620
XtransConnInfo ciptr;
623
PRMSG(2,"TLIReopenCOTSServer(%d, %s)\n", fd, port, 0 );
625
if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
628
"TLIReopenCOTSServer: Unable to determine device for %s\n",
629
thistrans->TransName, 0,0 );
633
if( (ciptr=TRANS(TLIReopen)(
634
TLItrans2devtab[i].devcotsname, fd, port)) == NULL )
637
"TLIReopenCOTSServer: Unable to open device for %s\n",
638
thistrans->TransName, 0,0 );
642
/* Save the TLIFamily for later use in TLIAddrToNetbuf() lookups */
650
static XtransConnInfo
651
TRANS(TLIReopenCLTSServer)(Xtransport *thistrans, int fd, char *port)
654
XtransConnInfo ciptr;
657
PRMSG(2,"TLIReopenCLTSServer(%d, %s)\n", fd, port, 0 );
659
if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
662
"TLIReopenCLTSServer: Unable to determine device for %s\n",
663
thistrans->TransName, 0,0 );
667
if( (ciptr=TRANS(TLIReopen)(
668
TLItrans2devtab[i].devcltsname, fd, port)) == NULL )
671
"TLIReopenCLTSServer: Unable to open device for %s\n",
672
thistrans->TransName, 0,0 );
681
#endif /* TRANS_REOPEN */
685
TRANS(TLISetOption)(XtransConnInfo ciptr, int option, int arg)
688
PRMSG(2,"TLISetOption(%d,%d,%d)\n", ciptr->fd, option, arg );
697
TRANS(TLICreateListener)(XtransConnInfo ciptr, struct t_bind *req)
702
PRMSG(2,"TLICreateListener(%x->%d,%x)\n", ciptr, ciptr->fd, req );
704
if( (ret=(struct t_bind *)t_alloc(ciptr->fd,T_BIND,T_ALL)) == NULL )
706
PRMSG(1, "TLICreateListener: failed to allocate a t_bind\n",
708
t_free((char *)req,T_BIND);
709
return TRANS_CREATE_LISTENER_FAILED;
712
if( t_bind(ciptr->fd, req, ret) < 0 )
714
PRMSG(1, "TLICreateListener: t_bind failed\n", 0,0,0 );
715
t_free((char *)req,T_BIND);
716
t_free((char *)ret,T_BIND);
717
return TRANS_CREATE_LISTENER_FAILED;
720
if( memcmp(req->addr.buf,ret->addr.buf,req->addr.len) != 0 )
722
PRMSG(1, "TLICreateListener: unable to bind to %x\n",
724
t_free((char *)req,T_BIND);
725
t_free((char *)ret,T_BIND);
726
return TRANS_ADDR_IN_USE;
730
* Everything looks good: fill in the XtransConnInfo structure.
733
if( (ciptr->addr=(char *)xalloc(ret->addr.len)) == NULL )
736
"TLICreateListener: Unable to allocate space for the address\n",
738
t_free((char *)req,T_BIND);
739
t_free((char *)ret, T_BIND);
740
return TRANS_CREATE_LISTENER_FAILED;
743
ciptr->addrlen=ret->addr.len;
744
memcpy(ciptr->addr,ret->addr.buf,ret->addr.len);
746
t_free((char *)req,T_BIND);
747
t_free((char *)ret, T_BIND);
754
TRANS(TLIINETCreateListener)(XtransConnInfo ciptr, char *port)
757
char portbuf[PORTBUFSIZE];
759
struct sockaddr_in *sinaddr;
762
PRMSG(2,"TLIINETCreateListener(%x->%d,%s)\n", ciptr,
763
ciptr->fd, port ? port : "NULL" );
767
* X has a well known port, that is transport dependent. It is easier
768
* to handle it here, than try and come up with a transport independent
769
* representation that can be passed in and resolved the usual way.
771
* The port that is passed here is really a string containing the idisplay
772
* from ConnectDisplay().
775
if (is_numeric (port))
777
tmpport = X_TCP_PORT + strtol (port, (char**)NULL, 10);
778
sprintf(portbuf,"%u", tmpport);
783
if( (req=(struct t_bind *)t_alloc(ciptr->fd,T_BIND,T_ALL)) == NULL )
786
"TLIINETCreateListener: failed to allocate a t_bind\n",
788
return TRANS_CREATE_LISTENER_FAILED;
791
if( port && *port ) {
792
if(TRANS(TLIAddrToNetbuf)(ciptr->index,HOST_SELF,port,&(req->addr)) < 0)
795
"TLIINETCreateListener: can't resolve name:HOST_SELF.%s\n",
797
t_free((char *)req,T_BIND);
798
return TRANS_CREATE_LISTENER_FAILED;
801
sinaddr=(struct sockaddr_in *) req->addr.buf;
802
sinaddr->sin_family=AF_INET;
803
sinaddr->sin_port=htons(0);
804
sinaddr->sin_addr.s_addr=0;
811
return TRANS(TLICreateListener)(ciptr, req);
816
TRANS(TLITLICreateListener)(XtransConnInfo ciptr, char *port)
820
struct sockaddr_un *sunaddr;
823
PRMSG(2,"TLITLICreateListener(%x->%d,%s)\n", ciptr, ciptr->fd,
824
port ? port : "NULL");
826
if( (req=(struct t_bind *)t_alloc(ciptr->fd,T_BIND,0)) == NULL )
829
"TLITLICreateListener: failed to allocate a t_bind\n",
831
return TRANS_CREATE_LISTENER_FAILED;
834
if( (sunaddr=(struct sockaddr_un *)
835
malloc(sizeof(struct sockaddr_un))) == NULL )
838
"TLITLICreateListener: failed to allocate a sockaddr_un\n",
840
t_free((char *)req,T_BIND);
841
return TRANS_CREATE_LISTENER_FAILED;
844
sunaddr->sun_family=AF_UNIX;
845
if( port && *port ) {
846
if( *port == '/' ) { /* A full pathname */
847
(void) strcpy(sunaddr->sun_path, port);
849
(void) sprintf(sunaddr->sun_path,"%s%s", TLINODENAME, port );
852
(void) sprintf(sunaddr->sun_path,"%s%d", TLINODENAME, getpid());
855
req->addr.buf=(char *)sunaddr;
856
req->addr.len=sizeof(*sunaddr);
857
req->addr.maxlen=sizeof(*sunaddr);
863
ret_value = TRANS(TLICreateListener)(ciptr, req);
865
free((char *) sunaddr);
871
static XtransConnInfo
872
TRANS(TLIAccept)(XtransConnInfo ciptr, int *status)
876
XtransConnInfo newciptr;
879
PRMSG(2,"TLIAccept(%x->%d)\n", ciptr, ciptr->fd, 0 );
881
if( (call=(struct t_call *)t_alloc(ciptr->fd,T_CALL,T_ALL)) == NULL )
883
PRMSG(1, "TLIAccept() failed to allocate a t_call\n", 0,0,0 );
884
*status = TRANS_ACCEPT_BAD_MALLOC;
888
if( t_listen(ciptr->fd,call) < 0 )
890
extern char *t_errlist[];
892
PRMSG(1, "TLIAccept() t_listen() failed\n", 0,0,0 );
893
PRMSG(1, "TLIAccept: %s\n", t_errlist[t_errno], 0,0 );
894
t_free((char *)call,T_CALL);
895
*status = TRANS_ACCEPT_MISC_ERROR;
900
* Now we need to set up the new endpoint for the incoming connection.
903
i=ciptr->index; /* Makes the next line more readable */
905
if( (newciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcotsname)) == NULL )
907
PRMSG(1, "TLIAccept() failed to open a new endpoint\n", 0,0,0 );
908
t_free((char *)call,T_CALL);
909
*status = TRANS_ACCEPT_MISC_ERROR;
913
if( TRANS(TLITLIBindLocal)(newciptr->fd,TLItrans2devtab[i].family,"") < 0 )
916
"TLIAccept: TRANS(TLITLIBindLocal)() failed: %d\n",
918
t_free((char *)call,T_CALL);
919
t_close(newciptr->fd);
921
*status = TRANS_ACCEPT_MISC_ERROR;
926
if( t_accept(ciptr->fd,newciptr->fd,call) < 0 )
928
extern char *t_errlist[];
930
PRMSG(1, "TLIAccept() t_accept() failed\n", 0,0,0 );
931
PRMSG(1, "TLIAccept: %s\n", t_errlist[t_errno], 0,0 );
932
if( t_errno == TLOOK )
934
int evtype = t_look(ciptr->fd);
935
PRMSG(1, "TLIAccept() t_look() returned %d\n", evtype,0,0 );
939
if( t_rcvdis(ciptr->fd, NULL) < 0 )
941
PRMSG(1, "TLIAccept() t_rcvdis() failed\n", 0,0,0 );
942
PRMSG(1, "TLIAccept: %s\n", t_errlist[t_errno], 0,0 );
949
t_free((char *)call,T_CALL);
950
t_close(newciptr->fd);
952
*status = TRANS_ACCEPT_FAILED;
956
t_free((char *)call,T_CALL);
958
if( TRANS(TLIGetAddr)(newciptr) < 0 )
961
"TLIAccept: TRANS(TLIGetPeerAddr)() failed: %d\n",
963
t_close(newciptr->fd);
965
*status = TRANS_ACCEPT_MISC_ERROR;
969
if( TRANS(TLIGetPeerAddr)(newciptr) < 0 )
972
"TLIAccept: TRANS(TLIGetPeerAddr)() failed: %d\n",
974
t_close(newciptr->fd);
975
xfree(newciptr->addr);
977
*status = TRANS_ACCEPT_MISC_ERROR;
981
if( ioctl(newciptr->fd, I_POP,"timod") < 0 )
983
PRMSG(1, "TLIAccept() ioctl(I_POP, \"timod\") failed %d\n",
985
t_close(newciptr->fd);
986
xfree(newciptr->addr);
988
*status = TRANS_ACCEPT_MISC_ERROR;
992
if( ioctl(newciptr->fd, I_PUSH,"tirdwr") < 0 )
994
PRMSG(1, "TLIAccept() ioctl(I_PUSH,\"tirdwr\") failed %d\n",
996
t_close(newciptr->fd);
997
xfree(newciptr->addr);
999
*status = TRANS_ACCEPT_MISC_ERROR;
1008
#endif /* TRANS_SERVER */
1014
TRANS(TLIConnect)(XtransConnInfo ciptr, struct t_call *sndcall )
1017
PRMSG(2, "TLIConnect(%x->%d,%x)\n", ciptr, ciptr->fd, sndcall);
1019
if( t_connect(ciptr->fd,sndcall,NULL) < 0 )
1021
extern char *t_errlist[];
1023
PRMSG(1, "TLIConnect() t_connect() failed\n", 0,0,0 );
1024
PRMSG(1, "TLIConnect: %s\n", t_errlist[t_errno], 0,0 );
1025
t_free((char *)sndcall,T_CALL);
1026
if (t_errno == TLOOK && t_look(ciptr->fd) == T_DISCONNECT)
1028
t_rcvdis(ciptr->fd,NULL);
1029
return TRANS_TRY_CONNECT_AGAIN;
1032
return TRANS_CONNECT_FAILED;
1035
t_free((char *)sndcall,T_CALL);
1038
* Sync up the address fields of ciptr.
1041
if( TRANS(TLIGetAddr)(ciptr) < 0 )
1044
"TLIConnect: ...TLIGetAddr() failed: %d\n",
1046
return TRANS_CONNECT_FAILED;
1049
if( TRANS(TLIGetPeerAddr)(ciptr) < 0 )
1052
"TLIConnect: ...TLIGetPeerAddr() failed: %d\n",
1054
return TRANS_CONNECT_FAILED;
1057
if( ioctl(ciptr->fd, I_POP,"timod") < 0 )
1059
PRMSG(1, "TLIConnect() ioctl(I_POP,\"timod\") failed %d\n",
1061
return TRANS_CONNECT_FAILED;
1064
if( ioctl(ciptr->fd, I_PUSH,"tirdwr") < 0 )
1066
PRMSG(1, "TLIConnect() ioctl(I_PUSH,\"tirdwr\") failed %d\n",
1068
return TRANS_CONNECT_FAILED;
1076
TRANS(TLIINETConnect)(XtransConnInfo ciptr, char *host, char *port)
1079
char portbuf[PORTBUFSIZE];
1080
struct t_call *sndcall;
1083
PRMSG(2, "TLIINETConnect(%s,%s)\n", host, port, 0);
1087
* X has a well known port, that is transport dependant. It is easier
1088
* to handle it here, than try and come up with a transport independent
1089
* representation that can be passed in and resolved the usual way.
1091
* The port that is passed here is really a string containing the idisplay
1092
* from ConnectDisplay().
1095
if (is_numeric (port))
1097
tmpport = X_TCP_PORT + strtol (port, (char**)NULL, 10);
1098
sprintf(portbuf,"%u", tmpport );
1103
if( (sndcall=(struct t_call *)t_alloc(ciptr->fd,T_CALL,T_ALL)) == NULL )
1105
PRMSG(1, "TLIINETConnect() failed to allocate a t_call\n", 0,0,0 );
1106
return TRANS_CONNECT_FAILED;
1109
if( TRANS(TLIAddrToNetbuf)(ciptr->index, host, port, &(sndcall->addr) ) < 0 )
1111
PRMSG(1, "TLIINETConnect() unable to resolve name:%s.%s\n",
1113
t_free((char *)sndcall,T_CALL);
1114
return TRANS_CONNECT_FAILED;
1117
return TRANS(TLIConnect)(ciptr, sndcall );
1122
TRANS(TLITLIConnect)(XtransConnInfo ciptr, char *host, char *port)
1125
struct t_call *sndcall;
1126
struct sockaddr_un *sunaddr;
1129
PRMSG(2, "TLITLIConnect(%s,%s)\n", host, port, 0);
1131
if( (sndcall=(struct t_call *)t_alloc(ciptr->fd,T_CALL,T_OPT|T_UDATA)) == NULL )
1133
PRMSG(1, "TLITLIConnect() failed to allocate a t_call\n", 0,0,0 );
1134
return TRANS_CONNECT_FAILED;
1137
if( (sunaddr=(struct sockaddr_un *)
1138
malloc(sizeof(struct sockaddr_un))) == NULL )
1141
"TLITLIConnect: failed to allocate a sockaddr_un\n",
1143
t_free((char *)sndcall,T_CALL);
1144
return TRANS_CONNECT_FAILED;
1147
sunaddr->sun_family=AF_UNIX;
1149
strncmp (port, TLINODENAME, strlen (TLINODENAME)) == 0) {
1150
/* Use the port as is */
1151
(void) strcpy(sunaddr->sun_path, port);
1153
(void) sprintf(sunaddr->sun_path,"%s%s", TLINODENAME, port );
1156
sndcall->addr.buf=(char *)sunaddr;
1157
sndcall->addr.len=sizeof(*sunaddr);
1158
sndcall->addr.maxlen=sizeof(*sunaddr);
1160
ret_value = TRANS(TLIConnect)(ciptr, sndcall );
1162
free((char *) sunaddr);
1167
#endif /* TRANS_CLIENT */
1171
TRANS(TLIBytesReadable)(XtransConnInfo ciptr, BytesReadable_t *pend)
1175
struct pollfd filedes;
1177
PRMSG(2, "TLIByteReadable(%x->%d,%x)\n", ciptr, ciptr->fd, pend );
1180
* This function should detect hangup conditions. Use poll to check
1181
* if no data is present. On SVR4, the M_HANGUP message sits on the
1182
* streams head, and ioctl(N_READ) keeps returning 0 because there is
1183
* no data available. The hangup goes undetected, and the client hangs.
1186
ret=ioctl(ciptr->fd, I_NREAD, (char *)pend);
1189
return ret; /* Data present or error */
1192
/* Zero data, or POLLHUP message */
1194
filedes.fd=ciptr->fd;
1195
filedes.events=POLLIN;
1197
ret=poll(&filedes, 1, 0);
1201
return 0; /* Really, no data */
1205
return -1; /* just pass back the error */
1207
if( filedes.revents & (POLLHUP|POLLERR) ) /* check for hangup */
1210
/* Should only get here if data arrived after the first ioctl() */
1211
return ioctl(ciptr->fd, I_NREAD, (char *)pend);
1216
TRANS(TLIRead)(XtransConnInfo ciptr, char *buf, int size)
1219
PRMSG(2, "TLIRead(%d,%x,%d)\n", ciptr->fd, buf, size );
1221
return read(ciptr->fd,buf,size);
1226
TRANS(TLIWrite)(XtransConnInfo ciptr, char *buf, int size)
1229
PRMSG(2, "TLIWrite(%d,%x,%d)\n", ciptr->fd, buf, size );
1231
return write(ciptr->fd,buf,size);
1236
TRANS(TLIReadv)(XtransConnInfo ciptr, struct iovec *buf, int size)
1239
PRMSG(2, "TLIReadv(%d,%x,%d)\n", ciptr->fd, buf, size );
1241
return READV(ciptr,buf,size);
1246
TRANS(TLIWritev)(XtransConnInfo ciptr, struct iovec *buf, int size)
1249
PRMSG(2, "TLIWritev(%d,%x,%d)\n", ciptr->fd, buf, size );
1251
return WRITEV(ciptr,buf,size);
1256
TRANS(TLIDisconnect)(XtransConnInfo ciptr)
1259
PRMSG(2, "TLIDisconnect(%x->%d)\n", ciptr, ciptr->fd, 0 );
1262
* Restore the TLI modules so that the connection can be properly shutdown.
1263
* This avoids the situation where a connection goes into the TIME_WAIT
1264
* state, and the address remains unavailable for a while.
1266
ioctl(ciptr->fd, I_POP,"tirdwr");
1267
ioctl(ciptr->fd, I_PUSH,"timod");
1269
t_snddis(ciptr->fd,NULL);
1276
TRANS(TLIClose)(XtransConnInfo ciptr)
1279
PRMSG(2, "TLIClose(%x->%d)\n", ciptr, ciptr->fd, 0 );
1281
t_unbind(ciptr->fd);
1283
return (t_close(ciptr->fd));
1288
TRANS(TLICloseForCloning)(XtransConnInfo ciptr)
1295
PRMSG(2, "TLICloseForCloning(%x->%d)\n", ciptr, ciptr->fd, 0 );
1297
return (t_close(ciptr->fd));
1301
Xtransport TRANS(TLITCPFuncs) = {
1306
TRANS(TLIOpenCOTSClient),
1307
#endif /* TRANS_CLIENT */
1309
TRANS(TLIOpenCOTSServer),
1310
#endif /* TRANS_SERVER */
1312
TRANS(TLIOpenCLTSClient),
1313
#endif /* TRANS_CLIENT */
1315
TRANS(TLIOpenCLTSServer),
1316
#endif /* TRANS_SERVER */
1318
TRANS(TLIReopenCOTSServer),
1319
TRANS(TLIReopenCLTSServer),
1321
TRANS(TLISetOption),
1323
TRANS(TLIINETCreateListener),
1324
NULL, /* ResetListener */
1326
#endif /* TRANS_SERVER */
1328
TRANS(TLIINETConnect),
1329
#endif /* TRANS_CLIENT */
1330
TRANS(TLIBytesReadable),
1335
TRANS(TLIDisconnect),
1337
TRANS(TLICloseForCloning),
1340
Xtransport TRANS(TLIINETFuncs) = {
1345
TRANS(TLIOpenCOTSClient),
1346
#endif /* TRANS_CLIENT */
1348
TRANS(TLIOpenCOTSServer),
1349
#endif /* TRANS_SERVER */
1351
TRANS(TLIOpenCLTSClient),
1352
#endif /* TRANS_CLIENT */
1354
TRANS(TLIOpenCLTSServer),
1355
#endif /* TRANS_SERVER */
1357
TRANS(TLIReopenCOTSServer),
1358
TRANS(TLIReopenCLTSServer),
1360
TRANS(TLISetOption),
1362
TRANS(TLIINETCreateListener),
1363
NULL, /* ResetListener */
1365
#endif /* TRANS_SERVER */
1367
TRANS(TLIINETConnect),
1368
#endif /* TRANS_CLIENT */
1369
TRANS(TLIBytesReadable),
1374
TRANS(TLIDisconnect),
1376
TRANS(TLICloseForCloning),
1379
Xtransport TRANS(TLITLIFuncs) = {
1384
TRANS(TLIOpenCOTSClient),
1385
#endif /* TRANS_CLIENT */
1387
TRANS(TLIOpenCOTSServer),
1388
#endif /* TRANS_SERVER */
1390
TRANS(TLIOpenCLTSClient),
1391
#endif /* TRANS_CLIENT */
1393
TRANS(TLIOpenCLTSServer),
1394
#endif /* TRANS_SERVER */
1396
TRANS(TLIReopenCOTSServer),
1397
TRANS(TLIReopenCLTSServer),
1399
TRANS(TLISetOption),
1401
TRANS(TLITLICreateListener),
1402
NULL, /* ResetListener */
1404
#endif /* TRANS_SERVER */
1406
TRANS(TLITLIConnect),
1407
#endif /* TRANS_CLIENT */
1408
TRANS(TLIBytesReadable),
1413
TRANS(TLIDisconnect),
1415
TRANS(TLICloseForCloning),