1 /******************************************************************************
2 
3 
4 Copyright 1993, 1998  The Open Group
5 
6 Permission to use, copy, modify, distribute, and sell this software and its
7 documentation for any purpose is hereby granted without fee, provided that
8 the above copyright notice appear in all copies and that both that
9 copyright notice and this permission notice appear in supporting
10 documentation.
11 
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
14 
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 
22 Except as contained in this notice, the name of The Open Group shall not be
23 used in advertising or otherwise to promote the sale, use or other dealings
24 in this Software without prior written authorization from The Open Group.
25 
26 Author: Ralph Mor, X Consortium
27 ******************************************************************************/
28 
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32 #include <X11/ICE/ICElib.h>
33 #include "ICElibint.h"
34 #include <X11/Xtrans/Xtrans.h>
35 
36 
37 IceConn
IceAcceptConnection(IceListenObj listenObj,IceAcceptStatus * statusRet)38 IceAcceptConnection (
39 	IceListenObj 	listenObj,
40 	IceAcceptStatus	*statusRet
41 )
42 {
43     IceConn    		iceConn;
44     XtransConnInfo	newconn;
45     iceByteOrderMsg 	*pMsg;
46     int   		endian, status;
47 
48     /*
49      * Accept the connection.
50      */
51 
52     if ((newconn = _IceTransAccept (listenObj->trans_conn, &status)) == NULL)
53     {
54 	if (status == TRANS_ACCEPT_BAD_MALLOC)
55 	    *statusRet = IceAcceptBadMalloc;
56 	else
57 	    *statusRet = IceAcceptFailure;
58 	return (NULL);
59     }
60 
61 
62     /*
63      * Set close-on-exec so that programs that fork() don't get confused.
64      */
65 
66     _IceTransSetOption (newconn, TRANS_CLOSEONEXEC, 1);
67 
68 
69     /*
70      * Create an ICE object for this connection.
71      */
72 
73     if ((iceConn = malloc (sizeof (struct _IceConn))) == NULL)
74     {
75 	_IceTransClose (newconn);
76 	*statusRet = IceAcceptBadMalloc;
77 	return (NULL);
78     }
79 
80     iceConn->listen_obj = listenObj;
81 
82     iceConn->waiting_for_byteorder = True;
83     iceConn->connection_status = IceConnectPending;
84     iceConn->io_ok = True;
85     iceConn->dispatch_level = 0;
86     iceConn->context = NULL;
87     iceConn->my_ice_version_index = 0;
88 
89     iceConn->trans_conn = newconn;
90     iceConn->send_sequence = 0;
91     iceConn->receive_sequence = 0;
92 
93     iceConn->connection_string = strdup(listenObj->network_id);
94 
95     if (iceConn->connection_string == NULL)
96     {
97 	_IceTransClose (newconn);
98 	free (iceConn);
99 	*statusRet = IceAcceptBadMalloc;
100 	return (NULL);
101     }
102 
103     iceConn->vendor = NULL;
104     iceConn->release = NULL;
105 
106     if ((iceConn->inbuf = iceConn->inbufptr = malloc (ICE_INBUFSIZE)) != NULL)
107     {
108 	iceConn->inbufmax = iceConn->inbuf + ICE_INBUFSIZE;
109     }
110     else
111     {
112 	_IceTransClose (newconn);
113 	free (iceConn->connection_string);
114 	free (iceConn);
115 	*statusRet = IceAcceptBadMalloc;
116 	return (NULL);
117     }
118 
119     if ((iceConn->outbuf = iceConn->outbufptr = malloc (ICE_OUTBUFSIZE)) != NULL)
120     {
121 	iceConn->outbufmax = iceConn->outbuf + ICE_OUTBUFSIZE;
122     }
123     else
124     {
125 	_IceTransClose (newconn);
126 	free (iceConn->connection_string);
127 	free (iceConn->inbuf);
128 	free (iceConn);
129 	*statusRet = IceAcceptBadMalloc;
130 	return (NULL);
131     }
132 
133     iceConn->scratch = NULL;
134     iceConn->scratch_size = 0;
135 
136     iceConn->open_ref_count = 1;
137     iceConn->proto_ref_count = 0;
138 
139     iceConn->skip_want_to_close = False;
140     iceConn->want_to_close = False;
141     iceConn->free_asap = False;
142 
143     iceConn->saved_reply_waits = NULL;
144     iceConn->ping_waits = NULL;
145 
146     iceConn->process_msg_info = NULL;
147 
148     iceConn->connect_to_you = NULL;
149     iceConn->protosetup_to_you = NULL;
150 
151     iceConn->connect_to_me = NULL;
152     iceConn->protosetup_to_me = NULL;
153 
154 
155     /*
156      * Send our byte order.
157      */
158 
159     IceGetHeader (iceConn, 0, ICE_ByteOrder,
160 	SIZEOF (iceByteOrderMsg), iceByteOrderMsg, pMsg);
161 
162     endian = 1;
163     if (*(char *) &endian)
164 	pMsg->byteOrder = IceLSBfirst;
165     else
166 	pMsg->byteOrder = IceMSBfirst;
167 
168     IceFlush (iceConn);
169 
170 
171     if (_IceWatchProcs)
172     {
173 	/*
174 	 * Notify the watch procedures that an iceConn was opened.
175 	 */
176 
177 	_IceConnectionOpened (iceConn);
178     }
179 
180     *statusRet = IceAcceptSuccess;
181 
182     return (iceConn);
183 }
184