~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/lib/xtrans/Xtranstli.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

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