1bbe1b32bSmrg/*
2bbe1b32bSmrg * Copyright © 2003 Keith Packard
3bbe1b32bSmrg *
4bbe1b32bSmrg * Permission to use, copy, modify, distribute, and sell this software and its
5bbe1b32bSmrg * documentation for any purpose is hereby granted without fee, provided that
6bbe1b32bSmrg * the above copyright notice appear in all copies and that both that
7bbe1b32bSmrg * copyright notice and this permission notice appear in supporting
8bbe1b32bSmrg * documentation, and that the name of Keith Packard not be used in
9bbe1b32bSmrg * advertising or publicity pertaining to distribution of the software without
10bbe1b32bSmrg * specific, written prior permission.  Keith Packard makes no
11bbe1b32bSmrg * representations about the suitability of this software for any purpose.  It
12bbe1b32bSmrg * is provided "as is" without express or implied warranty.
13bbe1b32bSmrg *
14bbe1b32bSmrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15bbe1b32bSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16bbe1b32bSmrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17bbe1b32bSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18bbe1b32bSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19bbe1b32bSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20bbe1b32bSmrg * PERFORMANCE OF THIS SOFTWARE.
21bbe1b32bSmrg */
22bbe1b32bSmrg
2334f90d55Smrg#include <config.h>
24bbe1b32bSmrg
25ce6676dbSmrg#define FONT_t 1
26ce6676dbSmrg#define TRANS_REOPEN 1
27ce6676dbSmrg#define TRANS_SERVER 1
28bbe1b32bSmrg
29bbe1b32bSmrg#include <X11/Xtrans/transport.c>
30ce6676dbSmrg
31ce6676dbSmrg#ifdef XFS_INETD
32ce6676dbSmrg/* xfs special handling for listen socket passed from inetd */
3330e1ba2cSmrg
3430e1ba2cSmrg/* XXX duplicated from misc.h */
3530e1ba2cSmrgtypedef struct {		/* when cloning, need old transport info */
3630e1ba2cSmrg    int trans_id;
3730e1ba2cSmrg    int fd;
3830e1ba2cSmrg    int portnum;
3930e1ba2cSmrg} OldListenRec;
40ce6676dbSmrg
41ce6676dbSmrgOldListenRec *
42ce6676dbSmrgTRANS(GetInetdListenInfo) (int fd)
43ce6676dbSmrg{
4430e1ba2cSmrg    const char *port = "0";
45ce6676dbSmrg    XtransConnInfo inetdCI;
46ce6676dbSmrg    OldListenRec *old_listen;
47ce6676dbSmrg    int portnum;
48ce6676dbSmrg
49ce6676dbSmrg    /* Create a XtransConnInfo struct for this connection */
50ce6676dbSmrg    inetdCI = TRANS(ReopenCOTSServer)(TRANS_SOCKET_TCP_INDEX, fd, port);
51ce6676dbSmrg
52ce6676dbSmrg    /* Fill in correct address/portnum */
53ce6676dbSmrg    TRANS(SocketINETGetAddr)(inetdCI);
54293e56a8Schristos#if defined(IPv6) && defined(AF_INET6)
55ce6676dbSmrg    if ( ((struct sockaddr *)(inetdCI->addr))->sa_family == AF_INET6 )
56ce6676dbSmrg	portnum = ntohs(((struct sockaddr_in6 *)(inetdCI->addr))->sin6_port);
57ce6676dbSmrg    else
58ce6676dbSmrg#endif
59ce6676dbSmrg	portnum = ntohs(((struct sockaddr_in *)(inetdCI->addr))->sin_port);
6034f90d55Smrg    inetdCI->port = malloc(6); /* Base 10 integer <= 65535 + trailing NUL */
61ce6676dbSmrg    snprintf(inetdCI->port, 6, "%d", portnum);
62ce6676dbSmrg
63ce6676dbSmrg    /* Do the socket setup that xtrans normally takes care of in
64ce6676dbSmrg     * TRANS(SocketOpen) && TRANS(SocketCreateListener)
65ce6676dbSmrg     */
66ce6676dbSmrg    {
67ce6676dbSmrg	/*
68ce6676dbSmrg	 * turn off TCP coalescence for INET sockets
69ce6676dbSmrg	 */
70ce6676dbSmrg
71ce6676dbSmrg	int tmp = 1;
72ce6676dbSmrg	setsockopt (fd, IPPROTO_TCP, TCP_NODELAY,
73ce6676dbSmrg		    (char *) &tmp, sizeof (int));
74ce6676dbSmrg    }
75ce6676dbSmrg#ifdef SO_DONTLINGER
76ce6676dbSmrg    setsockopt (fd, SOL_SOCKET, SO_DONTLINGER, NULL, 0);
77ce6676dbSmrg#else
78ce6676dbSmrg# ifdef SO_LINGER
79ce6676dbSmrg    {
80ce6676dbSmrg	static int linger[2] = { 0, 0 };
81ce6676dbSmrg	setsockopt (fd, SOL_SOCKET, SO_LINGER,
82ce6676dbSmrg		    (char *) linger, sizeof (linger));
83ce6676dbSmrg    }
84ce6676dbSmrg# endif
85ce6676dbSmrg#endif
86ce6676dbSmrg
87ce6676dbSmrg    if (listen (fd, BACKLOG) < 0)
8830e1ba2cSmrg        return NULL;
89ce6676dbSmrg
90ce6676dbSmrg    /* Pass the inetd socket back through the connection setup code
91ce6676dbSmrg     * the same way as a cloned listening port
92ce6676dbSmrg     */
93ce6676dbSmrg    old_listen =  malloc (sizeof (OldListenRec));
94ce6676dbSmrg    if (old_listen != NULL) {
958f34cbf9Ssnj        char *old_port;
96ce6676dbSmrg	TRANS(GetReopenInfo)(inetdCI, &(old_listen->trans_id),
978f34cbf9Ssnj			     &(old_listen->fd), &old_port);
98ce6676dbSmrg
99ce6676dbSmrg	old_listen->portnum = portnum;
100ce6676dbSmrg    }
101ce6676dbSmrg
102ce6676dbSmrg    return old_listen;
103ce6676dbSmrg}
104ce6676dbSmrg#endif /* XFS_INETD */
105