]> git.sesse.net Git - rdpsrv/blob - Xserver/lib/xtrans/Xtranslcl.c
Support RDP5 logon packets.
[rdpsrv] / Xserver / lib / xtrans / Xtranslcl.c
1 /* $XConsortium: Xtranslcl.c /main/27 1996/09/28 16:50:14 rws $ */
2 /* $XFree86: xc/lib/xtrans/Xtranslcl.c,v 3.21.2.3 1998/02/01 16:04:34 robin 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 /*
57  *
58  * The connection code/ideas in lib/X and server/os for SVR4/Intel 
59  * environments was contributed by the following companies/groups:
60  *
61  *      MetroLink Inc
62  *      NCR
63  *      Pittsburgh Powercomputing Corporation (PPc)/Quarterdeck Office Systems
64  *      SGCS
65  *      Unix System Laboratories (USL) / Novell
66  *      XFree86
67  *
68  * The goal is to have common connection code among all SVR4/Intel vendors.
69  *
70  * ALL THE ABOVE COMPANIES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 
71  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, 
72  * IN NO EVENT SHALL THESE COMPANIES * BE LIABLE FOR ANY SPECIAL, INDIRECT 
73  * OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 
74  * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 
75  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE 
76  * OR PERFORMANCE OF THIS SOFTWARE.
77  */
78
79 #include <errno.h>
80 #include <ctype.h>
81 #include <sys/signal.h>
82 #include <sys/ioctl.h>
83 #include <sys/stat.h>
84 #ifdef SVR4
85 #include <sys/filio.h>
86 #endif
87 #include <sys/stropts.h>
88 #include <sys/wait.h>
89
90 /*
91  * The local transports should be treated the same as a UNIX domain socket
92  * wrt authentication, etc. Because of this, we will use struct sockaddr_un
93  * for the address format. This will simplify the code in other places like
94  * The X Server.
95  */
96
97 #include <sys/socket.h>
98 #ifndef X_NO_SYS_UN
99 #include <sys/un.h>
100 #endif
101
102 #if defined(ISC) && !defined(_POSIX_SOURCE)
103 typedef unsigned short  mode_t;
104 /* POSIX needed for mode_t define in sys/types.h */
105 #endif
106
107 /*
108  * These functions actually implement the local connection mechanisms.
109  */
110
111 /* Type Not Supported */
112
113 static int
114 TRANS(OpenFail)(ciptr, port)
115
116 XtransConnInfo  ciptr;
117 char            *port;
118
119 {
120     return -1;
121 }
122
123 #ifdef TRANS_REOPEN
124
125 static int
126 TRANS(ReopenFail)(ciptr, fd, port)
127
128 XtransConnInfo  ciptr;
129 int             fd;
130 char            *port;
131
132 {
133     return 0;
134 }
135
136 #endif /* TRANS_REOPEN */
137
138
139 \f
140 static int
141 TRANS(FillAddrInfo)(ciptr, sun_path, peer_sun_path)
142
143 XtransConnInfo  ciptr;
144 char            *sun_path;
145 char            *peer_sun_path;
146
147 {
148     struct sockaddr_un  *sunaddr;
149     struct sockaddr_un  *p_sunaddr;
150
151     ciptr->family = AF_UNIX;
152     ciptr->addrlen = sizeof (struct sockaddr_un);
153
154     if ((sunaddr = (struct sockaddr_un *) xalloc (ciptr->addrlen)) == NULL)
155     {
156         PRMSG(1,"FillAddrInfo: failed to allocate memory for addr\n",
157                                                                         0,0,0);
158         return 0;
159     }
160
161     sunaddr->sun_family = AF_UNIX;
162
163     strcpy (sunaddr->sun_path, sun_path);
164 #if defined(BSD44SOCKETS) && !defined(Lynx)
165     sunaddr->sun_len = strlen (sunaddr->sun_path);
166 #endif
167
168     ciptr->addr = (char *) sunaddr;
169
170     ciptr->peeraddrlen = sizeof (struct sockaddr_un);
171
172     if ((p_sunaddr = (struct sockaddr_un *) xalloc (
173         ciptr->peeraddrlen)) == NULL)
174     {
175         PRMSG(1,
176            "FillAddrInfo: failed to allocate memory for peer addr\n",
177                                                                         0,0,0);
178         xfree ((char *) sunaddr);
179         ciptr->addr = NULL;
180
181         return 0;
182     }
183
184     p_sunaddr->sun_family = AF_UNIX;
185
186     strcpy (p_sunaddr->sun_path, peer_sun_path);
187 #if defined(BSD44SOCKETS) && !defined(Lynx)
188     p_sunaddr->sun_len = strlen (p_sunaddr->sun_path);
189 #endif
190
191     ciptr->peeraddr = (char *) p_sunaddr;
192
193     return 1;
194 }
195
196
197 \f
198 /* PTS */
199
200 #if defined(SYSV) && !defined(sco) && !defined(SCO) && !defined(ISC)
201 #define SIGNAL_T int
202 #else
203 #define SIGNAL_T void
204 #endif /* SYSV */
205
206 typedef SIGNAL_T (*PFV)();
207
208 extern PFV signal();
209
210 extern char *ptsname(
211 #if NeedFunctionPrototypes
212     int
213 #endif
214 );
215
216 static void _dummy(sig)
217
218 int sig;
219
220 {
221 }
222
223 #define X_STREAMS_DIR   "/dev/X"
224 #define DEV_PTMX        "/dev/ptmx"
225 #define DEV_SPX         "/dev/spx"
226
227 #if defined(X11_t)
228
229 #define PTSNODENAME "/dev/X/server."
230 #define NAMEDNODENAME "/dev/X/Nserver."
231
232 /*
233  * ISC and SCO are only defined for X11 since they are there for
234  * backwards binary compatability only.
235  */
236
237 #define X_ISC_DIR       "/dev/X/ISCCONN"
238 #define ISCDEVNODENAME  "/dev/X/ISCCONN/X%s"
239 #define ISCTMPNODENAME  "/tmp/.X11-unix/X%s"
240 #define SCORNODENAME    "/dev/X%1sR"
241 #define SCOSNODENAME    "/dev/X%1sS"
242 #endif
243 #if defined(XIM_t)
244 #define PTSNODENAME     "/dev/X/XIM."
245 #define NAMEDNODENAME   "/dev/X/NXIM."
246 #endif
247 #if defined(FS_t) || defined (FONT_t)
248 /*
249  * USL has already defined something here. We need to check with them
250  * and see if their choice is usable here.
251  */
252 #define PTSNODENAME     "/dev/X/fontserver."
253 #define NAMEDNODENAME   "/dev/X/Nfontserver."
254 #endif
255 #if defined(ICE_t)
256 #define PTSNODENAME     "/dev/X/ICE."
257 #define NAMEDNODENAME   "/dev/X/NICE."
258 #endif
259 #if defined(TEST_t)
260 #define PTSNODENAME     "/dev/X/transtest."
261 #define NAMEDNODENAME   "/dev/X/Ntranstest."
262 #endif
263
264
265 \f
266 #ifdef TRANS_CLIENT
267
268 static int
269 TRANS(PTSOpenClient)(ciptr, port)
270
271 XtransConnInfo  ciptr;
272 char            *port;
273
274 {
275     int                 fd,server,exitval,alarm_time,ret;
276     char                server_path[64];
277     char                *slave, namelen;
278     char                buf[20]; /* MAX_PATH_LEN?? */
279     PFV                 savef;
280
281     PRMSG(2,"PTSOpenClient(%s)\n", port, 0,0 );
282
283 #if !defined(PTSNODENAME)
284     PRMSG(1,"PTSOpenClient: Protocol is not supported by a pts connection\n", 0,0,0);
285     return -1;
286 #else
287     if (port && *port ) {
288         if( *port == '/' ) { /* A full pathname */
289                 (void) sprintf(server_path, "%s", port);
290             } else {
291                 (void) sprintf(server_path, "%s%s", PTSNODENAME, port);
292             }
293     } else {
294         (void) sprintf(server_path, "%s%d", PTSNODENAME, getpid());
295     }
296
297
298     /*
299      * Open the node the on which the server is listening.
300      */
301
302     if ((server = open (server_path, O_RDWR)) < 0) {
303         PRMSG(1,"PTSOpenClient: failed to open %s\n", server_path, 0,0);
304         return -1;
305     }
306
307
308     /*
309      * Open the streams based pipe that will be this connection.
310      */
311
312     if ((fd = open("/dev/ptmx", O_RDWR)) < 0) {
313         PRMSG(1,"PTSOpenClient: failed to open /dev/ptmx\n", 0,0,0);
314         return -1;
315     }
316
317     (void) grantpt(fd);
318     (void) unlockpt(fd);
319
320     slave = ptsname(fd); /* get name */
321
322     if( slave == NULL ) {
323         PRMSG(1,"PTSOpenClient: failed to get ptsname()\n", 0,0,0);
324         close(fd);
325         close(server);
326         return -1;
327     }
328
329     /*
330      * This is neccesary for the case where a program is setuid to non-root.
331      * grantpt() calls /usr/lib/pt_chmod which is set-uid root. This program will
332      * set the owner of the pt device incorrectly if the uid is not restored
333      * before it is called. The problem is that once it gets restored, it
334      * cannot be changed back to its original condition, hence the fork().
335      */
336
337     if( !fork()) {
338         uid_t       saved_euid;
339
340         saved_euid = geteuid();
341         setuid( getuid() ); /** sets the euid to the actual/real uid **/
342         if( chown( slave, saved_euid, -1 ) < 0 ) {
343                 exit( 1 );
344                 }
345
346         exit( 0 );
347     }
348
349     wait( &exitval );
350
351     if (chmod(slave, 0666) < 0) {
352         close(fd);
353         close(server);
354         PRMSG(1,"PTSOpenClient: Cannot chmod %s\n", slave, 0,0);
355         return(-1);
356     }
357
358     /*
359      * write slave name to server
360      */
361
362     namelen = strlen(slave);
363     buf[0] = namelen;
364     (void) sprintf(&buf[1], slave);
365     (void) write(server, buf, namelen+1);
366     (void) close(server);
367
368     /*
369      * wait for server to respond
370      */
371
372     savef = signal(SIGALRM, _dummy);
373     alarm_time = alarm (30); /* CONNECT_TIMEOUT */
374
375     ret = read(fd, buf, 1);
376
377     (void) alarm(alarm_time);
378     (void) signal(SIGALRM, savef);
379
380     if (ret != 1) {
381         PRMSG(1,
382         "PTSOpenClient: failed to get acknoledgement from server\n",
383                                                                         0,0,0);
384         (void) close(fd);
385         fd = -1;
386     }
387
388     /*
389      * Everything looks good: fill in the XtransConnInfo structure.
390      */
391
392     if (TRANS(FillAddrInfo) (ciptr, slave, server_path) == 0)
393     {
394         PRMSG(1,"PTSOpenClient: failed to fill in addr info\n",
395                                                                 0,0,0);
396         close(fd);
397         return -1;
398     }
399
400     return(fd);
401
402 #endif /* !PTSNODENAME */
403 }
404
405 #endif /* TRANS_CLIENT */
406
407
408 #ifdef TRANS_SERVER
409
410 static int
411 TRANS(PTSOpenServer)(ciptr, port)
412
413 XtransConnInfo  ciptr;
414 char            *port;
415
416 {
417     int fd, server;
418     char server_path[64], *slave;
419
420     PRMSG(2,"PTSOpenServer(%s)\n", port, 0,0 );
421
422 #if !defined(PTSNODENAME)
423     PRMSG(1,"PTSOpenServer: Protocol is not supported by a pts connection\n", 0,0,0);
424     return -1;
425 #else
426     if (port && *port ) {
427         if( *port == '/' ) { /* A full pathname */
428                 (void) sprintf(server_path, "%s", port);
429             } else {
430                 (void) sprintf(server_path, "%s%s", PTSNODENAME, port);
431             }
432     } else {
433         (void) sprintf(server_path, "%s%d", PTSNODENAME, getpid());
434     }
435
436     mkdir(X_STREAMS_DIR, 0777);
437     chmod(X_STREAMS_DIR, 0777);
438
439     if( (fd=open(server_path, O_RDWR)) >= 0 ) {
440 #if 0
441         /*
442          * This doesn't prevent the server from starting up, and doesn't
443          * prevent clients from trying to connect to the in-use PTS (which
444          * is often in use by something other than another server).
445          */
446         PRMSG(1, "PTSOpenServer: A server is already running on port %s\n", port, 0,0 );
447         PRMSG(1, "PTSOpenServer: Remove %s if this is incorrect.\n", server_path, 0,0 );
448         close(fd);
449         return(-1);
450 #else
451         /* Just remove the old path (which is what happens with UNIXCONN) */
452         ;
453 #endif
454     }
455
456     unlink(server_path);
457
458     if( (fd=open(DEV_PTMX, O_RDWR)) < 0) {
459         PRMSG(1, "PTSOpenServer: Unable to open %s\n", DEV_PTMX, 0,0 );
460         return(-1);
461     }
462
463     grantpt(fd);
464     unlockpt(fd);
465
466     if( (slave=ptsname(fd)) == NULL) {
467         PRMSG(1, "PTSOpenServer: Unable to get slave device name\n", 0,0,0 );
468         close(fd);
469         return(-1);
470     }
471
472     if( link(slave,server_path) < 0 ) {
473         PRMSG(1, "PTSOpenServer: Unable to link %s to %s\n", slave, server_path,0 );
474         close(fd);
475         return(-1);
476     }
477
478     if( chmod(server_path, 0666) < 0 ) {
479         PRMSG(1, "PTSOpenServer: Unable to chmod %s to 0666\n", server_path,0,0 );
480         close(fd);
481         return(-1);
482     }
483
484     if( (server=open(server_path, O_RDWR)) < 0 ) {
485         PRMSG(1, "PTSOpenServer: Unable to open server device %s\n", server_path,0,0 );
486         close(fd);
487         return(-1);
488     }
489
490     close(server);
491
492     /*
493      * Everything looks good: fill in the XtransConnInfo structure.
494      */
495
496     if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
497     {
498         PRMSG(1,"PTSOpenServer: failed to fill in addr info\n",
499                                                                 0,0,0);
500         close(fd);
501         return -1;
502     }
503
504     return fd;
505
506 #endif /* !PTSNODENAME */
507 }
508
509 static int
510 TRANS(PTSAccept)(ciptr, newciptr, status)
511
512 XtransConnInfo  ciptr;
513 XtransConnInfo  newciptr;
514 int             *status;
515
516 {
517     int                 newfd;
518     int                 in;
519     unsigned char       length;
520     char                buf[256];
521     struct sockaddr_un  *sunaddr;
522
523     PRMSG(2,"PTSAccept(%x->%d)\n",ciptr,ciptr->fd,0);
524
525     if( (in=read(ciptr->fd,&length,1)) <= 0 ){
526         if( !in ) {
527                 PRMSG(2,
528                 "PTSAccept: Incoming connection closed\n",0,0,0);
529                 }
530         else {
531                 PRMSG(1,
532         "PTSAccept: Error reading incoming connection. errno=%d \n",
533                                                                 errno,0,0);
534                 }
535         *status = TRANS_ACCEPT_MISC_ERROR;
536         return -1;
537     }
538
539     if( (in=read(ciptr->fd,buf,length)) <= 0 ){
540         if( !in ) {
541                 PRMSG(2,
542                 "PTSAccept: Incoming connection closed\n",0,0,0);
543                 }
544         else {
545                 PRMSG(1,
546 "PTSAccept: Error reading device name for new connection. errno=%d \n",
547                                                                 errno,0,0);
548                 }
549         *status = TRANS_ACCEPT_MISC_ERROR;
550         return -1;
551     }
552
553     buf[length] = '\0';
554
555     if( (newfd=open(buf,O_RDWR)) < 0 ) {
556         PRMSG(1, "PTSAccept: Failed to open %s\n",buf,0,0);
557         *status = TRANS_ACCEPT_MISC_ERROR;
558         return -1;
559     }
560
561     write(newfd,"1",1);
562
563     /*
564      * Everything looks good: fill in the XtransConnInfo structure.
565      */
566
567     newciptr->addrlen=ciptr->addrlen;
568     if( (newciptr->addr=(char *)xalloc(newciptr->addrlen)) == NULL ) {
569         PRMSG(1,"PTSAccept: failed to allocate memory for peer addr\n",
570                                                                         0,0,0);
571         close(newfd);
572         *status = TRANS_ACCEPT_BAD_MALLOC;
573         return -1;
574     }
575
576     memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen);
577
578     newciptr->peeraddrlen=sizeof(struct sockaddr_un);
579     if( (sunaddr=(struct sockaddr_un *)xalloc(newciptr->peeraddrlen)) == NULL ) {
580         PRMSG(1,"PTSAccept: failed to allocate memory for peer addr\n",
581                                                                         0,0,0);
582         xfree(newciptr->addr);
583         close(newfd);
584         *status = TRANS_ACCEPT_BAD_MALLOC;
585         return -1;
586     }
587
588     sunaddr->sun_family=AF_UNIX;
589     strcpy(sunaddr->sun_path,buf);
590 #if defined(BSD44SOCKETS) && !defined(Lynx)
591     sunaddr->sun_len=strlen(sunaddr->sun_path);
592 #endif
593
594     newciptr->peeraddr=(char *)sunaddr;
595
596     *status = 0;
597
598     return newfd;
599 }
600
601 #endif /* TRANS_SERVER */
602
603 \f
604 #ifdef SVR4
605
606 /* NAMED */
607
608 #ifdef TRANS_CLIENT
609
610 static int
611 TRANS(NAMEDOpenClient)(ciptr, port)
612
613 XtransConnInfo  ciptr;
614 char            *port;
615
616 {
617     int                 fd;
618     char                server_path[64];
619     struct stat         filestat;
620     extern int          isastream();
621
622     PRMSG(2,"NAMEDOpenClient(%s)\n", port, 0,0 );
623
624 #if !defined(NAMEDNODENAME)
625     PRMSG(1,"NAMEDOpenClient: Protocol is not supported by a NAMED connection\n", 0,0,0);
626     return -1;
627 #else
628     if ( port && *port ) {
629         if( *port == '/' ) { /* A full pathname */
630                 (void) sprintf(server_path, "%s", port);
631             } else {
632                 (void) sprintf(server_path, "%s%s", NAMEDNODENAME, port);
633             }
634     } else {
635         (void) sprintf(server_path, "%s%d", NAMEDNODENAME, getpid());
636     }
637
638     if (stat(server_path, &filestat) < 0 ) {
639         PRMSG(1,"NAMEDOpenClient: No device %s for NAMED connection\n", server_path, 0,0 );
640         return -1;
641     }
642
643     if ((filestat.st_mode & S_IFMT) != S_IFIFO) {
644         PRMSG(1,"NAMEDOpenClient: Device %s is not a FIFO\n", server_path, 0,0 );
645         /* Is this really a failure? */
646         return -1;
647     }
648
649     if ((fd = open(server_path, O_RDWR)) < 0) {
650         PRMSG(1,"NAMEDOpenClient: Cannot open %s for NAMED connection\n", server_path, 0,0 );
651         return -1;
652     }
653
654     if (isastream(fd) <= 0) {
655         PRMSG(1,"NAMEDOpenClient: %s is not a streams device\n", server_path, 0,0 );
656         (void) close(fd);
657         return -1;
658     }
659
660     /*
661      * Everything looks good: fill in the XtransConnInfo structure.
662      */
663
664     if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
665     {
666         PRMSG(1,"NAMEDOpenClient: failed to fill in addr info\n",
667                                                                 0,0,0);
668         close(fd);
669         return -1;
670     }
671
672     return(fd);
673
674 #endif /* !NAMEDNODENAME */
675 }
676
677 #endif /* TRANS_CLIENT */
678
679
680 #ifdef TRANS_SERVER
681
682 static int
683 TRANS(NAMEDOpenServer)(ciptr, port)
684
685 XtransConnInfo  ciptr;
686 char            *port;
687
688 {
689     int                 fd, pipefd[2];
690     char                server_path[64];
691     struct stat         sbuf;
692
693     PRMSG(2,"NAMEDOpenServer(%s)\n", port, 0,0 );
694
695 #if !defined(NAMEDNODENAME)
696     PRMSG(1,"NAMEDOpenServer: Protocol is not supported by a NAMED connection\n", 0,0,0);
697     return -1;
698 #else
699     if ( port && *port ) {
700         if( *port == '/' ) { /* A full pathname */
701             (void) sprintf(server_path, "%s", port);
702         } else {
703             (void) sprintf(server_path, "%s%s", NAMEDNODENAME, port);
704         }
705     } else {
706         (void) sprintf(server_path, "%s%d", NAMEDNODENAME, getpid());
707     }
708
709     mkdir(X_STREAMS_DIR, 0777);
710     chmod(X_STREAMS_DIR, 0777);
711
712     if(stat(server_path, &sbuf) != 0) {
713         if (errno == ENOENT) {
714             if ((fd = creat(server_path, (mode_t)0666)) == -1) {
715                 PRMSG(1, "NAMEDOpenServer: Can't open %s\n", server_path, 0,0 );
716                 return(-1);
717             }
718             close(fd);
719             if (chmod(server_path, (mode_t)0666) < 0) {
720                 PRMSG(1, "NAMEDOpenServer: Can't open %s\n", server_path, 0,0 );
721                 return(-1);
722             }
723         } else {
724             PRMSG(1, "NAMEDOpenServer: stat on %s failed\n", server_path, 0,0 );
725             return(-1);
726         }
727     }
728
729     if( pipe(pipefd) != 0) {
730         PRMSG(1, "NAMEDOpenServer: pipe() failed, errno=%d\n",errno, 0,0 );
731         return(-1);
732     }
733
734     if( ioctl(pipefd[0], I_PUSH, "connld") != 0) {
735         PRMSG(1, "NAMEDOpenServer: ioctl(I_PUSH,\"connld\") failed, errno=%d\n",errno, 0,0 );
736         close(pipefd[0]);
737         close(pipefd[1]);
738         return(-1);
739     }
740
741     if( fattach(pipefd[0], server_path) != 0) {
742         PRMSG(1, "NAMEDOpenServer: fattach(%s) failed, errno=%d\n", server_path,errno, 0 );
743         close(pipefd[0]);
744         close(pipefd[1]);
745         return(-1);
746     }
747
748     /*
749      * Everything looks good: fill in the XtransConnInfo structure.
750      */
751
752     if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
753     {
754         PRMSG(1,"NAMEDOpenServer: failed to fill in addr info\n",
755                                                                 0,0,0);
756         close(fd);
757         return -1;
758     }
759
760     return(pipefd[1]);
761
762 #endif /* !NAMEDNODENAME */
763 }
764
765 static int
766 TRANS(NAMEDAccept)(ciptr, newciptr, status)
767
768 XtransConnInfo  ciptr;
769 XtransConnInfo  newciptr;
770 int             *status;
771
772 {
773     struct strrecvfd str;
774
775     PRMSG(2,"NAMEDAccept(%x->%d)\n", ciptr, ciptr->fd, 0 );
776
777     if( ioctl(ciptr->fd, I_RECVFD, &str ) < 0 ) {
778         PRMSG(1, "NAMEDAccept: ioctl(I_RECVFD) failed, errno=%d\n", errno, 0,0 );
779         *status = TRANS_ACCEPT_MISC_ERROR;
780         return(-1);
781     }
782
783     /*
784      * Everything looks good: fill in the XtransConnInfo structure.
785      */
786
787     newciptr->addrlen=ciptr->addrlen;
788     if( (newciptr->addr=(char *)xalloc(newciptr->addrlen)) == NULL ) {
789         PRMSG(1,
790               "NAMEDAccept: failed to allocate memory for peer addr\n",
791                                                                         0,0,0);
792         close(str.fd);
793         *status = TRANS_ACCEPT_BAD_MALLOC;
794         return -1;
795     }
796
797     memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen);
798
799     newciptr->peeraddrlen=newciptr->addrlen;
800     if( (newciptr->peeraddr=(char *)xalloc(newciptr->peeraddrlen)) == NULL ) {
801         PRMSG(1,
802         "NAMEDAccept: failed to allocate memory for peer addr\n",
803                                                                         0,0,0);
804         xfree(newciptr->addr);
805         close(str.fd);
806         *status = TRANS_ACCEPT_BAD_MALLOC;
807         return -1;
808     }
809
810     memcpy(newciptr->peeraddr,newciptr->addr,newciptr->peeraddrlen);
811
812     *status = 0;
813
814     return str.fd;
815 }
816
817 #endif /* TRANS_SERVER */
818
819 #endif /* SVR4 */
820
821
822 \f
823 /*
824  * connect_spipe is used by both the SCO and ISC connection types.
825  */
826 static int
827 connect_spipe(fd1, fd2)
828
829 int     fd1, fd2;
830
831 {
832     long temp;
833     struct strfdinsert sbuf;
834
835     sbuf.databuf.maxlen = -1;
836     sbuf.databuf.len = -1;
837     sbuf.databuf.buf = NULL;
838     sbuf.ctlbuf.maxlen = sizeof(long);
839     sbuf.ctlbuf.len = sizeof(long);
840     sbuf.ctlbuf.buf = (caddr_t)&temp;
841     sbuf.offset = 0;
842     sbuf.fildes = fd2;
843     sbuf.flags = 0;
844
845     if( ioctl(fd1, I_FDINSERT, &sbuf) < 0 )
846         return(-1);
847
848     return(0);
849 }
850
851 /*
852  * connect_spipe is used by both the SCO and ISC connection types.
853  */
854
855 static int
856 named_spipe(fd, path)
857
858 int     fd;
859 char    *path;
860
861 {
862     int oldUmask, ret;
863     struct stat sbuf;
864
865     oldUmask = umask(0);
866
867     (void) fstat(fd, &sbuf);
868     ret = mknod(path, 0020666, sbuf.st_rdev);
869
870     umask(oldUmask);
871
872     if (ret < 0) {
873         ret = -1;
874     } else {
875         ret = fd;
876     }
877     
878     return(ret);
879 }
880
881 \f
882 /* ISC */
883
884 #ifdef TRANS_CLIENT
885
886 static int
887 TRANS(ISCOpenClient)(ciptr, port)
888
889 XtransConnInfo  ciptr;
890 char            *port;
891
892 {
893     int         fd,fds,server;
894     char        server_path[64];
895     char        server_dev_path[64];
896     struct      strfdinsert buf;
897     long        temp;
898     mode_t      spmode;
899     struct stat         filestat;
900     
901     PRMSG(2,"ISCOpenClient(%s)\n", port, 0,0 );
902     
903 #if !defined(ISCDEVNODENAME)
904     PRMSG(1,"ISCOpenClient: Protocol is not supported by a ISC connection\n", 0,0,0);
905     return -1;
906 #else
907     (void) sprintf(server_path, ISCTMPNODENAME, port);
908     (void) sprintf(server_dev_path, ISCDEVNODENAME, port);
909
910     fd = fds = server = -1;
911
912     if (stat(DEV_SPX, &filestat) == -1) {
913         PRMSG(1, "ISCOpenClient: stat(%s) failed, errno=%d\n", DEV_SPX, errno, 0 );
914         return(-1);
915     }
916
917     spmode = (filestat.st_mode & S_IFMT);
918
919     if (stat(server_path, &filestat) != -1) {
920         if ((filestat.st_mode & S_IFMT) == spmode) {
921             if ((server = open(server_path, O_RDWR)) < 0) {
922                 PRMSG(1,"ISCOpenClient: failed to open %s\n",
923                       server_path, 0,0 );
924             }
925         }
926     }
927     
928     if (server < 0) {
929         /* try the alternate path */
930         if (stat(server_dev_path, &filestat) != -1) {
931             if ((filestat.st_mode & S_IFMT) == spmode) {
932                 if ((server = open(server_dev_path, O_RDWR)) < 0) {
933                     PRMSG(1,"ISCOpenClient: failed to open %s\n",
934                           server_dev_path, 0,0 );
935                 }
936             }
937         }
938     }
939     
940     if (server < 0) {
941         PRMSG(1,"ISCOpenClient: can't open either device %s or %s\n",
942               server_path, server_dev_path, 0 );
943         return -1;
944     }
945
946     if ((fds = open(DEV_SPX, O_RDWR)) < 0 ||
947         (fd  = open(DEV_SPX, O_RDWR)) < 0) {
948         /* Failed to open all of the devices */
949         PRMSG(1,"ISCOpenClient: can't open %s\n", DEV_SPX, 0,0 );
950         (void) close(server);
951         if (fds != -1)
952             (void) close(fds);
953         if (fd != -1)
954             (void) close(fd);
955         return -1;
956     }
957
958     /* make a STREAMS-pipe */
959
960     buf.databuf.maxlen = -1;
961     buf.databuf.len = -1;
962     buf.databuf.buf = NULL;
963     buf.ctlbuf.maxlen = sizeof(long);
964     buf.ctlbuf.len = sizeof(long);
965     buf.ctlbuf.buf = (caddr_t)&temp;
966     buf.offset = 0;
967     buf.fildes = fd;
968     buf.flags = 0;
969     
970     if (ioctl(fds, I_FDINSERT, &buf) < 0 ||
971         ioctl(server, I_SENDFD, fds) < 0) {
972         PRMSG(1,"ISCOpenClient: ioctl(I_FDINSERT or I_SENDFD) failed\n",
973                                                                 0,0,0 );
974         (void) close(server);
975         (void) close(fds);
976         (void) close(fd);
977         return -1;
978     }
979
980     /*
981      * Everything looks good: fill in the XtransConnInfo structure.
982      */
983     
984     if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
985     {
986         PRMSG(1,"ISCOpenClient: failed to fill in addr info\n",
987                                                                 0,0,0);
988         close(fd);
989         return -1;
990     }
991
992     return (fd);
993
994 #endif /* !ISCDEVNODENAME */
995 }
996
997 #endif /* TRANS_CLIENT */
998
999
1000 #ifdef TRANS_SERVER
1001
1002 static int
1003 TRANS(ISCOpenServer)(ciptr, port)
1004
1005 XtransConnInfo  ciptr;
1006 char            *port;
1007
1008 {
1009     int fd = -1,fds = -1;
1010     char        server_path[64],server_unix_path[64];
1011     
1012     PRMSG(2,"ISCOpenServer(%s)\n", port, 0,0 );
1013     
1014 #if !defined(ISCDEVNODENAME)
1015     PRMSG(1,"ISCOpenServer: Protocol is not supported by a ISC connection\n", 0,0,0);
1016     return -1;
1017 #else
1018     (void) sprintf(server_path, ISCDEVNODENAME, port);
1019     (void) sprintf(server_unix_path, ISCTMPNODENAME, port);
1020     
1021     mkdir(X_STREAMS_DIR, 0777); /* "/dev/X" */
1022     chmod(X_STREAMS_DIR, 0777);
1023     mkdir(X_ISC_DIR, 0777); /* "/dev/X/ISCCONN" */
1024     chmod(X_ISC_DIR, 0777);
1025     
1026     unlink(server_path);
1027     
1028     if( ((fds=open(DEV_SPX, O_RDWR)) < 0) ||
1029        ((fd =open(DEV_SPX, O_RDWR)) < 0)) {
1030         PRMSG(1,"ISCOpenServer: failed to open %s\n", DEV_SPX, 0,0 );
1031         return -1;
1032     }
1033     
1034     if( (connect_spipe(fds, fd) < 0) ||
1035        (named_spipe(fds, server_path) < 0)) {
1036         PRMSG(1,"ISCOpenServer: failed connect pipes\n", 0,0,0 );
1037         close(fd);
1038         close(fds);
1039         return -1;
1040     }
1041     
1042 #if !defined(UNIXCONN)
1043     /*
1044      * If the UNIX Domain socket transport is not being used, then link this
1045      * device to the path /tmp/.X11-unix/X path.
1046      */
1047 #define X_UNIX_DIR      "/tmp/.X11-unix"
1048     
1049     if (!mkdir(X_UNIX_DIR, 01777))
1050         chmod(X_UNIX_DIR, 01777);
1051     
1052     unlink(server_unix_path);
1053     
1054 #ifdef SVR4
1055     /* we prefer symbolic links because hard links can't cross file systems */
1056     if( symlink(server_path, server_unix_path) < 0 )
1057         PRMSG(1,"ISCOpenServer: failed to link %s to %s\n",
1058               server_path, server_unix_path, 0 );
1059     /*
1060      * Don't make this failure fatal since the listener 
1061      * is already established, and this just for compatability
1062      */
1063 #else
1064 #ifdef ISC40
1065     /* catch SIGSYS on symlink for ISC40 compiled binaries running on ISC30 */
1066     signal(SIGSYS,_dummy);
1067 #endif
1068     if( link(server_path, server_unix_path) < 0 )
1069 #ifdef ISC40
1070       if( symlink(server_path, server_unix_path) < 0 )
1071 #endif
1072         PRMSG(1,"ISCOpenServer: failed to link %s to %s\n",
1073               server_path, server_unix_path, 0 );
1074     /*
1075      * Don't make this failure fatal since the listener 
1076      * is already established, and this just for compatability
1077      */
1078 #endif /* SVR4 */
1079 #endif /* !UNIXCONN */
1080     
1081     /*
1082      * Everything looks good: fill in the XtransConnInfo structure.
1083      */
1084     
1085     if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
1086     {
1087         PRMSG(1,"ISCOpenServer: failed to fill in addr info\n",
1088                                                                 0,0,0);
1089         close(fd);
1090         return -1;
1091     }
1092
1093     return fd;
1094
1095 #endif /* !ISCDEVNODENAME */
1096 }
1097
1098 static int
1099 TRANS(ISCAccept)(ciptr, newciptr, status)
1100
1101 XtransConnInfo  ciptr;
1102 XtransConnInfo  newciptr;
1103 int             *status;
1104
1105 {
1106     struct strrecvfd str;
1107     
1108     PRMSG(2,"ISCAccept(%d)\n", ciptr->fd, 0,0 );
1109     
1110     while (ioctl(ciptr->fd, I_RECVFD, &str) < 0) {
1111         if (errno != EAGAIN) {
1112             PRMSG(1,"ISCAccept: Can't read fildes", 0,0,0 );
1113             *status = TRANS_ACCEPT_MISC_ERROR;
1114             return(-1);
1115         }
1116     }
1117     
1118     /*
1119      * Everything looks good: fill in the XtransConnInfo structure.
1120      */
1121     
1122     newciptr->addrlen=ciptr->addrlen;
1123     if( (newciptr->addr=(char *)xalloc(newciptr->addrlen)) == NULL ) {
1124         PRMSG(1,
1125               "ISCAccept: failed to allocate memory for peer addr\n",
1126               0,0,0);
1127         close(str.fd);
1128         *status = TRANS_ACCEPT_BAD_MALLOC;
1129         return -1;
1130     }
1131     
1132     memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen);
1133     
1134     newciptr->peeraddrlen=newciptr->addrlen;
1135     if( (newciptr->peeraddr=(char *)xalloc(newciptr->peeraddrlen)) == NULL ) {
1136         PRMSG(1,
1137               "ISCAccept: failed to allocate memory for peer addr\n",
1138               0,0,0);
1139         xfree(newciptr->addr);
1140         close(str.fd);
1141         *status = TRANS_ACCEPT_BAD_MALLOC;
1142         return -1;
1143     }
1144     
1145     memcpy(newciptr->peeraddr,newciptr->addr,newciptr->peeraddrlen);
1146     
1147     *status = 0;
1148
1149     return(str.fd);
1150 }
1151
1152 #endif /* TRANS_SERVER */
1153
1154
1155 \f
1156
1157 /* SCO */
1158
1159 #ifdef TRANS_CLIENT
1160
1161 static int
1162 TRANS(SCOOpenClient)(ciptr, port)
1163
1164 XtransConnInfo  ciptr;
1165 char            *port;
1166
1167 {
1168     int                 fd, server, fl, ret;
1169     char                server_path[64];
1170     struct strbuf       ctlbuf;
1171     unsigned long       alarm_time;
1172     void                (*savef)();
1173     long                temp;
1174     extern int  getmsg(), putmsg();
1175     
1176     PRMSG(2,"SCOOpenClient(%s)\n", port, 0,0 );
1177     
1178 #if !defined(SCORNODENAME)
1179     PRMSG(1,"SCOOpenClient: Protocol is not supported by a SCO connection\n", 0,0,0);
1180     return -1;
1181 #else
1182     (void) sprintf(server_path, SCORNODENAME, port);
1183     
1184     if ((server = open(server_path, O_RDWR)) < 0) {
1185         PRMSG(1,"SCOOpenClient: failed to open %s\n", server_path, 0,0 );
1186         return -1;
1187     }
1188     
1189     if ((fd = open(DEV_SPX, O_RDWR)) < 0) {
1190         PRMSG(1,"SCOOpenClient: failed to open %s\n", DEV_SPX, 0,0 );
1191         close(server);
1192         return -1;
1193     }
1194     
1195     (void) write(server, &server, 1);
1196     ctlbuf.len = 0;
1197     ctlbuf.maxlen = sizeof(long);
1198     ctlbuf.buf = (caddr_t)&temp;
1199     fl = 0;
1200     
1201     savef = signal(SIGALRM, _dummy);
1202     alarm_time = alarm(10);
1203     
1204     ret = getmsg(server, &ctlbuf, 0, &fl);
1205     
1206     (void) alarm(alarm_time);
1207     (void) signal(SIGALRM, savef);
1208     
1209     if (ret < 0) {
1210         PRMSG(1,"SCOOpenClient: error from getmsg\n", 0,0,0 );
1211         close(fd);
1212         close(server);
1213         return -1;
1214     }
1215     
1216     /* The msg we got via getmsg is the result of an
1217      * I_FDINSERT, so if we do a putmsg with whatever
1218      * we recieved, we're doing another I_FDINSERT ...
1219      */
1220     (void) putmsg(fd, &ctlbuf, 0, 0);
1221     (void) fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,0)|O_NDELAY);
1222     
1223     (void) close(server);
1224     
1225     /*
1226      * Everything looks good: fill in the XtransConnInfo structure.
1227      */
1228     
1229     if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
1230     {
1231         PRMSG(1,"SCOOpenClient: failed to fill addr info\n",
1232               0,0,0);
1233         close(fd);
1234         return -1;
1235     }
1236     
1237     return(fd);
1238
1239 #endif  /* !SCORNODENAME */
1240 }
1241
1242 #endif /* TRANS_CLIENT */
1243
1244
1245 #ifdef TRANS_SERVER
1246
1247 static int
1248 TRANS(SCOOpenServer)(ciptr, port)
1249
1250 XtransConnInfo  ciptr;
1251 char            *port;
1252
1253 {
1254     char                serverR_path[64];
1255     char                serverS_path[64];
1256     int fdr = -1;
1257     int fds = -1;
1258     
1259     PRMSG(2,"SCOOpenServer(%s)\n", port, 0,0 );
1260     
1261 #if !defined(SCORNODENAME)
1262     PRMSG(1,"SCOOpenServer: Protocol is not supported by a SCO connection\n", 0,0,0);
1263     return -1;
1264 #else
1265     (void) sprintf(serverR_path, SCORNODENAME, port);
1266     (void) sprintf(serverS_path, SCOSNODENAME, port);
1267     
1268     unlink(serverR_path);
1269     unlink(serverS_path);
1270     
1271     if ((fds = open(DEV_SPX, O_RDWR)) < 0 ||
1272         (fdr = open(DEV_SPX, O_RDWR)) < 0 ) {
1273         PRMSG(2,"SCOOpenServer: failed to open %s\n", DEV_SPX, 0,0 );
1274         return -1;
1275     }
1276     
1277     if (connect_spipe(fds, fdr) != -1 &&
1278         named_spipe(fds, serverS_path) != -1 &&
1279         named_spipe(fdr, serverR_path) != -1) {
1280         PRMSG(2,"SCOOpenServer: connect pipes\n", 0,0,0 );
1281         } else {
1282         PRMSG(2,"SCOOpenServer: failed to connect pipes\n", 0,0,0 );
1283         close(fds);
1284         close(fdr);
1285         return -1;
1286     }
1287     
1288     /*
1289      * Everything looks good: fill in the XtransConnInfo structure.
1290      */
1291     
1292     if (TRANS(FillAddrInfo) (ciptr, serverS_path, serverR_path) == 0)
1293     {
1294         PRMSG(1,"SCOOpenServer: failed to fill in addr info\n",
1295               0,0,0);
1296         close(fds);
1297         close(fdr);
1298         return -1;
1299     }
1300     
1301     return(fds);
1302
1303 #endif /* !SCORNODENAME */
1304 }
1305
1306 static int
1307 TRANS(SCOAccept)(ciptr, newciptr, status)
1308
1309 XtransConnInfo  ciptr;
1310 XtransConnInfo  newciptr;
1311 int             *status;
1312
1313 {
1314     char        c;
1315     int fd;
1316     
1317     PRMSG(2,"SCOAccept(%d)\n", ciptr->fd, 0,0 );
1318     
1319     if (read(ciptr->fd, &c, 1) < 0) {
1320         PRMSG(1,"SCOAccept: can't read from client",0,0,0);
1321         *status = TRANS_ACCEPT_MISC_ERROR;
1322         return(-1);
1323     }
1324     
1325     if( (fd = open(DEV_SPX, O_RDWR)) < 0 ) {
1326         PRMSG(1,"SCOAccept: can't open \"%s\"",DEV_SPX, 0,0 );
1327         *status = TRANS_ACCEPT_MISC_ERROR;
1328         return(-1);
1329     }
1330     
1331     if (connect_spipe(ciptr->fd, fd) < 0) {
1332         PRMSG(1,"SCOAccept: can't connect pipes", 0,0,0 );
1333         (void) close(fd);
1334         *status = TRANS_ACCEPT_MISC_ERROR;
1335         return(-1);
1336     }
1337     
1338     /*
1339      * Everything looks good: fill in the XtransConnInfo structure.
1340      */
1341     
1342     newciptr->addrlen=ciptr->addrlen;
1343     if( (newciptr->addr=(char *)xalloc(newciptr->addrlen)) == NULL ) {
1344         PRMSG(1,
1345               "SCOAccept: failed to allocate memory for peer addr\n",
1346               0,0,0);
1347         close(fd);
1348         *status = TRANS_ACCEPT_BAD_MALLOC;
1349         return -1;
1350     }
1351     
1352     memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen);
1353     
1354     newciptr->peeraddrlen=newciptr->addrlen;
1355     if( (newciptr->peeraddr=(char *)xalloc(newciptr->peeraddrlen)) == NULL ) {
1356         PRMSG(1,
1357               "SCOAccept: failed to allocate memory for peer addr\n",
1358               0,0,0);
1359         xfree(newciptr->addr);
1360         close(fd);
1361         *status = TRANS_ACCEPT_BAD_MALLOC;
1362         return -1;
1363     }
1364     
1365     memcpy(newciptr->peeraddr,newciptr->addr,newciptr->peeraddrlen);
1366     
1367     *status = 0;
1368
1369     return(fd);
1370 }
1371
1372 #endif /* TRANS_SERVER */
1373
1374
1375 \f
1376 #ifdef TRANS_REOPEN
1377
1378 static int
1379 TRANS(PTSReopenServer)(ciptr, fd, port)
1380
1381 XtransConnInfo  ciptr;
1382 int             fd;
1383 char            *port;
1384 {
1385     char server_path[64];
1386
1387     PRMSG(2,"PTSReopenServer(%d,%s)\n", fd, port, 0 );
1388
1389 #if !defined(PTSNODENAME)
1390     PRMSG(1,"PTSReopenServer: Protocol is not supported by a pts connection\n", 0,0,0);
1391     return 0;
1392 #else
1393     if (port && *port ) {
1394         if( *port == '/' ) { /* A full pathname */
1395                 (void) sprintf(server_path, "%s", port);
1396             } else {
1397                 (void) sprintf(server_path, "%s%s", PTSNODENAME, port);
1398             }
1399     } else {
1400         (void) sprintf(server_path, "%s%d", PTSNODENAME, getpid());
1401     }
1402
1403     if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
1404     {
1405         PRMSG(1,"PTSReopenServer: failed to fill in addr info\n",
1406                                                                 0,0,0);
1407         return 0;
1408     }
1409
1410     return 1;
1411
1412 #endif /* !PTSNODENAME */
1413 }
1414
1415
1416 static int
1417 TRANS(NAMEDReopenServer)(ciptr, fd, port)
1418
1419 XtransConnInfo  ciptr;
1420 int             fd;
1421 char            *port;
1422
1423 {
1424     char server_path[64];
1425
1426     PRMSG(2,"NAMEDReopenServer(%s)\n", port, 0,0 );
1427
1428 #if !defined(NAMEDNODENAME)
1429     PRMSG(1,"NAMEDReopenServer: Protocol is not supported by a NAMED connection\n", 0,0,0);
1430     return 0;
1431 #else
1432     if ( port && *port ) {
1433         if( *port == '/' ) { /* A full pathname */
1434             (void) sprintf(server_path, "%s", port);
1435         } else {
1436             (void) sprintf(server_path, "%s%s", NAMEDNODENAME, port);
1437         }
1438     } else {
1439         (void) sprintf(server_path, "%s%d", NAMEDNODENAME, getpid());
1440     }
1441
1442     if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
1443     {
1444         PRMSG(1,"NAMEDReopenServer: failed to fill in addr info\n",
1445                                                                 0,0,0);
1446         return 0;
1447     }
1448
1449     return 1;
1450
1451 #endif /* !NAMEDNODENAME */
1452 }
1453
1454
1455 static int
1456 TRANS(ISCReopenServer)(ciptr, fd, port)
1457
1458 XtransConnInfo  ciptr;
1459 int             fd;
1460 char            *port;
1461
1462 {
1463     char server_path[64],server_unix_path[64];
1464     
1465     PRMSG(2,"ISCReopenServer(%s)\n", port, 0,0 );
1466     
1467 #if !defined(ISCDEVNODENAME)
1468     PRMSG(1,"ISCReopenServer: Protocol is not supported by a ISC connection\n", 0,0,0);
1469     return 0;
1470 #else
1471     (void) sprintf(server_path, ISCDEVNODENAME, port);
1472     (void) sprintf(server_unix_path, ISCTMPNODENAME, port);
1473
1474     if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
1475     {
1476         PRMSG(1,"ISCReopenServer: failed to fill in addr info\n",
1477                                                                 0,0,0);
1478         return 0;
1479     }
1480     
1481     return 1;
1482
1483 #endif /* !ISCDEVNODENAME */
1484 }
1485
1486
1487 static int
1488 TRANS(SCOReopenServer)(ciptr, fd, port)
1489
1490 XtransConnInfo  ciptr;
1491 int             fd;
1492 char            *port;
1493
1494 {
1495     char                serverR_path[64];
1496     char                serverS_path[64];
1497     
1498     PRMSG(2,"SCOReopenServer(%s)\n", port, 0,0 );
1499     
1500 #if !defined(SCORNODENAME)
1501     PRMSG(1,"SCOReopenServer: Protocol is not supported by a SCO connection\n", 0,0,0);
1502     return 0;
1503 #else
1504     (void) sprintf(serverR_path, SCORNODENAME, port);
1505     (void) sprintf(serverS_path, SCOSNODENAME, port);
1506     
1507     if (TRANS(FillAddrInfo) (ciptr, serverS_path, serverR_path) == 0)
1508     {
1509         PRMSG(1,"SCOReopenServer: failed to fill in addr info\n",
1510               0,0,0);
1511         return 0;
1512     }
1513     
1514     return 1;
1515
1516 #endif /* SCORNODENAME */
1517 }
1518
1519 #endif /* TRANS_REOPEN */
1520
1521
1522 \f
1523 /*
1524  * This table contains all of the entry points for the different local
1525  * connection mechanisms.
1526  */
1527
1528 typedef struct _LOCALtrans2dev {
1529     char        *transname;
1530
1531 #ifdef TRANS_CLIENT
1532
1533     int (*devcotsopenclient)(
1534 #if NeedFunctionPrototypes
1535         XtransConnInfo, char * /*port*/
1536 #endif
1537 );
1538
1539 #endif /* TRANS_CLIENT */
1540
1541 #ifdef TRANS_SERVER
1542
1543     int (*devcotsopenserver)(
1544 #if NeedFunctionPrototypes
1545         XtransConnInfo, char * /*port*/
1546 #endif
1547 );
1548
1549 #endif /* TRANS_SERVER */
1550
1551 #ifdef TRANS_CLIENT
1552
1553     int (*devcltsopenclient)(
1554 #if NeedFunctionPrototypes
1555         XtransConnInfo, char * /*port*/
1556 #endif
1557 );
1558
1559 #endif /* TRANS_CLIENT */
1560
1561 #ifdef TRANS_SERVER
1562
1563     int (*devcltsopenserver)(
1564 #if NeedFunctionPrototypes
1565         XtransConnInfo, char * /*port*/
1566 #endif
1567 );
1568
1569 #endif /* TRANS_SERVER */
1570
1571 #ifdef TRANS_REOPEN
1572
1573     int (*devcotsreopenserver)(
1574 #if NeedFunctionPrototypes
1575         XtransConnInfo,
1576         int,    /* fd */
1577         char *  /* port */
1578 #endif
1579 );
1580
1581     int (*devcltsreopenserver)(
1582 #if NeedFunctionPrototypes
1583         XtransConnInfo,
1584         int,    /* fd */
1585         char *  /* port */
1586 #endif
1587 );
1588
1589 #endif /* TRANS_REOPEN */
1590
1591 #ifdef TRANS_SERVER
1592
1593     int (*devaccept)(
1594 #if NeedFunctionPrototypes
1595         XtransConnInfo, XtransConnInfo, int *
1596 #endif
1597
1598 );
1599
1600 #endif /* TRANS_SERVER */
1601
1602 } LOCALtrans2dev;
1603
1604 static LOCALtrans2dev LOCALtrans2devtab[] = {
1605 {"",
1606 #ifdef TRANS_CLIENT
1607      TRANS(PTSOpenClient),
1608 #endif /* TRANS_CLIENT */
1609 #ifdef TRANS_SERVER
1610      TRANS(PTSOpenServer),
1611 #endif /* TRANS_SERVER */
1612 #ifdef TRANS_CLIENT
1613      TRANS(OpenFail),
1614 #endif /* TRANS_CLIENT */
1615 #ifdef TRANS_SERVER
1616      TRANS(OpenFail),
1617 #endif /* TRANS_SERVER */
1618 #ifdef TRANS_REOPEN
1619      TRANS(PTSReopenServer),
1620      TRANS(ReopenFail),
1621 #endif
1622 #ifdef TRANS_SERVER
1623      TRANS(PTSAccept)
1624 #endif /* TRANS_SERVER */
1625 },
1626
1627 {"local",
1628 #ifdef TRANS_CLIENT
1629      TRANS(PTSOpenClient),
1630 #endif /* TRANS_CLIENT */
1631 #ifdef TRANS_SERVER
1632      TRANS(PTSOpenServer),
1633 #endif /* TRANS_SERVER */
1634 #ifdef TRANS_CLIENT
1635      TRANS(OpenFail),
1636 #endif /* TRANS_CLIENT */
1637 #ifdef TRANS_SERVER
1638      TRANS(OpenFail),
1639 #endif /* TRANS_SERVER */
1640 #ifdef TRANS_REOPEN
1641      TRANS(PTSReopenServer),
1642      TRANS(ReopenFail),
1643 #endif
1644 #ifdef TRANS_SERVER
1645      TRANS(PTSAccept)
1646 #endif /* TRANS_SERVER */
1647 },
1648
1649 {"pts",
1650 #ifdef TRANS_CLIENT
1651      TRANS(PTSOpenClient),
1652 #endif /* TRANS_CLIENT */
1653 #ifdef TRANS_SERVER
1654      TRANS(PTSOpenServer),
1655 #endif /* TRANS_SERVER */
1656 #ifdef TRANS_CLIENT
1657      TRANS(OpenFail),
1658 #endif /* TRANS_CLIENT */
1659 #ifdef TRANS_SERVER
1660      TRANS(OpenFail),
1661 #endif /* TRANS_SERVER */
1662 #ifdef TRANS_REOPEN
1663      TRANS(PTSReopenServer),
1664      TRANS(ReopenFail),
1665 #endif
1666 #ifdef TRANS_SERVER
1667      TRANS(PTSAccept)
1668 #endif /* TRANS_SERVER */
1669 },
1670
1671 #ifdef SVR4
1672 {"named",
1673 #ifdef TRANS_CLIENT
1674      TRANS(NAMEDOpenClient),
1675 #endif /* TRANS_CLIENT */
1676 #ifdef TRANS_SERVER
1677      TRANS(NAMEDOpenServer),
1678 #endif /* TRANS_SERVER */
1679 #ifdef TRANS_CLIENT
1680      TRANS(OpenFail),
1681 #endif /* TRANS_CLIENT */
1682 #ifdef TRANS_SERVER
1683      TRANS(OpenFail),
1684 #endif /* TRANS_SERVER */
1685 #ifdef TRANS_REOPEN
1686      TRANS(NAMEDReopenServer),
1687      TRANS(ReopenFail),
1688 #endif
1689 #ifdef TRANS_SERVER
1690      TRANS(NAMEDAccept)
1691 #endif /* TRANS_SERVER */
1692 },
1693 #endif /* SVR4 */
1694
1695 {"isc",
1696 #ifdef TRANS_CLIENT
1697      TRANS(ISCOpenClient),
1698 #endif /* TRANS_CLIENT */
1699 #ifdef TRANS_SERVER
1700      TRANS(ISCOpenServer),
1701 #endif /* TRANS_SERVER */
1702 #ifdef TRANS_CLIENT
1703      TRANS(OpenFail),
1704 #endif /* TRANS_CLIENT */
1705 #ifdef TRANS_SERVER
1706      TRANS(OpenFail),
1707 #endif /* TRANS_SERVER */
1708 #ifdef TRANS_REOPEN
1709      TRANS(ISCReopenServer),
1710      TRANS(ReopenFail),
1711 #endif
1712 #ifdef TRANS_SERVER
1713      TRANS(ISCAccept)
1714 #endif /* TRANS_SERVER */
1715 },
1716
1717 {"sco",
1718 #ifdef TRANS_CLIENT
1719      TRANS(SCOOpenClient),
1720 #endif /* TRANS_CLIENT */
1721 #ifdef TRANS_SERVER
1722      TRANS(SCOOpenServer),
1723 #endif /* TRANS_SERVER */
1724 #ifdef TRANS_CLIENT
1725      TRANS(OpenFail),
1726 #endif /* TRANS_CLIENT */
1727 #ifdef TRANS_SERVER
1728      TRANS(OpenFail),
1729 #endif /* TRANS_SERVER */
1730 #ifdef TRANS_REOPEN
1731      TRANS(SCOReopenServer),
1732      TRANS(ReopenFail),
1733 #endif
1734 #ifdef TRANS_SERVER
1735      TRANS(SCOAccept)
1736 #endif /* TRANS_SERVER */
1737 },
1738 };
1739
1740 #define NUMTRANSPORTS   (sizeof(LOCALtrans2devtab)/sizeof(LOCALtrans2dev))
1741     
1742 static  char    *XLOCAL=NULL;
1743 static  char    *workingXLOCAL=NULL;
1744 static  char    *freeXLOCAL=NULL;
1745
1746 static void
1747 TRANS(LocalInitTransports)(protocol)
1748
1749 char *protocol;
1750
1751 {
1752     PRMSG(3,"LocalInitTransports(%s)\n", protocol, 0,0 );
1753     
1754     if( strcmp(protocol,"local") && strcmp(protocol,"LOCAL") )
1755     {
1756         workingXLOCAL=freeXLOCAL=(char *)xalloc (strlen (protocol) + 1);
1757         if (workingXLOCAL)
1758             strcpy (workingXLOCAL, protocol);
1759     }
1760     else {
1761         XLOCAL=(char *)getenv("XLOCAL");
1762         if(XLOCAL==NULL)
1763             XLOCAL="UNIX:PTS:NAMED:ISC:SCO";
1764         workingXLOCAL=freeXLOCAL=(char *)xalloc (strlen (XLOCAL) + 1);
1765         if (workingXLOCAL)
1766             strcpy (workingXLOCAL, XLOCAL);
1767     }
1768 }
1769
1770 static void
1771 TRANS(LocalEndTransports)()
1772
1773 {
1774     PRMSG(3,"LocalEndTransports()\n", 0,0,0 );
1775     xfree(freeXLOCAL);
1776 }
1777
1778 static LOCALtrans2dev *
1779 TRANS(LocalGetNextTransport)()
1780
1781 {
1782     int i,j;
1783     char        *typetocheck;
1784 #define TYPEBUFSIZE     32
1785     char        typebuf[TYPEBUFSIZE];
1786     PRMSG(3,"LocalGetNextTransport()\n", 0,0,0 );
1787     
1788     while(1)
1789     {
1790         if( workingXLOCAL == NULL || *workingXLOCAL == '\0' )
1791             return NULL;
1792         
1793         typetocheck=workingXLOCAL;
1794         workingXLOCAL=strchr(workingXLOCAL,':');
1795         if(workingXLOCAL && *workingXLOCAL)
1796             *workingXLOCAL++='\0';
1797         
1798         for(i=0;i<NUMTRANSPORTS;i++)
1799         {
1800             /*
1801              * This is equivilent to a case insensitive strcmp(),
1802              * but should be more portable.
1803              */
1804             strncpy(typebuf,typetocheck,TYPEBUFSIZE);
1805             for(j=0;j<TYPEBUFSIZE;j++)
1806                 if (isupper(typebuf[j]))
1807                     typebuf[j]=tolower(typebuf[j]);
1808             
1809             /* Now, see if they match */
1810             if(!strcmp(LOCALtrans2devtab[i].transname,typebuf))
1811                 return &LOCALtrans2devtab[i];
1812         }
1813     }
1814     /*NOTREACHED*/
1815     return NULL;
1816 }
1817
1818 #ifdef TRANS_CLIENT
1819
1820 #ifdef NEED_UTSNAME
1821 #include <sys/utsname.h>
1822 #endif
1823
1824 /*
1825  * Make sure 'host' is really local.
1826  */
1827
1828 static int
1829 HostReallyLocal (host)
1830
1831 char *host;
1832
1833 {
1834     /*
1835      * The 'host' passed to this function may have been generated
1836      * by either uname() or gethostname().  We try both if possible.
1837      */
1838
1839 #ifdef NEED_UTSNAME
1840     struct utsname name;
1841 #endif
1842     char buf[256];
1843
1844 #ifdef NEED_UTSNAME
1845     if (uname (&name) >= 0 && strcmp (host, name.nodename) == 0)
1846         return (1);
1847 #endif
1848
1849     buf[0] = '\0';
1850     (void) gethostname (buf, 256);
1851     buf[255] = '\0';
1852
1853     if (strcmp (host, buf) == 0)
1854         return (1);
1855
1856     return (0);
1857 }
1858
1859
1860 static XtransConnInfo
1861 TRANS(LocalOpenClient)(type, protocol, host, port)
1862
1863 int  type;
1864 char *protocol;
1865 char *host;
1866 char *port;
1867
1868 {
1869     int fd = -1;
1870     LOCALtrans2dev *transptr;
1871     XtransConnInfo ciptr;
1872     int index;
1873
1874     PRMSG(3,"LocalOpenClient()\n", 0,0,0 );
1875     
1876     /*
1877      * Make sure 'host' is really local.  If not, we return failure.
1878      * The reason we make this check is because a process may advertise
1879      * a "local" address for which it can accept connections, but if a
1880      * process on a remote machine tries to connect to this address,
1881      * we know for sure it will fail.
1882      */
1883
1884     if (strcmp (host, "unix") != 0 && !HostReallyLocal (host))
1885     {
1886         PRMSG (1,
1887            "LocalOpenClient: Cannot connect to non-local host %s\n",
1888                host, 0, 0);
1889         return NULL;
1890     }
1891
1892
1893 #if defined(X11_t)
1894     /*
1895      * X has a well known port, that is transport dependant. It is easier
1896      * to handle it here, than try and come up with a transport independent
1897      * representation that can be passed in and resolved the usual way.
1898      *
1899      * The port that is passed here is really a string containing the idisplay
1900      * from ConnectDisplay(). Since that is what we want for the local transports,
1901      * we don't have to do anything special.
1902      */
1903 #endif /* X11_t */
1904     
1905     if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL )
1906     {
1907         PRMSG(1,"LocalOpenClient: calloc(1,%d) failed\n",
1908               sizeof(struct _XtransConnInfo),0,0 );
1909         return NULL;
1910     }
1911     
1912     ciptr->fd = -1;
1913     
1914     TRANS(LocalInitTransports)(protocol);
1915     
1916     index = 0;
1917     for(transptr=TRANS(LocalGetNextTransport)();
1918         transptr!=NULL;transptr=TRANS(LocalGetNextTransport)(), index++)
1919     {
1920         switch( type )
1921         {
1922         case XTRANS_OPEN_COTS_CLIENT:
1923             ciptr->fd=transptr->devcotsopenclient(ciptr,port);
1924             break;
1925         case XTRANS_OPEN_CLTS_CLIENT:
1926             ciptr->fd=transptr->devcltsopenclient(ciptr,port);
1927             break;
1928         case XTRANS_OPEN_COTS_SERVER:
1929         case XTRANS_OPEN_CLTS_SERVER:
1930             PRMSG(1,
1931                   "LocalOpenClient: Should not be opening a server with this function\n",
1932                   0,0,0);
1933             break;
1934         default:
1935             PRMSG(1,
1936                   "LocalOpenClient: Unknown Open type %d\n",
1937                   type, 0,0 );
1938         }
1939         if( ciptr->fd >= 0 )
1940             break;
1941     }
1942     
1943     TRANS(LocalEndTransports)();
1944     
1945     if( ciptr->fd < 0 )
1946     {
1947         xfree(ciptr);
1948         return NULL;
1949     }
1950     
1951     ciptr->priv=(char *)transptr;
1952     ciptr->index = index;
1953     
1954     return ciptr;
1955 }
1956
1957 #endif /* TRANS_CLIENT */
1958
1959
1960 #ifdef TRANS_SERVER
1961
1962 static XtransConnInfo
1963 TRANS(LocalOpenServer)(type, protocol, host, port)
1964
1965 int  type;
1966 char *protocol;
1967 char *host;
1968 char *port;
1969
1970 {
1971     int i,fd = -1;
1972     XtransConnInfo ciptr;
1973     
1974     PRMSG(2,"LocalOpenServer(%d,%s,%s)\n", type, protocol, port);
1975     
1976 #if defined(X11_t)
1977     /*
1978      * For X11, the port will be in the format xserverN where N is the
1979      * display number. All of the local connections just need to know
1980      * the display number because they don't do any name resolution on
1981      * the port. This just truncates port to the display portion.
1982      */
1983 #endif /* X11_t */
1984     
1985     if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL )
1986     {
1987         PRMSG(1,"LocalOpenServer: calloc(1,%d) failed\n",
1988               sizeof(struct _XtransConnInfo),0,0 );
1989         return NULL;
1990     }
1991     
1992     for(i=1;i<NUMTRANSPORTS;i++)
1993     {
1994         if( strcmp(protocol,LOCALtrans2devtab[i].transname) != 0 )
1995             continue;
1996         switch( type )
1997         {
1998         case XTRANS_OPEN_COTS_CLIENT:
1999         case XTRANS_OPEN_CLTS_CLIENT:
2000             PRMSG(1,
2001                   "LocalOpenServer: Should not be opening a client with this function\n",
2002                   0,0,0);
2003             break;
2004         case XTRANS_OPEN_COTS_SERVER:
2005             ciptr->fd=LOCALtrans2devtab[i].devcotsopenserver(ciptr,port);
2006             break;
2007         case XTRANS_OPEN_CLTS_SERVER:
2008             ciptr->fd=LOCALtrans2devtab[i].devcltsopenserver(ciptr,port);
2009             break;
2010         default:
2011             PRMSG(1,"LocalOpenServer: Unknown Open type %d\n",
2012                   type ,0,0);
2013         }
2014         if( ciptr->fd >= 0 ) {
2015             ciptr->priv=(char *)&LOCALtrans2devtab[i];
2016             ciptr->index=i;
2017             ciptr->flags=1;
2018             return ciptr;
2019         }
2020     }
2021     
2022     xfree(ciptr);
2023     return NULL;
2024 }
2025
2026 #endif /* TRANS_SERVER */
2027
2028
2029 #ifdef TRANS_REOPEN
2030
2031 static XtransConnInfo
2032 TRANS(LocalReopenServer)(type, index, fd, port)
2033
2034 int  type;
2035 int  index;
2036 int  fd;
2037 char *port;
2038
2039 {
2040     XtransConnInfo ciptr;
2041     int stat;
2042     
2043     PRMSG(2,"LocalReopenServer(%d,%d,%d)\n", type, index, fd);
2044     
2045     if( (ciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo))) == NULL )
2046     {
2047         PRMSG(1,"LocalReopenServer: calloc(1,%d) failed\n",
2048               sizeof(struct _XtransConnInfo),0,0 );
2049         return NULL;
2050     }
2051     
2052     ciptr->fd = fd;
2053
2054     switch( type )
2055     {
2056     case XTRANS_OPEN_COTS_SERVER:
2057         stat = LOCALtrans2devtab[index].devcotsreopenserver(ciptr,fd,port);
2058         break;
2059     case XTRANS_OPEN_CLTS_SERVER:
2060         stat = LOCALtrans2devtab[index].devcltsreopenserver(ciptr,fd,port);
2061         break;
2062     default:
2063         PRMSG(1,"LocalReopenServer: Unknown Open type %d\n",
2064           type ,0,0);
2065     }
2066
2067     if( stat > 0 ) {
2068         ciptr->priv=(char *)&LOCALtrans2devtab[index];
2069         ciptr->index=index;
2070         ciptr->flags=1;
2071         return ciptr;
2072     }
2073     
2074     xfree(ciptr);
2075     return NULL;
2076 }
2077
2078 #endif /* TRANS_REOPEN */
2079
2080
2081 \f
2082 /*
2083  * This is the Local implementation of the X Transport service layer
2084  */
2085
2086 #ifdef TRANS_CLIENT
2087
2088 static XtransConnInfo
2089 TRANS(LocalOpenCOTSClient)(thistrans, protocol, host, port)
2090
2091 Xtransport *thistrans;
2092 char *protocol;
2093 char *host;
2094 char *port;
2095
2096 {
2097     PRMSG(2,"LocalOpenCOTSClient(%s,%s,%s)\n",protocol,host,port);
2098     
2099     return TRANS(LocalOpenClient)(XTRANS_OPEN_COTS_CLIENT, protocol, host, port);
2100 }
2101
2102 #endif /* TRANS_CLIENT */
2103
2104
2105 #ifdef TRANS_SERVER
2106
2107 static XtransConnInfo
2108 TRANS(LocalOpenCOTSServer)(thistrans, protocol, host, port)
2109
2110 Xtransport *thistrans;
2111 char *protocol;
2112 char *host;
2113 char *port;
2114
2115 {
2116     char *typetocheck = NULL;
2117     int found = 0;
2118     char typebuf[TYPEBUFSIZE];
2119
2120     PRMSG(2,"LocalOpenCOTSServer(%s,%s,%s)\n",protocol,host,port);
2121
2122     /* Check if this local type is in the XLOCAL list */
2123     TRANS(LocalInitTransports)("local");
2124     typetocheck = workingXLOCAL;
2125     while (typetocheck && !found) {
2126         int j;
2127
2128         workingXLOCAL = strchr(workingXLOCAL, ':');
2129         if (workingXLOCAL && *workingXLOCAL)
2130             *workingXLOCAL++ = '\0';
2131         strncpy(typebuf, typetocheck, TYPEBUFSIZE);
2132         for (j = 0; j < TYPEBUFSIZE; j++)
2133             if (isupper(typebuf[j]))
2134                 typebuf[j] = tolower(typebuf[j]);
2135         if (!strcmp(thistrans->TransName, typebuf))
2136             found = 1;
2137         typetocheck = workingXLOCAL;
2138     }
2139     TRANS(LocalEndTransports)();
2140     
2141     if (!found) {
2142         PRMSG(3,"LocalOpenCOTSServer: disabling %s\n",thistrans->TransName,0,0);
2143         thistrans->flags |= TRANS_DISABLED;
2144         return NULL;
2145     }
2146
2147     return TRANS(LocalOpenServer)(XTRANS_OPEN_COTS_SERVER, protocol, host, port);
2148 }
2149
2150 #endif /* TRANS_SERVER */
2151
2152
2153 #ifdef TRANS_CLIENT
2154
2155 static XtransConnInfo
2156 TRANS(LocalOpenCLTSClient)(thistrans, protocol, host, port)
2157
2158 Xtransport *thistrans;
2159 char *protocol;
2160 char *host;
2161 char *port;
2162
2163 {
2164     PRMSG(2,"LocalOpenCLTSClient(%s,%s,%s)\n",protocol,host,port);
2165     
2166     return TRANS(LocalOpenClient)(XTRANS_OPEN_CLTS_CLIENT, protocol, host, port);
2167 }
2168
2169 #endif /* TRANS_CLIENT */
2170
2171
2172 #ifdef TRANS_SERVER
2173
2174 static XtransConnInfo
2175 TRANS(LocalOpenCLTSServer)(thistrans, protocol, host, port)
2176
2177 Xtransport *thistrans;
2178 char *protocol;
2179 char *host;
2180 char *port;
2181
2182 {
2183     PRMSG(2,"LocalOpenCLTSServer(%s,%s,%s)\n",protocol,host,port);
2184     
2185     return TRANS(LocalOpenServer)(XTRANS_OPEN_CLTS_SERVER, protocol, host, port);
2186 }
2187
2188 #endif /* TRANS_SERVER */
2189
2190
2191 #ifdef TRANS_REOPEN
2192
2193 static XtransConnInfo
2194 TRANS(LocalReopenCOTSServer)(thistrans, fd, port)
2195
2196 Xtransport *thistrans;
2197 int        fd;
2198 char       *port;
2199
2200 {
2201     int index;
2202
2203     PRMSG(2,"LocalReopenCOTSServer(%d,%s)\n", fd, port, 0);
2204     
2205     for(index=1;index<NUMTRANSPORTS;index++)
2206     {
2207         if( strcmp(thistrans->TransName,
2208             LOCALtrans2devtab[index].transname) == 0 )
2209             break;
2210     }
2211     
2212     if (index >= NUMTRANSPORTS)
2213     {
2214         return (NULL);
2215     }
2216
2217     return TRANS(LocalReopenServer)(XTRANS_OPEN_COTS_SERVER,
2218         index, fd, port);
2219 }
2220
2221 static XtransConnInfo
2222 TRANS(LocalReopenCLTSServer)(thistrans, fd, port)
2223
2224 Xtransport *thistrans;
2225 int        fd;
2226 char       *port;
2227
2228 {
2229     int index;
2230
2231     PRMSG(2,"LocalReopenCLTSServer(%d,%s)\n", fd, port, 0);
2232     
2233     for(index=1;index<NUMTRANSPORTS;index++)
2234     {
2235         if( strcmp(thistrans->TransName,
2236             LOCALtrans2devtab[index].transname) == 0 )
2237             break;
2238     }
2239     
2240     if (index >= NUMTRANSPORTS)
2241     {
2242         return (NULL);
2243     }
2244
2245     return TRANS(LocalReopenServer)(XTRANS_OPEN_CLTS_SERVER,
2246         index, fd, port);
2247 }
2248
2249 #endif /* TRANS_REOPEN */
2250
2251
2252
2253 static
2254 TRANS(LocalSetOption)(ciptr, option, arg)
2255
2256 XtransConnInfo ciptr;
2257 int option;
2258 int arg;
2259
2260 {
2261     PRMSG(2,"LocalSetOption(%d,%d,%d)\n",ciptr->fd,option,arg);
2262     
2263     return -1;
2264 }
2265
2266
2267 #ifdef TRANS_SERVER
2268
2269 static
2270 TRANS(LocalCreateListener)(ciptr, port)
2271
2272 XtransConnInfo ciptr;
2273 char *port;
2274
2275 {
2276     PRMSG(2,"LocalCreateListener(%x->%d,%s)\n",ciptr,ciptr->fd,port);
2277     
2278     return 0;
2279 }
2280
2281 static XtransConnInfo
2282 TRANS(LocalAccept)(ciptr, status)
2283
2284 XtransConnInfo ciptr;
2285 int            *status;
2286
2287 {
2288     XtransConnInfo      newciptr;
2289     LOCALtrans2dev      *transptr;
2290     
2291     PRMSG(2,"LocalAccept(%x->%d)\n", ciptr, ciptr->fd,0);
2292     
2293     transptr=(LOCALtrans2dev *)ciptr->priv;
2294     
2295     if( (newciptr=(XtransConnInfo)xcalloc(1,sizeof(struct _XtransConnInfo)))==NULL )
2296     {
2297         PRMSG(1,"LocalAccept: calloc(1,%d) failed\n",
2298               sizeof(struct _XtransConnInfo),0,0 );
2299         *status = TRANS_ACCEPT_BAD_MALLOC;
2300         return NULL;
2301     }
2302     
2303     newciptr->fd=transptr->devaccept(ciptr,newciptr,status);
2304     
2305     if( newciptr->fd < 0 )
2306     {
2307         xfree(newciptr);
2308         return NULL;
2309     }
2310     
2311     newciptr->priv=(char *)transptr;
2312     newciptr->index = ciptr->index;
2313     
2314     *status = 0;
2315
2316     return newciptr;
2317 }
2318
2319 #endif /* TRANS_SERVER */
2320
2321
2322 #ifdef TRANS_CLIENT
2323
2324 static
2325 TRANS(LocalConnect)(ciptr, host, port)
2326
2327 XtransConnInfo ciptr;
2328 char *host;
2329 char *port;
2330
2331 {
2332     PRMSG(2,"LocalConnect(%x->%d,%s)\n", ciptr, ciptr->fd, port);
2333     
2334     return 0;
2335 }
2336
2337 #endif /* TRANS_CLIENT */
2338
2339
2340 static int
2341 TRANS(LocalBytesReadable)(ciptr, pend )
2342
2343 XtransConnInfo ciptr;
2344 BytesReadable_t *pend;
2345
2346 {
2347     PRMSG(2,"LocalBytesReadable(%x->%d,%x)\n", ciptr, ciptr->fd, pend);
2348
2349 #if defined(ISC) || defined(SCO)
2350     return ioctl(ciptr->fd, I_NREAD, (char *)pend);
2351 #else
2352     return ioctl(ciptr->fd, FIONREAD, (char *)pend);
2353 #endif
2354 }
2355
2356 static int
2357 TRANS(LocalRead)(ciptr, buf, size)
2358
2359 XtransConnInfo ciptr;
2360 char *buf;
2361 int size;
2362
2363 {
2364     PRMSG(2,"LocalRead(%d,%x,%d)\n", ciptr->fd, buf, size );
2365     
2366     return read(ciptr->fd,buf,size);
2367 }
2368
2369 static int
2370 TRANS(LocalWrite)(ciptr, buf, size)
2371
2372 XtransConnInfo ciptr;
2373 char *buf;
2374 int size;
2375
2376 {
2377     PRMSG(2,"LocalWrite(%d,%x,%d)\n", ciptr->fd, buf, size );
2378     
2379     return write(ciptr->fd,buf,size);
2380 }
2381
2382 static int
2383 TRANS(LocalReadv)(ciptr, buf, size)
2384
2385 XtransConnInfo  ciptr;
2386 struct iovec    *buf;
2387 int             size;
2388
2389 {
2390     PRMSG(2,"LocalReadv(%d,%x,%d)\n", ciptr->fd, buf, size );
2391     
2392     return READV(ciptr,buf,size);
2393 }
2394
2395 static int
2396 TRANS(LocalWritev)(ciptr, buf, size)
2397
2398 XtransConnInfo  ciptr;
2399 struct iovec    *buf;
2400 int             size;
2401
2402 {
2403     PRMSG(2,"LocalWritev(%d,%x,%d)\n", ciptr->fd, buf, size );
2404     
2405     return WRITEV(ciptr,buf,size);
2406 }
2407
2408 static int
2409 TRANS(LocalDisconnect)(ciptr)
2410
2411 XtransConnInfo ciptr;
2412
2413 {
2414     PRMSG(2,"LocalDisconnect(%x->%d)\n", ciptr, ciptr->fd, 0);
2415     
2416     return 0;
2417 }
2418
2419 static int
2420 TRANS(LocalClose)(ciptr)
2421
2422 XtransConnInfo ciptr;
2423
2424 {
2425     struct sockaddr_un      *sockname=(struct sockaddr_un *) ciptr->addr;
2426     char    path[200]; /* > sizeof sun_path +1 */
2427     int ret;
2428     
2429     PRMSG(2,"LocalClose(%x->%d)\n", ciptr, ciptr->fd ,0);
2430     
2431     ret=close(ciptr->fd);
2432     
2433     if(ciptr->flags
2434        && sockname
2435        && sockname->sun_family == AF_UNIX
2436        && sockname->sun_path[0] )
2437     {
2438         strncpy(path,sockname->sun_path,
2439                 ciptr->addrlen-sizeof(sockname->sun_family));
2440         unlink(path);
2441     }
2442     
2443     return ret;
2444 }
2445
2446 static int
2447 TRANS(LocalCloseForCloning)(ciptr)
2448
2449 XtransConnInfo ciptr;
2450
2451 {
2452     int ret;
2453
2454     PRMSG(2,"LocalCloseForCloning(%x->%d)\n", ciptr, ciptr->fd ,0);
2455     
2456     /* Don't unlink path */
2457
2458     ret=close(ciptr->fd);
2459     
2460     return ret;
2461 }
2462
2463
2464 /*
2465  * MakeAllCOTSServerListeners() will go through the entire Xtransports[]
2466  * array defined in Xtrans.c and try to OpenCOTSServer() for each entry.
2467  * We will add duplicate entries to that table so that the OpenCOTSServer()
2468  * function will get called once for each type of local transport. 
2469  *
2470  * The TransName is in lowercase, so it will never match during a normal
2471  * call to SelectTransport() in Xtrans.c.
2472  */
2473
2474 Xtransport      TRANS(LocalFuncs) = {
2475         /* Local Interface */
2476         "local",
2477         TRANS_ALIAS | TRANS_LOCAL,
2478 #ifdef TRANS_CLIENT
2479         TRANS(LocalOpenCOTSClient),
2480 #endif /* TRANS_CLIENT */
2481 #ifdef TRANS_SERVER
2482         TRANS(LocalOpenCOTSServer),
2483 #endif /* TRANS_SERVER */
2484 #ifdef TRANS_CLIENT
2485         TRANS(LocalOpenCLTSClient),
2486 #endif /* TRANS_CLIENT */
2487 #ifdef TRANS_SERVER
2488         TRANS(LocalOpenCLTSServer),
2489 #endif /* TRANS_SERVER */
2490 #ifdef TRANS_REOPEN
2491         TRANS(LocalReopenCOTSServer),
2492         TRANS(LocalReopenCLTSServer),
2493 #endif
2494         TRANS(LocalSetOption),
2495 #ifdef TRANS_SERVER
2496         TRANS(LocalCreateListener),
2497         NULL,                                   /* ResetListener */
2498         TRANS(LocalAccept),
2499 #endif /* TRANS_SERVER */
2500 #ifdef TRANS_CLIENT
2501         TRANS(LocalConnect),
2502 #endif /* TRANS_CLIENT */
2503         TRANS(LocalBytesReadable),
2504         TRANS(LocalRead),
2505         TRANS(LocalWrite),
2506         TRANS(LocalReadv),
2507         TRANS(LocalWritev),
2508         TRANS(LocalDisconnect),
2509         TRANS(LocalClose),
2510         TRANS(LocalCloseForCloning),
2511 };
2512
2513 Xtransport      TRANS(PTSFuncs) = {
2514         /* Local Interface */
2515         "pts",
2516         TRANS_LOCAL,
2517 #ifdef TRANS_CLIENT
2518         TRANS(LocalOpenCOTSClient),
2519 #endif /* TRANS_CLIENT */
2520 #ifdef TRANS_SERVER
2521         TRANS(LocalOpenCOTSServer),
2522 #endif /* TRANS_SERVER */
2523 #ifdef TRANS_CLIENT
2524         TRANS(LocalOpenCLTSClient),
2525 #endif /* TRANS_CLIENT */
2526 #ifdef TRANS_SERVER
2527         TRANS(LocalOpenCLTSServer),
2528 #endif /* TRANS_SERVER */
2529 #ifdef TRANS_REOPEN
2530         TRANS(LocalReopenCOTSServer),
2531         TRANS(LocalReopenCLTSServer),
2532 #endif
2533         TRANS(LocalSetOption),
2534 #ifdef TRANS_SERVER
2535         TRANS(LocalCreateListener),
2536         NULL,                                   /* ResetListener */
2537         TRANS(LocalAccept),
2538 #endif /* TRANS_SERVER */
2539 #ifdef TRANS_CLIENT
2540         TRANS(LocalConnect),
2541 #endif /* TRANS_CLIENT */
2542         TRANS(LocalBytesReadable),
2543         TRANS(LocalRead),
2544         TRANS(LocalWrite),
2545         TRANS(LocalReadv),
2546         TRANS(LocalWritev),
2547         TRANS(LocalDisconnect),
2548         TRANS(LocalClose),
2549         TRANS(LocalCloseForCloning),
2550 };
2551
2552 Xtransport      TRANS(NAMEDFuncs) = {
2553         /* Local Interface */
2554         "named",
2555         TRANS_LOCAL,
2556 #ifdef TRANS_CLIENT
2557         TRANS(LocalOpenCOTSClient),
2558 #endif /* TRANS_CLIENT */
2559 #ifdef TRANS_SERVER
2560         TRANS(LocalOpenCOTSServer),
2561 #endif /* TRANS_SERVER */
2562 #ifdef TRANS_CLIENT
2563         TRANS(LocalOpenCLTSClient),
2564 #endif /* TRANS_CLIENT */
2565 #ifdef TRANS_SERVER
2566         TRANS(LocalOpenCLTSServer),
2567 #endif /* TRANS_SERVER */
2568 #ifdef TRANS_REOPEN
2569         TRANS(LocalReopenCOTSServer),
2570         TRANS(LocalReopenCLTSServer),
2571 #endif
2572         TRANS(LocalSetOption),
2573 #ifdef TRANS_SERVER
2574         TRANS(LocalCreateListener),
2575         NULL,                                   /* ResetListener */
2576         TRANS(LocalAccept),
2577 #endif /* TRANS_SERVER */
2578 #ifdef TRANS_CLIENT
2579         TRANS(LocalConnect),
2580 #endif /* TRANS_CLIENT */
2581         TRANS(LocalBytesReadable),
2582         TRANS(LocalRead),
2583         TRANS(LocalWrite),
2584         TRANS(LocalReadv),
2585         TRANS(LocalWritev),
2586         TRANS(LocalDisconnect),
2587         TRANS(LocalClose),
2588         TRANS(LocalCloseForCloning),
2589 };
2590
2591 Xtransport      TRANS(ISCFuncs) = {
2592         /* Local Interface */
2593         "isc",
2594         TRANS_LOCAL,
2595 #ifdef TRANS_CLIENT
2596         TRANS(LocalOpenCOTSClient),
2597 #endif /* TRANS_CLIENT */
2598 #ifdef TRANS_SERVER
2599         TRANS(LocalOpenCOTSServer),
2600 #endif /* TRANS_SERVER */
2601 #ifdef TRANS_CLIENT
2602         TRANS(LocalOpenCLTSClient),
2603 #endif /* TRANS_CLIENT */
2604 #ifdef TRANS_SERVER
2605         TRANS(LocalOpenCLTSServer),
2606 #endif /* TRANS_SERVER */
2607 #ifdef TRANS_REOPEN
2608         TRANS(LocalReopenCOTSServer),
2609         TRANS(LocalReopenCLTSServer),
2610 #endif
2611         TRANS(LocalSetOption),
2612 #ifdef TRANS_SERVER
2613         TRANS(LocalCreateListener),
2614         NULL,                                   /* ResetListener */
2615         TRANS(LocalAccept),
2616 #endif /* TRANS_SERVER */
2617 #ifdef TRANS_CLIENT
2618         TRANS(LocalConnect),
2619 #endif /* TRANS_CLIENT */
2620         TRANS(LocalBytesReadable),
2621         TRANS(LocalRead),
2622         TRANS(LocalWrite),
2623         TRANS(LocalReadv),
2624         TRANS(LocalWritev),
2625         TRANS(LocalDisconnect),
2626         TRANS(LocalClose),
2627         TRANS(LocalCloseForCloning),
2628 };
2629 Xtransport      TRANS(SCOFuncs) = {
2630         /* Local Interface */
2631         "sco",
2632         TRANS_LOCAL,
2633 #ifdef TRANS_CLIENT
2634         TRANS(LocalOpenCOTSClient),
2635 #endif /* TRANS_CLIENT */
2636 #ifdef TRANS_SERVER
2637         TRANS(LocalOpenCOTSServer),
2638 #endif /* TRANS_SERVER */
2639 #ifdef TRANS_CLIENT
2640         TRANS(LocalOpenCLTSClient),
2641 #endif /* TRANS_CLIENT */
2642 #ifdef TRANS_SERVER
2643         TRANS(LocalOpenCLTSServer),
2644 #endif /* TRANS_SERVER */
2645 #ifdef TRANS_REOPEN
2646         TRANS(LocalReopenCOTSServer),
2647         TRANS(LocalReopenCLTSServer),
2648 #endif
2649         TRANS(LocalSetOption),
2650 #ifdef TRANS_SERVER
2651         TRANS(LocalCreateListener),
2652         NULL,                                   /* ResetListener */
2653         TRANS(LocalAccept),
2654 #endif /* TRANS_SERVER */
2655 #ifdef TRANS_CLIENT
2656         TRANS(LocalConnect),
2657 #endif /* TRANS_CLIENT */
2658         TRANS(LocalBytesReadable),
2659         TRANS(LocalRead),
2660         TRANS(LocalWrite),
2661         TRANS(LocalReadv),
2662         TRANS(LocalWritev),
2663         TRANS(LocalDisconnect),
2664         TRANS(LocalClose),
2665         TRANS(LocalCloseForCloning),
2666 };