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