imTransR.c revision 818534a1
1/*
2 * Copyright 1992 Oracle and/or its affiliates. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * 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
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23/******************************************************************
24
25              Copyright 1992, 1993, 1994 by FUJITSU LIMITED
26
27Permission to use, copy, modify, distribute, and sell this software
28and its documentation for any purpose is hereby granted without fee,
29provided that the above copyright notice appear in all copies and
30that both that copyright notice and this permission notice appear
31in supporting documentation, and that the name of FUJITSU LIMITED
32not be used in advertising or publicity pertaining to distribution
33of the software without specific, written prior permission.
34FUJITSU LIMITED makes no representations about the suitability of
35this software for any purpose.
36It is provided "as is" without express or implied warranty.
37
38FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
39INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
40EVENT SHALL FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR
41CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
42USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
43OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
44PERFORMANCE OF THIS SOFTWARE.
45
46  Author: Hideki Hiura (hhiura@Sun.COM) Sun Microsystems, Inc.
47          Takashi Fujiwara     FUJITSU LIMITED
48                               fujiwara@a80.tech.yk.fujitsu.co.jp
49
50******************************************************************/
51
52#ifdef HAVE_CONFIG_H
53#include <config.h>
54#endif
55#include "Xlibint.h"
56#include "Xlcint.h"
57#include "XimTrInt.h"
58#include "Ximint.h"
59
60TransportSW _XimTransportRec[] = {
61    { "X",          _XimXConf },  /* 1st entry must be X.
62					This will be a fallback */
63#ifdef TCPCONN
64    { "tcp",        _XimTransConf }, /* use X transport lib */
65#endif /* TCPCONN */
66#if defined(UNIXCONN) || defined(LOCALCONN)
67    { "local",      _XimTransConf }, /* use X transport lib */
68#endif /* UNIXCONN */
69    { (char *)NULL, (Bool (*)(Xim, char *))NULL },
70};
71
72Bool
73_XimConnect(Xim im)
74{
75    return im->private.proto.connect(im);
76}
77
78Bool
79_XimShutdown(Xim im)
80{
81    return im->private.proto.shutdown(im);
82}
83
84Bool
85_XimWrite(Xim im, INT16 len, XPointer data)
86{
87    return im->private.proto.write(im, len, data);
88}
89
90static int
91_CheckProtocolData(
92    Xim		  im,
93    char	 *recv_buf)
94{
95    int		 data_len;
96
97    data_len = (int)(((*((CARD16 *)recv_buf + 1)) * 4) + XIM_HEADER_SIZE);
98    return data_len;
99}
100
101static int
102_XimReadData(
103    Xim		 im,
104    INT16	*len,
105    XPointer	 buf,
106    int		 buf_size)
107{
108    char	*hold_buf;
109    char	*tmp;
110    int		 data_len;
111    int		 packet_size;
112    int		 ret_len;
113    register int i;
114
115    if (buf_size < XIM_HEADER_SIZE) {
116	*len = (INT16)XIM_HEADER_SIZE;
117	return XIM_OVERFLOW;
118    }
119
120    bzero(buf, buf_size);
121    packet_size = 0;
122    data_len = 0;
123
124    if ((hold_buf = im->private.proto.hold_data)) {
125	data_len = im->private.proto.hold_data_len;
126	if (data_len >= XIM_HEADER_SIZE) {
127	    packet_size = _CheckProtocolData(im, hold_buf);
128	    if (packet_size > buf_size) {
129		*len = (INT16)packet_size;
130		return XIM_OVERFLOW;
131	    }
132	    if (packet_size <= data_len) {
133		memcpy(buf, hold_buf, packet_size);
134		for (i = packet_size; i < data_len; i++) {
135		    if (hold_buf[i])
136			break;
137		}
138		data_len -= i;
139
140		if (data_len) {
141		    if (!(tmp = Xmalloc(data_len))) {
142			return XIM_FALSE;
143		    }
144		    memcpy(tmp, &hold_buf[i], data_len);
145		    im->private.proto.hold_data = tmp;
146		    im->private.proto.hold_data_len = data_len;
147		} else {
148		    im->private.proto.hold_data = 0;
149		    im->private.proto.hold_data_len = 0;
150		}
151		Xfree(hold_buf);
152		*len = (INT16)packet_size;
153		return XIM_TRUE;
154	    }
155	}
156	memcpy(buf, hold_buf, data_len);
157	buf_size -= data_len;
158	Xfree(hold_buf);
159	im->private.proto.hold_data = 0;
160	im->private.proto.hold_data_len = 0;
161    }
162
163    if (!packet_size) {
164	while (data_len < XIM_HEADER_SIZE) {
165	    if (!(im->private.proto.read(im,
166			(XPointer)&buf[data_len], buf_size, &ret_len))) {
167		return XIM_FALSE;
168	    }
169	    data_len += ret_len;
170	    buf_size -= ret_len;
171	}
172	packet_size = _CheckProtocolData(im, buf);
173    }
174
175    if (packet_size > buf_size) {
176	if (!(tmp = Xmalloc(data_len))) {
177	    return XIM_FALSE;
178	}
179	memcpy(tmp, buf, data_len);
180	bzero(buf, data_len);
181	im->private.proto.hold_data = tmp;
182	im->private.proto.hold_data_len = data_len;
183	*len = (INT16)packet_size;
184	return XIM_OVERFLOW;
185    }
186
187    while (data_len < packet_size) {
188	if (!(im->private.proto.read(im,
189			(XPointer)&buf[data_len], buf_size, &ret_len))) {
190	    return XIM_FALSE;
191	}
192	data_len += ret_len;
193	buf_size -= ret_len;
194    }
195
196    for (i = packet_size; i < data_len; i++) {
197	if (buf[i])
198	    break;
199    }
200    data_len -= i;
201
202    if (data_len) {
203	if (!(tmp = Xmalloc(data_len))) {
204	    return XIM_FALSE;
205	}
206	memcpy(tmp, &buf[i], data_len);
207	bzero(&buf[i], data_len);
208	im->private.proto.hold_data = tmp;
209	im->private.proto.hold_data_len = data_len;
210    } else {
211	im->private.proto.hold_data = 0;
212	im->private.proto.hold_data_len = 0;
213    }
214    *len = (INT16)packet_size;
215    return XIM_TRUE;
216}
217
218static Bool
219_XimCallDispatcher(
220    Xim		 im,
221    INT16	 len,
222    XPointer	 data)
223{
224    return im->private.proto.call_dispatcher(im, len, data);
225}
226
227int
228_XimRead(Xim im, INT16 *len, XPointer buf, int buf_size,
229	 Bool (*predicate)(Xim, INT16, XPointer, XPointer), XPointer arg)
230{
231    INT16	 read_len;
232    int		 ret_code;
233
234    for (;;) {
235	ret_code = _XimReadData(im, &read_len, buf, buf_size);
236	if(ret_code != XIM_TRUE) {
237	    return ret_code;
238	}
239	if ((*predicate)(im, read_len, buf, arg))
240	    break;
241	if (_XimCallDispatcher(im, read_len, buf))
242	    continue;
243	_XimError(im, 0, XIM_BadProtocol, (INT16)0, (CARD16)0, (char *)NULL);
244    }
245    *len = read_len;
246    return True;
247}
248
249Bool
250_XimRegisterDispatcher(
251    Xim		 im,
252    Bool	 (*callback)(
253			     Xim, INT16, XPointer, XPointer
254			     ),
255    XPointer	 call_data)
256{
257    return im->private.proto.register_dispatcher(im, callback, call_data);
258}
259
260void
261_XimFlush(Xim im)
262{
263    im->private.proto.flush(im);
264    return;
265}
266
267Bool
268_XimFilterWaitEvent(Xim im)
269{
270    INT16	 read_len;
271    CARD32	 reply32[BUFSIZE/4];
272    char	*reply = (char *)reply32;
273    XPointer	 preply;
274    int		 buf_size;
275    int		 ret_code;
276
277    buf_size = BUFSIZE;
278    ret_code = _XimReadData(im, &read_len, (XPointer)reply, buf_size);
279    if(ret_code == XIM_TRUE) {
280	preply = reply;
281    } else if(ret_code == XIM_OVERFLOW) {
282	if(read_len <= 0) {
283	    preply = reply;
284	} else {
285	    buf_size = (int)read_len;
286	    preply = Xmalloc(buf_size);
287	    ret_code = _XimReadData(im, &read_len, preply, buf_size);
288	    if(ret_code != XIM_TRUE) {
289		if (preply != reply)
290		    Xfree(preply);
291		return False;
292	    }
293	}
294    } else {
295	return False;
296    }
297    if (_XimCallDispatcher(im, read_len, preply)) {
298	if(reply != preply)
299	    Xfree(preply);
300	return True;
301    }
302    _XimError(im, 0, XIM_BadProtocol, (INT16)0, (CARD16)0, (char *)NULL);
303    if(reply != preply)
304	Xfree(preply);
305    return True;
306}
307