]> git.sesse.net Git - rdpsrv/blob - Xserver/lib/xtrans/Xtranstli.c
Support RDP5 logon packets.
[rdpsrv] / Xserver / lib / xtrans / Xtranstli.c
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 $ */
3 /*
4
5 Copyright (c) 1993, 1994  X Consortium
6
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:
14
15 The above copyright notice and this permission notice shall be included
16 in all copies or substantial portions of the Software.
17
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.
25
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.
30
31 */
32
33 /* Copyright (c) 1993, 1994 NCR Corporation - Dayton, Ohio, USA
34  *
35  * All Rights Reserved
36  *
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.
46  *
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.
54  */
55
56 #include <sys/un.h>
57 #include <stropts.h>
58 #include <poll.h>
59 #include <tiuser.h>
60
61 #include <netdir.h>
62 #include <netconfig.h>
63
64
65 /*
66  * This is the TLI implementation of the X Transport service layer
67  */
68
69 typedef struct _TLItrans2dev {
70     char        *transname;
71     char        *protofamily;
72     char        *devcotsname;
73     char        *devcltsname;
74     int family;
75 } TLItrans2dev;
76
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},
81 };
82
83 #define NUMTLIFAMILIES (sizeof(TLItrans2devtab)/sizeof(TLItrans2dev))
84     
85 /*
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.
89  */
90     
91 #if defined(X11_t)
92 #define TLINODENAME     "TLI:xserver"
93 #endif
94     
95 #if defined(XIM_t)
96 #define TLINODENAME     "TLI:xim"
97 #endif
98     
99 #if defined(FS_t) || defined(FONT_t)
100 #define TLINODENAME     "TLI:fontserver"
101 #endif
102     
103 #if defined(ICE_t)
104 #define TLINODENAME     "TLI:ICE"
105 #endif
106     
107 #if defined(TEST_t)
108 #define TLINODENAME     "TLI:test"
109 #endif
110     
111
112 /*
113  * These are some utility function used by the real interface function below.
114  */
115
116 static int
117 TRANS(TLISelectFamily)(family)
118
119 char    *family;
120
121 {
122     int     i;
123     
124     PRMSG(3,"TLISelectFamily(%s)\n", family, 0,0 );
125     
126     for(i=0;i<NUMTLIFAMILIES;i++)
127     {
128         if( !strcmp(family,TLItrans2devtab[i].transname) )
129             return i;
130     }
131     return -1;
132 }
133
134
135 /*
136  * This function gets the local address of the transport and stores it in the
137  * XtransConnInfo structure for the connection.
138  */
139
140 static int
141 TRANS(TLIGetAddr)(ciptr)
142
143 XtransConnInfo  ciptr;
144
145 {
146     Xtransaddr          sockname;
147     struct netbuf       netbuf;
148     
149     PRMSG(3,"TLIGetAddr(%x)\n", ciptr, 0,0 );
150     
151     netbuf.buf=(char *)&sockname;
152     netbuf.len=sizeof(sockname);
153     netbuf.maxlen=sizeof(sockname);
154     
155     if( t_getname(ciptr->fd,&netbuf,LOCALNAME) < 0 )
156     {
157         PRMSG(1,"TLIGetAddr: t_getname(LOCALNAME) failed: %d\n",
158               errno, 0,0 );
159         return -1;
160     }
161     
162     PRMSG(4,"TLIGetAddr: got family %d len %d\n",
163           ((struct sockaddr *) &sockname)->sa_family ,netbuf.len, 0 );
164     
165     /*
166      * Everything looks good: fill in the XtransConnInfo structure.
167      */
168     
169     if( ciptr->addr )
170         xfree(ciptr->addr);
171     
172     if( (ciptr->addr=(char *)xalloc(netbuf.len)) == NULL )
173     {
174         PRMSG(1, "TLIGetAddr: Can't allocate space for the addr\n",
175               0,0,0);
176         return -1;
177     }
178     
179     ciptr->family=((struct sockaddr *) &sockname)->sa_family;
180     ciptr->addrlen=netbuf.len;
181     memcpy(ciptr->addr,&sockname,ciptr->addrlen);
182     
183     return 0;
184 }
185
186
187 /*
188  * This function gets the remote address of the socket and stores it in the
189  * XtransConnInfo structure for the connection.
190  */
191
192 static int
193 TRANS(TLIGetPeerAddr)(ciptr)
194
195 XtransConnInfo  ciptr;
196
197 {
198     Xtransaddr          sockname;
199     struct netbuf       netbuf;
200     
201     PRMSG(3,"TLIGetPeerAddr(%x)\n", ciptr, 0,0 );
202     
203     netbuf.buf=(char *)&sockname;
204     netbuf.len=sizeof(sockname);
205     netbuf.maxlen=sizeof(sockname);
206     
207     if( t_getname(ciptr->fd,&netbuf,REMOTENAME) < 0 )
208     {
209         PRMSG(1,"TLIGetPeerAddr: t_getname(REMOTENAME) failed: %d\n",
210               errno, 0,0 );
211         return -1;
212     }
213     
214     PRMSG(4,"TLIGetPeerAddr: got family %d len %d\n",
215           ((struct sockaddr *) &sockname)->sa_family ,netbuf.len, 0 );
216     
217     /*
218      * Everything looks good: fill in the XtransConnInfo structure.
219      */
220     
221     if( ciptr->peeraddr )
222         xfree(ciptr->peeraddr);
223     
224     if( (ciptr->peeraddr=(char *)xalloc(netbuf.len)) == NULL )
225     {
226         PRMSG(1,
227               "TLIGetPeerAddr: Can't allocate space for the addr\n",
228               0,0,0);
229         return -1;
230     }
231     
232     ciptr->peeraddrlen=netbuf.len;
233     memcpy(ciptr->peeraddr,&sockname,ciptr->peeraddrlen);
234     
235     return 0;
236 }
237
238
239 /*
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
243  * higher layer.
244  *
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.
247  */
248
249 static int
250 TRANS(TLITLIBindLocal)(fd,family,port)
251
252 int     fd;
253 int     family;
254 char    *port;
255
256 {
257     struct sockaddr_un  *sunaddr;
258     struct t_bind       *req=NULL;
259     
260     PRMSG(2, "TLITLIBindLocal(%d,%d,%s)\n", fd, family, port);
261     
262     if( family == AF_UNIX )
263     {
264         if( (req=(struct t_bind *)t_alloc(fd,T_BIND,0)) == NULL )
265         {
266             PRMSG(1,
267                   "TLITLIBindLocal() failed to allocate a t_bind\n",
268                   0,0,0 );
269             return -1;
270         }
271         
272         if( (sunaddr=(struct sockaddr_un *)
273              malloc(sizeof(struct sockaddr_un))) == NULL )
274         {
275             PRMSG(1,
276                   "TLITLIBindLocal: failed to allocate a sockaddr_un\n",
277                   0,0,0 );
278             t_free((char *)req,T_BIND);
279             return -1;
280         }
281         
282         sunaddr->sun_family=AF_UNIX;
283         
284 #ifdef nuke
285         if( *port == '/' ) { /* A full pathname */
286             (void) strcpy(sunaddr->sun_path, port);
287         } else {
288             (void) sprintf(sunaddr->sun_path,"%s%s", TLINODENAME, port );
289         }
290 #endif /*NUKE*/
291         
292         (void) sprintf(sunaddr->sun_path,"%s%d",
293                        TLINODENAME, getpid()^time(NULL) );
294         
295         PRMSG(4, "TLITLIBindLocal: binding to %s\n",
296               sunaddr->sun_path, 0,0);
297         
298         req->addr.buf=(char *)sunaddr;
299         req->addr.len=sizeof(*sunaddr);
300         req->addr.maxlen=sizeof(*sunaddr);
301     }
302     
303     if( t_bind(fd, req, NULL) < 0 )
304     {
305         PRMSG(1,
306               "TLIBindLocal: Unable to bind TLI device to %s\n",
307               port, 0,0 );
308         return -1;
309     }
310     return 0;
311 }
312
313 static XtransConnInfo
314 TRANS(TLIOpen)(device)
315
316 char    *device;
317
318 {
319     XtransConnInfo      ciptr;
320     
321     PRMSG(3,"TLIOpen(%s)\n", device, 0,0 );
322     
323     if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL )
324     {
325         PRMSG(1, "TLIOpen: calloc failed\n", 0,0,0 );
326         return NULL;
327     }
328     
329     if( (ciptr->fd=t_open( device, O_RDWR, NULL )) < 0 )
330     {
331         PRMSG(1, "TLIOpen: t_open failed for %s\n", device, 0,0 );
332         return NULL;
333     }
334     
335     return ciptr;
336 }
337
338
339 #ifdef TRANS_REOPEN
340
341 static XtransConnInfo
342 TRANS(TLIReopen)(device, fd, port)
343
344 char    *device;
345 int     fd;
346 char    *port;
347
348 {
349     XtransConnInfo      ciptr;
350     
351     PRMSG(3,"TLIReopen(%s,%d, %s)\n", device, fd, port );
352     
353     if (t_sync (fd) < 0)
354     {
355         PRMSG(1, "TLIReopen: t_sync failed\n", 0,0,0 );
356         return NULL;
357     }
358
359     if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL )
360     {
361         PRMSG(1, "TLIReopen: calloc failed\n", 0,0,0 );
362         return NULL;
363     }
364     
365     ciptr->fd = fd;
366     
367     return ciptr;
368 }
369
370 #endif /* TRANS_REOPEN */
371
372
373 static  int
374 TRANS(TLIAddrToNetbuf)(tlifamily, host, port, netbufp)
375
376 int             tlifamily;
377 char            *host;
378 char            *port;
379 struct netbuf   *netbufp;
380
381 {
382     struct netconfig *netconfigp;
383     struct nd_hostserv  nd_hostserv;
384     struct nd_addrlist *nd_addrlistp = NULL;
385     void *handlep;
386     
387     PRMSG(3,"TLIAddrToNetbuf(%d,%s,%s)\n", tlifamily, host, port );
388     
389     if( (handlep=setnetconfig()) == NULL )
390         return -1;
391     
392     nd_hostserv.h_host = host;
393     if( port && *port ) {
394         nd_hostserv.h_serv = port;
395     } else {
396         nd_hostserv.h_serv = NULL;
397     }
398     
399     while( (netconfigp=getnetconfig(handlep)) != NULL )
400     {
401         if( strcmp(netconfigp->nc_protofmly,
402                    TLItrans2devtab[tlifamily].protofamily) != 0 )
403             continue;
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 )
407         {
408             /* we have at least one address to use */
409             
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),
412                   0,0 );
413             
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);
418             return 0;
419         }
420     }
421     endnetconfig(handlep);
422     
423     return -1;
424 }
425
426 /*
427  * These functions are the interface supplied in the Xtransport structure
428  */
429
430 #ifdef TRANS_CLIENT
431
432 static XtransConnInfo
433 TRANS(TLIOpenCOTSClient)(thistrans, protocol, host, port)
434
435 Xtransport      *thistrans;
436 char            *protocol;
437 char            *host;
438 char            *port;
439
440 {
441     XtransConnInfo      ciptr;
442     int                 i;
443     
444     PRMSG(2,"TLIOpenCOTSClient(%s,%s,%s)\n", protocol, host, port );
445     
446     if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
447     {
448         PRMSG(1,"TLIOpenCOTSClient: Unable to determine device for %s\n",
449               thistrans->TransName, 0,0 );
450         return NULL;
451     }
452     
453     if( (ciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcotsname)) == NULL )
454     {
455         PRMSG(1,"TLIOpenCOTSClient: Unable to open device for %s\n",
456               thistrans->TransName, 0,0 );
457         return NULL;
458     }
459     
460     if( TRANS(TLITLIBindLocal)(ciptr->fd,TLItrans2devtab[i].family,port) < 0 )
461     {
462         PRMSG(1,
463               "TLIOpenCOTSClient: ...TLITLIBindLocal() failed: %d\n",
464               errno, 0,0 );
465         t_close(ciptr->fd);
466         xfree(ciptr);
467         return NULL;
468     }
469     
470     if( TRANS(TLIGetAddr)(ciptr) < 0 )
471     {
472         PRMSG(1,
473               "TLIOpenCOTSClient: ...TLIGetAddr() failed: %d\n",
474               errno, 0,0 );
475         t_close(ciptr->fd);
476         xfree(ciptr);
477         return NULL;
478     }
479     
480     /* Save the TLIFamily for later use in TLIAddrToNetbuf() lookups */
481     ciptr->index = i;
482     
483     return ciptr;
484 }
485
486 #endif /* TRANS_CLIENT */
487
488
489 #ifdef TRANS_SERVER
490
491 static XtransConnInfo
492 TRANS(TLIOpenCOTSServer)(thistrans, protocol, host, port)
493
494 Xtransport      *thistrans;
495 char            *protocol;
496 char            *host;
497 char            *port;
498
499 {
500     XtransConnInfo      ciptr;
501     int                 i;
502     
503     PRMSG(2,"TLIOpenCOTSServer(%s,%s,%s)\n", protocol, host, port );
504     
505     if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
506     {
507         PRMSG(1,
508               "TLIOpenCOTSServer: Unable to determine device for %s\n",
509               thistrans->TransName, 0,0 );
510         return NULL;
511     }
512     
513     if( (ciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcotsname)) == NULL )
514     {
515         PRMSG(1,
516               "TLIOpenCOTSServer: Unable to open device for %s\n",
517               thistrans->TransName, 0,0 );
518         return NULL;
519     }
520     
521     /* Set the family type */
522
523     ciptr->family = TLItrans2devtab[i].family;
524
525
526     /* Save the TLIFamily for later use in TLIAddrToNetbuf() lookups */
527     
528     ciptr->index = i;
529     
530     return ciptr;
531 }
532
533 #endif /* TRANS_SERVER */
534
535
536 #ifdef TRANS_CLIENT
537
538 static XtransConnInfo
539 TRANS(TLIOpenCLTSClient)(thistrans, protocol, host, port)
540
541 Xtransport      *thistrans;
542 char            *protocol;
543 char            *host;
544 char            *port;
545
546 {
547     XtransConnInfo      ciptr;
548     int                 i;
549     
550     PRMSG(2,"TLIOpenCLTSClient(%s,%s,%s)\n", protocol, host, port );
551     
552     if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
553     {
554         PRMSG(1,
555               "TLIOpenCLTSClient: Unable to determine device for %s\n",
556               thistrans->TransName, 0,0 );
557         return NULL;
558     }
559     
560     if( (ciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcltsname)) == NULL )
561     {
562         PRMSG(1,
563               "TLIOpenCLTSClient: Unable to open device for %s\n",
564               thistrans->TransName, 0,0 );
565         return NULL;
566     }
567     
568     if( TRANS(TLITLIBindLocal)(ciptr->fd,TLItrans2devtab[i].family,port) < 0 )
569     {
570         PRMSG(1,
571               "TLIOpenCLTSClient: ...TLITLIBindLocal() failed: %d\n",
572               errno, 0,0 );
573         t_close(ciptr->fd);
574         xfree(ciptr);
575         return NULL;
576     }
577     
578     if( TRANS(TLIGetAddr)(ciptr) < 0 )
579     {
580         PRMSG(1,
581               "TLIOpenCLTSClient: ...TLIGetPeerAddr() failed: %d\n",
582               errno, 0,0 );
583         t_close(ciptr->fd);
584         xfree(ciptr);
585         return NULL;
586     }
587     
588     return ciptr;
589 }                       
590
591 #endif /* TRANS_CLIENT */
592
593
594 #ifdef TRANS_SERVER
595
596 static XtransConnInfo
597 TRANS(TLIOpenCLTSServer)(thistrans, protocol, host, port)
598
599 Xtransport      *thistrans;
600 char            *protocol;
601 char            *host;
602 char            *port;
603
604 {
605     XtransConnInfo      ciptr;
606     int                 i;
607     
608     PRMSG(2,"TLIOpenCLTSServer(%s,%s,%s)\n", protocol, host, port );
609     
610     if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
611     {
612         PRMSG(1,
613               "TLIOpenCLTSServer: Unable to determine device for %s\n",
614               thistrans->TransName, 0,0 );
615         return NULL;
616     }
617     
618     if( (ciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcltsname)) == NULL )
619     {
620         PRMSG(1,
621               "TLIOpenCLTSServer: Unable to open device for %s\n",
622               thistrans->TransName, 0,0 );
623         return NULL;
624     }
625     
626     return ciptr;
627 }                       
628
629 #endif /* TRANS_SERVER */
630
631
632 #ifdef TRANS_REOPEN
633
634 static XtransConnInfo
635 TRANS(TLIReopenCOTSServer)(thistrans, fd, port)
636
637 Xtransport      *thistrans;
638 int             fd;
639 char            *port;
640
641 {
642     XtransConnInfo      ciptr;
643     int                 i;
644     
645     PRMSG(2,"TLIReopenCOTSServer(%d, %s)\n", fd, port, 0 );
646     
647     if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
648     {
649         PRMSG(1,
650               "TLIReopenCOTSServer: Unable to determine device for %s\n",
651               thistrans->TransName, 0,0 );
652         return NULL;
653     }
654
655     if( (ciptr=TRANS(TLIReopen)(
656         TLItrans2devtab[i].devcotsname, fd, port)) == NULL )
657     {
658         PRMSG(1,
659               "TLIReopenCOTSServer: Unable to open device for %s\n",
660               thistrans->TransName, 0,0 );
661         return NULL;
662     }
663     
664     /* Save the TLIFamily for later use in TLIAddrToNetbuf() lookups */
665     
666     ciptr->index = i;
667     
668     return ciptr;
669 }
670
671
672 static XtransConnInfo
673 TRANS(TLIReopenCLTSServer)(thistrans, fd, port)
674
675 Xtransport      *thistrans;
676 int             fd;
677 char            *port;
678
679 {
680     XtransConnInfo      ciptr;
681     int                 i;
682     
683     PRMSG(2,"TLIReopenCLTSServer(%d, %s)\n", fd, port, 0 );
684     
685     if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
686     {
687         PRMSG(1,
688               "TLIReopenCLTSServer: Unable to determine device for %s\n",
689               thistrans->TransName, 0,0 );
690         return NULL;
691     }
692
693     if( (ciptr=TRANS(TLIReopen)(
694         TLItrans2devtab[i].devcltsname, fd, port)) == NULL )
695     {
696         PRMSG(1,
697               "TLIReopenCLTSServer: Unable to open device for %s\n",
698               thistrans->TransName, 0,0 );
699         return NULL;
700     }
701     
702     ciptr->index = i;
703
704     return ciptr;
705 }                       
706
707 #endif /* TRANS_REOPEN */
708
709
710 static
711 TRANS(TLISetOption)(ciptr, option, arg)
712
713 XtransConnInfo  ciptr;
714 int             option;
715 int             arg;
716
717 {
718     PRMSG(2,"TLISetOption(%d,%d,%d)\n", ciptr->fd, option, arg );
719     
720     return -1;
721 }
722
723
724 #ifdef TRANS_SERVER
725
726 static
727 TRANS(TLICreateListener)(ciptr, req)
728
729 XtransConnInfo  ciptr;
730 struct t_bind   *req;
731
732 {
733     struct t_bind       *ret;
734     
735     PRMSG(2,"TLICreateListener(%x->%d,%x)\n", ciptr, ciptr->fd, req );
736     
737     if( (ret=(struct t_bind *)t_alloc(ciptr->fd,T_BIND,T_ALL)) == NULL )
738     {
739         PRMSG(1, "TLICreateListener: failed to allocate a t_bind\n",
740               0,0,0 );
741         return TRANS_CREATE_LISTENER_FAILED;
742     }
743     
744     if( t_bind(ciptr->fd, req, ret) < 0 )
745     {
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;
750     }
751     
752     if( memcmp(req->addr.buf,ret->addr.buf,req->addr.len) != 0 )
753     {
754         PRMSG(1, "TLICreateListener: unable to bind to %x\n",
755               req, 0,0 );
756         t_free((char *)req,T_BIND);
757         t_free((char *)ret,T_BIND);
758         return TRANS_ADDR_IN_USE;
759     }
760     
761     /*
762      * Everything looks good: fill in the XtransConnInfo structure.
763      */
764     
765     if( (ciptr->addr=(char *)xalloc(ret->addr.len)) == NULL )
766     {
767         PRMSG(1,
768               "TLICreateListener: Unable to allocate space for the address\n",
769               0,0,0 );
770         t_free((char *)req,T_BIND);
771         t_free((char *)ret, T_BIND);
772         return TRANS_CREATE_LISTENER_FAILED;
773     }
774     
775     ciptr->addrlen=ret->addr.len;
776     memcpy(ciptr->addr,ret->addr.buf,ret->addr.len);
777     
778     t_free((char *)req,T_BIND);
779     t_free((char *)ret, T_BIND);
780     
781     return 0;
782 }
783
784
785 static
786 TRANS(TLIINETCreateListener)(ciptr, port)
787
788 XtransConnInfo  ciptr;
789 char            *port;
790
791 {
792 #define PORTBUFSIZE     64      /* what is a real size for this? */
793     char    portbuf[PORTBUFSIZE];
794     struct t_bind       *req;
795     struct sockaddr_in  *sinaddr;
796     
797     PRMSG(2,"TLIINETCreateListener(%x->%d,%s)\n", ciptr,
798         ciptr->fd, port ? port : "NULL" );
799     
800 #ifdef X11_t
801     /*
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.
805      *
806      * The port that is passed here is really a string containing the idisplay
807      * from ConnectDisplay().
808      */
809     
810     if (is_numeric (port))
811     {
812         short tmpport = (short) atoi (port);
813         
814         sprintf(portbuf,"%d", X_TCP_PORT+tmpport );
815     }
816     else
817         strncpy(portbuf,port,PORTBUFSIZE);
818     port=portbuf;
819 #endif
820     
821     if( (req=(struct t_bind *)t_alloc(ciptr->fd,T_BIND,T_ALL)) == NULL )
822     {
823         PRMSG(1,
824             "TLIINETCreateListener: failed to allocate a t_bind\n",
825             0,0,0 );
826         return TRANS_CREATE_LISTENER_FAILED;
827     }
828
829     if( port && *port ) {
830         if(TRANS(TLIAddrToNetbuf)(ciptr->index,HOST_SELF,port,&(req->addr)) < 0)
831         {
832             PRMSG(1,
833                   "TLIINETCreateListener: can't resolve name:HOST_SELF.%s\n",
834                   port, 0,0 );
835             t_free((char *)req,T_BIND);
836             return TRANS_CREATE_LISTENER_FAILED;
837         }
838     } else {
839         sinaddr=(struct sockaddr_in *)req->addr.buf;
840         sinaddr->sin_family=AF_INET;
841         sinaddr->sin_port=0;
842         sinaddr->sin_addr.s_addr=0;
843     }
844
845     /* Set the qlen */
846
847     req->qlen=1;
848     
849     return TRANS(TLICreateListener)(ciptr, req);
850 }
851
852
853 static
854 TRANS(TLITLICreateListener)(ciptr, port)
855
856 XtransConnInfo  ciptr;
857 char            *port;
858
859 {
860     struct t_bind       *req;
861     struct sockaddr_un  *sunaddr;
862     
863     PRMSG(2,"TLITLICreateListener(%x->%d,%s)\n", ciptr, ciptr->fd,
864         port ? port : "NULL");
865     
866     if( (req=(struct t_bind *)t_alloc(ciptr->fd,T_BIND,0)) == NULL )
867     {
868         PRMSG(1,
869               "TLITLICreateListener: failed to allocate a t_bind\n",
870               0,0,0 );
871         return TRANS_CREATE_LISTENER_FAILED;
872     }
873     
874     if( (sunaddr=(struct sockaddr_un *)
875          malloc(sizeof(struct sockaddr_un))) == NULL )
876     {
877         PRMSG(1,
878               "TLITLICreateListener: failed to allocate a sockaddr_un\n",
879               0,0,0 );
880         t_free((char *)req,T_BIND);
881         return TRANS_CREATE_LISTENER_FAILED;
882     }
883     
884     sunaddr->sun_family=AF_UNIX;
885     if( port && *port ) {
886         if( *port == '/' ) { /* A full pathname */
887             (void) strcpy(sunaddr->sun_path, port);
888         } else {
889             (void) sprintf(sunaddr->sun_path,"%s%s", TLINODENAME, port );
890         }
891     } else {
892         (void) sprintf(sunaddr->sun_path,"%s%d", TLINODENAME, getpid());
893     }
894     
895     req->addr.buf=(char *)sunaddr;
896     req->addr.len=sizeof(*sunaddr);
897     req->addr.maxlen=sizeof(*sunaddr);
898     
899     /* Set the qlen */
900     
901     req->qlen=1;
902     
903     return TRANS(TLICreateListener)(ciptr, req);
904 }
905
906
907 static XtransConnInfo
908 TRANS(TLIAccept)(ciptr, status)
909
910 XtransConnInfo  ciptr;
911 int             *status;
912
913 {
914     struct t_call       *call;
915     XtransConnInfo      newciptr;
916     int i;
917     
918     PRMSG(2,"TLIAccept(%x->%d)\n", ciptr, ciptr->fd, 0 );
919     
920     if( (call=(struct t_call *)t_alloc(ciptr->fd,T_CALL,T_ALL)) == NULL )
921     {
922         PRMSG(1, "TLIAccept() failed to allocate a t_call\n", 0,0,0 );
923         *status = TRANS_ACCEPT_BAD_MALLOC;
924         return NULL;
925     }
926     
927     if( t_listen(ciptr->fd,call) < 0 )
928     {
929         extern char *t_errlist[];
930         extern int t_errno;
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;
935         return NULL;
936     }
937     
938     /*
939      * Now we need to set up the new endpoint for the incoming connection.
940      */
941     
942     i=ciptr->index; /* Makes the next line more readable */
943     
944     if( (newciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcotsname)) == NULL )
945     {
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;
949         return NULL;
950     }
951     
952     if( TRANS(TLITLIBindLocal)(newciptr->fd,TLItrans2devtab[i].family,"") < 0 )
953     {
954         PRMSG(1,
955               "TLIAccept: TRANS(TLITLIBindLocal)() failed: %d\n",
956               errno, 0,0 );
957         t_free((char *)call,T_CALL);
958         t_close(newciptr->fd);
959         xfree(newciptr);
960         *status = TRANS_ACCEPT_MISC_ERROR;
961         return NULL;
962     }
963     
964     
965     if( t_accept(ciptr->fd,newciptr->fd,call) < 0 )
966     {
967         extern char *t_errlist[];
968         extern int t_errno;
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);
974         xfree(newciptr);
975         *status = TRANS_ACCEPT_FAILED;
976         return NULL;
977     }
978     
979     t_free((char *)call,T_CALL);
980     
981     if( TRANS(TLIGetAddr)(newciptr) < 0 )
982     {
983         PRMSG(1,
984               "TLIAccept: TRANS(TLIGetPeerAddr)() failed: %d\n",
985               errno, 0,0 );
986         t_close(newciptr->fd);
987         xfree(newciptr);
988         *status = TRANS_ACCEPT_MISC_ERROR;
989         return NULL;
990     }
991     
992     if( TRANS(TLIGetPeerAddr)(newciptr) < 0 )
993     {
994         PRMSG(1,
995               "TLIAccept: TRANS(TLIGetPeerAddr)() failed: %d\n",
996               errno, 0,0 );
997         t_close(newciptr->fd);
998         xfree(newciptr->addr);
999         xfree(newciptr);
1000         *status = TRANS_ACCEPT_MISC_ERROR;
1001         return NULL;
1002     }
1003     
1004     if( ioctl(newciptr->fd, I_POP,"timod") < 0 )
1005     {
1006         PRMSG(1, "TLIAccept() ioctl(I_POP, \"timod\") failed %d\n",
1007               errno,0,0 );
1008         t_close(newciptr->fd);
1009         xfree(newciptr->addr);
1010         xfree(newciptr);
1011         *status = TRANS_ACCEPT_MISC_ERROR;
1012         return NULL;
1013     }
1014     
1015     if( ioctl(newciptr->fd, I_PUSH,"tirdwr") < 0 )
1016     {
1017         PRMSG(1, "TLIAccept() ioctl(I_PUSH,\"tirdwr\") failed %d\n",
1018               errno,0,0 );
1019         t_close(newciptr->fd);
1020         xfree(newciptr->addr);
1021         xfree(newciptr);
1022         *status = TRANS_ACCEPT_MISC_ERROR;
1023         return NULL;
1024     }
1025     
1026     *status = 0;
1027
1028     return newciptr;
1029 }
1030
1031 #endif /* TRANS_SERVER */
1032
1033
1034 #ifdef TRANS_CLIENT
1035
1036 static
1037 TRANS(TLIConnect)(ciptr, sndcall )
1038
1039 XtransConnInfo  ciptr;
1040 struct t_call   *sndcall;
1041
1042 {
1043     PRMSG(2, "TLIConnect(%x->%d,%x)\n", ciptr, ciptr->fd, sndcall);
1044     
1045     if( t_connect(ciptr->fd,sndcall,NULL) < 0 )
1046     {
1047         extern char *t_errlist[];
1048         extern int t_errno;
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)
1053         {
1054             t_rcvdis(ciptr->fd,NULL);
1055             return TRANS_TRY_CONNECT_AGAIN;
1056         }
1057         else
1058             return TRANS_CONNECT_FAILED;
1059     }
1060     
1061     t_free((char *)sndcall,T_CALL);
1062     
1063     /*
1064      * Sync up the address fields of ciptr.
1065      */
1066     
1067     if( TRANS(TLIGetAddr)(ciptr) < 0 )
1068     {
1069         PRMSG(1,
1070               "TLIConnect: ...TLIGetAddr() failed: %d\n",
1071               errno, 0,0 );
1072         return TRANS_CONNECT_FAILED;
1073     }
1074     
1075     if( TRANS(TLIGetPeerAddr)(ciptr) < 0 )
1076     {
1077         PRMSG(1,
1078               "TLIConnect: ...TLIGetPeerAddr() failed: %d\n",
1079               errno, 0,0 );
1080         return TRANS_CONNECT_FAILED;
1081     }
1082     
1083     if( ioctl(ciptr->fd, I_POP,"timod") < 0 )
1084     {
1085         PRMSG(1, "TLIConnect() ioctl(I_POP,\"timod\") failed %d\n",
1086               errno,0,0 );
1087         return TRANS_CONNECT_FAILED;
1088     }
1089     
1090     if( ioctl(ciptr->fd, I_PUSH,"tirdwr") < 0 )
1091     {
1092         PRMSG(1, "TLIConnect() ioctl(I_PUSH,\"tirdwr\") failed %d\n",
1093               errno,0,0 );
1094         return TRANS_CONNECT_FAILED;
1095     }
1096     
1097     return 0;
1098 }
1099
1100
1101 static
1102 TRANS(TLIINETConnect)(ciptr, host, port)
1103
1104 XtransConnInfo  ciptr;
1105 char            *host;
1106 char            *port;
1107
1108 {
1109 #define PORTBUFSIZE     64      /* what is a real size for this? */
1110     char        portbuf[PORTBUFSIZE];   
1111     struct      t_call  *sndcall;
1112     
1113     PRMSG(2, "TLIINETConnect(%s,%s)\n", host, port, 0);
1114     
1115 #ifdef X11_t
1116     /*
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.
1120      *
1121      * The port that is passed here is really a string containing the idisplay
1122      * from ConnectDisplay().
1123      */
1124     
1125     if (is_numeric (port))
1126     {
1127         short tmpport = (short) atoi (port);
1128         
1129         sprintf(portbuf,"%d", X_TCP_PORT+tmpport );
1130     }
1131     else
1132 #endif
1133         strncpy(portbuf,port,PORTBUFSIZE);
1134     
1135     if( (sndcall=(struct t_call *)t_alloc(ciptr->fd,T_CALL,T_ALL)) == NULL )
1136     {
1137         PRMSG(1, "TLIINETConnect() failed to allocate a t_call\n", 0,0,0 );
1138         return TRANS_CONNECT_FAILED;
1139     }
1140     
1141     if( TRANS(TLIAddrToNetbuf)(ciptr->index, host, portbuf, &(sndcall->addr) ) < 0 )
1142     {
1143         PRMSG(1, "TLIINETConnect() unable to resolve name:%s.%s\n",
1144               host, portbuf, 0 );
1145         t_free((char *)sndcall,T_CALL);
1146         return TRANS_CONNECT_FAILED;
1147     }
1148     
1149     return TRANS(TLIConnect)(ciptr, sndcall );
1150 }
1151
1152
1153 static
1154 TRANS(TLITLIConnect)(ciptr, host, port)
1155
1156 XtransConnInfo  ciptr;
1157 char            *host;
1158 char            *port;
1159
1160 {
1161     struct t_call       *sndcall;
1162     struct sockaddr_un  *sunaddr;
1163     
1164     PRMSG(2, "TLITLIConnect(%s,%s)\n", host, port, 0);
1165     
1166     if( (sndcall=(struct t_call *)t_alloc(ciptr->fd,T_CALL,T_OPT|T_UDATA)) == NULL )
1167     {
1168         PRMSG(1, "TLITLIConnect() failed to allocate a t_call\n", 0,0,0 );
1169         return TRANS_CONNECT_FAILED;
1170     }
1171     
1172     if( (sunaddr=(struct sockaddr_un *)
1173          malloc(sizeof(struct sockaddr_un))) == NULL )
1174     {
1175         PRMSG(1,
1176               "TLITLIConnect: failed to allocate a sockaddr_un\n",
1177               0,0,0 );
1178         t_free((char *)sndcall,T_CALL);
1179         return TRANS_CONNECT_FAILED;
1180     }
1181     
1182     sunaddr->sun_family=AF_UNIX;
1183     if( *port == '/' ||
1184         strncmp (port, TLINODENAME, strlen (TLINODENAME)) == 0) {
1185         /* Use the port as is */
1186         (void) strcpy(sunaddr->sun_path, port);
1187     } else {
1188         (void) sprintf(sunaddr->sun_path,"%s%s", TLINODENAME, port );
1189     }
1190
1191     sndcall->addr.buf=(char *)sunaddr;
1192     sndcall->addr.len=sizeof(*sunaddr);
1193     sndcall->addr.maxlen=sizeof(*sunaddr);
1194     
1195     return TRANS(TLIConnect)(ciptr, sndcall );
1196 }
1197
1198 #endif /* TRANS_CLIENT */
1199
1200
1201 static
1202 TRANS(TLIBytesReadable)(ciptr, pend)
1203
1204 XtransConnInfo  ciptr;
1205 BytesReadable_t *pend;
1206
1207 {
1208     int ret;
1209     struct pollfd filedes;
1210
1211     PRMSG(2, "TLIByteReadable(%x->%d,%x)\n", ciptr, ciptr->fd, pend );
1212
1213     /*
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.
1218      */
1219     
1220     ret=ioctl(ciptr->fd, I_NREAD, (char *)pend);
1221
1222     if( ret != 0 )
1223         return ret; /* Data present or error */
1224
1225
1226     /* Zero data, or POLLHUP message */
1227
1228     filedes.fd=ciptr->fd;
1229     filedes.events=POLLIN;
1230
1231     ret=poll(&filedes, 1, 0);
1232  
1233     if( ret == 0 ) {
1234         *pend=0;
1235         return 0; /* Really, no data */
1236         }
1237
1238     if( ret < 0 )
1239         return -1; /* just pass back the error */
1240
1241     if( filedes.revents & (POLLHUP|POLLERR) ) /* check for hangup */
1242         return -1;
1243
1244     /* Should only get here if data arrived after the first ioctl() */
1245     return ioctl(ciptr->fd, I_NREAD, (char *)pend);
1246 }
1247
1248
1249 static
1250 TRANS(TLIRead)(ciptr, buf, size)
1251
1252 XtransConnInfo  ciptr;
1253 char            *buf;
1254 int             size;
1255
1256 {
1257     PRMSG(2, "TLIRead(%d,%x,%d)\n", ciptr->fd, buf, size );
1258     
1259     return read(ciptr->fd,buf,size);
1260 }
1261
1262
1263 static
1264 TRANS(TLIWrite)(ciptr, buf, size)
1265
1266 XtransConnInfo  ciptr;
1267 char            *buf;
1268 int             size;
1269
1270 {
1271     PRMSG(2, "TLIWrite(%d,%x,%d)\n", ciptr->fd, buf, size );
1272     
1273     return write(ciptr->fd,buf,size);
1274 }
1275
1276
1277 static
1278 TRANS(TLIReadv)(ciptr, buf, size)
1279
1280 XtransConnInfo  ciptr;
1281 struct iovec    *buf;
1282 int             size;
1283
1284 {
1285     PRMSG(2, "TLIReadv(%d,%x,%d)\n", ciptr->fd, buf, size );
1286     
1287     return READV(ciptr,buf,size);
1288 }
1289
1290
1291 static
1292 TRANS(TLIWritev)(ciptr, buf, size)
1293
1294 XtransConnInfo  ciptr;
1295 struct iovec    *buf;
1296 int             size;
1297
1298 {
1299     PRMSG(2, "TLIWritev(%d,%x,%d)\n", ciptr->fd, buf, size );
1300     
1301     return WRITEV(ciptr,buf,size);
1302 }
1303
1304
1305 static
1306 TRANS(TLIDisconnect)(ciptr)
1307
1308 XtransConnInfo  ciptr;
1309
1310 {
1311     PRMSG(2, "TLIDisconnect(%x->%d)\n", ciptr, ciptr->fd, 0 );
1312     
1313     /*
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.
1317      */
1318     ioctl(ciptr->fd, I_POP,"tirdwr");
1319     ioctl(ciptr->fd, I_PUSH,"timod");
1320
1321     t_snddis(ciptr->fd,NULL);
1322     
1323     return 0;
1324 }
1325
1326
1327 static
1328 TRANS(TLIClose)(ciptr)
1329
1330 XtransConnInfo  ciptr;
1331
1332 {
1333     PRMSG(2, "TLIClose(%x->%d)\n", ciptr, ciptr->fd, 0 );
1334     
1335     t_unbind(ciptr->fd);
1336
1337     return (t_close(ciptr->fd));
1338 }
1339
1340
1341 static
1342 TRANS(TLICloseForCloning)(ciptr)
1343
1344 XtransConnInfo  ciptr;
1345
1346 {
1347     /*
1348      * Don't unbind.
1349      */
1350
1351     PRMSG(2, "TLICloseForCloning(%x->%d)\n", ciptr, ciptr->fd, 0 );
1352     
1353     return (t_close(ciptr->fd));
1354 }
1355
1356
1357 Xtransport      TRANS(TLITCPFuncs) = {
1358         /* TLI Interface */
1359         "tcp",
1360         0,
1361 #ifdef TRANS_CLIENT
1362         TRANS(TLIOpenCOTSClient),
1363 #endif /* TRANS_CLIENT */
1364 #ifdef TRANS_SERVER
1365         TRANS(TLIOpenCOTSServer),
1366 #endif /* TRANS_SERVER */
1367 #ifdef TRANS_CLIENT
1368         TRANS(TLIOpenCLTSClient),
1369 #endif /* TRANS_CLIENT */
1370 #ifdef TRANS_SERVER
1371         TRANS(TLIOpenCLTSServer),
1372 #endif /* TRANS_SERVER */
1373 #ifdef TRANS_REOPEN
1374         TRANS(TLIReopenCOTSServer),
1375         TRANS(TLIReopenCLTSServer),
1376 #endif
1377         TRANS(TLISetOption),
1378 #ifdef TRANS_SERVER
1379         TRANS(TLIINETCreateListener),
1380         NULL,                                   /* ResetListener */
1381         TRANS(TLIAccept),
1382 #endif /* TRANS_SERVER */
1383 #ifdef TRANS_CLIENT
1384         TRANS(TLIINETConnect),
1385 #endif /* TRANS_CLIENT */
1386         TRANS(TLIBytesReadable),
1387         TRANS(TLIRead),
1388         TRANS(TLIWrite),
1389         TRANS(TLIReadv),
1390         TRANS(TLIWritev),
1391         TRANS(TLIDisconnect),
1392         TRANS(TLIClose),
1393         TRANS(TLICloseForCloning),
1394 };
1395
1396 Xtransport      TRANS(TLIINETFuncs) = {
1397         /* TLI Interface */
1398         "inet",
1399         TRANS_ALIAS,
1400 #ifdef TRANS_CLIENT
1401         TRANS(TLIOpenCOTSClient),
1402 #endif /* TRANS_CLIENT */
1403 #ifdef TRANS_SERVER
1404         TRANS(TLIOpenCOTSServer),
1405 #endif /* TRANS_SERVER */
1406 #ifdef TRANS_CLIENT
1407         TRANS(TLIOpenCLTSClient),
1408 #endif /* TRANS_CLIENT */
1409 #ifdef TRANS_SERVER
1410         TRANS(TLIOpenCLTSServer),
1411 #endif /* TRANS_SERVER */
1412 #ifdef TRANS_REOPEN
1413         TRANS(TLIReopenCOTSServer),
1414         TRANS(TLIReopenCLTSServer),
1415 #endif
1416         TRANS(TLISetOption),
1417 #ifdef TRANS_SERVER
1418         TRANS(TLIINETCreateListener),
1419         NULL,                                   /* ResetListener */
1420         TRANS(TLIAccept),
1421 #endif /* TRANS_SERVER */
1422 #ifdef TRANS_CLIENT
1423         TRANS(TLIINETConnect),
1424 #endif /* TRANS_CLIENT */
1425         TRANS(TLIBytesReadable),
1426         TRANS(TLIRead),
1427         TRANS(TLIWrite),
1428         TRANS(TLIReadv),
1429         TRANS(TLIWritev),
1430         TRANS(TLIDisconnect),
1431         TRANS(TLIClose),
1432         TRANS(TLICloseForCloning),
1433 };
1434
1435 Xtransport      TRANS(TLITLIFuncs) = {
1436         /* TLI Interface */
1437         "tli",
1438         0,
1439 #ifdef TRANS_CLIENT
1440         TRANS(TLIOpenCOTSClient),
1441 #endif /* TRANS_CLIENT */
1442 #ifdef TRANS_SERVER
1443         TRANS(TLIOpenCOTSServer),
1444 #endif /* TRANS_SERVER */
1445 #ifdef TRANS_CLIENT
1446         TRANS(TLIOpenCLTSClient),
1447 #endif /* TRANS_CLIENT */
1448 #ifdef TRANS_SERVER
1449         TRANS(TLIOpenCLTSServer),
1450 #endif /* TRANS_SERVER */
1451 #ifdef TRANS_REOPEN
1452         TRANS(TLIReopenCOTSServer),
1453         TRANS(TLIReopenCLTSServer),
1454 #endif
1455         TRANS(TLISetOption),
1456 #ifdef TRANS_SERVER
1457         TRANS(TLITLICreateListener),
1458         NULL,                                   /* ResetListener */
1459         TRANS(TLIAccept),
1460 #endif /* TRANS_SERVER */
1461 #ifdef TRANS_CLIENT
1462         TRANS(TLITLIConnect),
1463 #endif /* TRANS_CLIENT */
1464         TRANS(TLIBytesReadable),
1465         TRANS(TLIRead),
1466         TRANS(TLIWrite),
1467         TRANS(TLIReadv),
1468         TRANS(TLIWritev),
1469         TRANS(TLIDisconnect),
1470         TRANS(TLIClose),
1471         TRANS(TLICloseForCloning),
1472 };