misc.c revision fb5e8d76
1266e564dSmrg/******************************************************************************
2266e564dSmrg
3266e564dSmrg
4266e564dSmrgCopyright 1993, 1998  The Open Group
5266e564dSmrg
6266e564dSmrgPermission to use, copy, modify, distribute, and sell this software and its
7266e564dSmrgdocumentation for any purpose is hereby granted without fee, provided that
8266e564dSmrgthe above copyright notice appear in all copies and that both that
9266e564dSmrgcopyright notice and this permission notice appear in supporting
10266e564dSmrgdocumentation.
11266e564dSmrg
12266e564dSmrgThe above copyright notice and this permission notice shall be included in
13266e564dSmrgall copies or substantial portions of the Software.
14266e564dSmrg
15266e564dSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16266e564dSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17266e564dSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18266e564dSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19266e564dSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20266e564dSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21266e564dSmrg
22266e564dSmrgExcept as contained in this notice, the name of The Open Group shall not be
23266e564dSmrgused in advertising or otherwise to promote the sale, use or other dealings
24266e564dSmrgin this Software without prior written authorization from The Open Group.
25266e564dSmrg
26266e564dSmrgAuthor: Ralph Mor, X Consortium
27266e564dSmrg******************************************************************************/
28266e564dSmrg
29266e564dSmrg#ifdef WIN32
30266e564dSmrg#define _WILLWINSOCK_
31266e564dSmrg#endif
32266e564dSmrg#ifdef HAVE_CONFIG_H
33266e564dSmrg#include <config.h>
34266e564dSmrg#endif
35266e564dSmrg#include <X11/ICE/ICElib.h>
36266e564dSmrg#include "ICElibint.h"
37266e564dSmrg#include <X11/Xtrans/Xtrans.h>
38266e564dSmrg#include <stdio.h>
39266e564dSmrg#ifdef WIN32
40266e564dSmrg#include <X11/Xwinsock.h>
41266e564dSmrg#include <X11/Xw32defs.h>
42266e564dSmrg#endif
43266e564dSmrg
44266e564dSmrg
45266e564dSmrg/*
46266e564dSmrg * scratch buffer
47266e564dSmrg */
48266e564dSmrg
49266e564dSmrgchar *
50c5629e66SmrgIceAllocScratch (
51c5629e66Smrg	IceConn		iceConn,
52c5629e66Smrg	unsigned long	size
53c5629e66Smrg)
54266e564dSmrg{
55266e564dSmrg    if (!iceConn->scratch || size > iceConn->scratch_size)
56266e564dSmrg    {
57266e564dSmrg	if (iceConn->scratch)
58266e564dSmrg	    free (iceConn->scratch);
59266e564dSmrg
60fb5e8d76Smrg	iceConn->scratch = malloc (size);
61266e564dSmrg	iceConn->scratch_size = size;
62266e564dSmrg    }
63266e564dSmrg
64266e564dSmrg    return (iceConn->scratch);
65266e564dSmrg}
66266e564dSmrg
67266e564dSmrg
68266e564dSmrg
69266e564dSmrg/*
70266e564dSmrg * Output/Input buffer functions
71266e564dSmrg */
72266e564dSmrg
73266e564dSmrgint
74c5629e66SmrgIceFlush (
75c5629e66Smrg	IceConn iceConn
76c5629e66Smrg)
77266e564dSmrg{
78266e564dSmrg    _IceWrite (iceConn,
79266e564dSmrg	(unsigned long) (iceConn->outbufptr - iceConn->outbuf),
80266e564dSmrg	iceConn->outbuf);
81266e564dSmrg
82266e564dSmrg    iceConn->outbufptr = iceConn->outbuf;
83266e564dSmrg    return 1;
84266e564dSmrg}
85266e564dSmrg
86266e564dSmrg
87266e564dSmrgint
88c5629e66SmrgIceGetOutBufSize (
89c5629e66Smrg	IceConn iceConn
90c5629e66Smrg)
91266e564dSmrg{
92266e564dSmrg    return (iceConn->outbufmax - iceConn->outbuf);
93266e564dSmrg}
94266e564dSmrg
95266e564dSmrg
96266e564dSmrgint
97c5629e66SmrgIceGetInBufSize (
98c5629e66Smrg	IceConn iceConn
99c5629e66Smrg)
100266e564dSmrg{
101266e564dSmrg    return (iceConn->inbufmax - iceConn->inbuf);
102266e564dSmrg}
103266e564dSmrg
104266e564dSmrg
105266e564dSmrg
106266e564dSmrg/*
107266e564dSmrg * informational functions
108266e564dSmrg */
109266e564dSmrg
110266e564dSmrgIceConnectStatus
111c5629e66SmrgIceConnectionStatus (
112c5629e66Smrg	IceConn iceConn
113c5629e66Smrg)
114266e564dSmrg{
115266e564dSmrg    return (iceConn->connection_status);
116266e564dSmrg}
117266e564dSmrg
118266e564dSmrg
119266e564dSmrgchar *
120c5629e66SmrgIceVendor (
121c5629e66Smrg	IceConn iceConn
122c5629e66Smrg)
123266e564dSmrg{
124266e564dSmrg    return strdup(iceConn->vendor);
125266e564dSmrg}
126266e564dSmrg
127266e564dSmrg
128266e564dSmrgchar *
129c5629e66SmrgIceRelease (
130c5629e66Smrg	IceConn iceConn
131c5629e66Smrg)
132266e564dSmrg{
133266e564dSmrg    return strdup(iceConn->release);
134266e564dSmrg}
135266e564dSmrg
136266e564dSmrg
137266e564dSmrgint
138c5629e66SmrgIceProtocolVersion (
139c5629e66Smrg	IceConn iceConn
140c5629e66Smrg)
141266e564dSmrg{
142266e564dSmrg    return (_IceVersions[iceConn->my_ice_version_index].major_version);
143266e564dSmrg}
144266e564dSmrg
145266e564dSmrg
146266e564dSmrgint
147c5629e66SmrgIceProtocolRevision (
148c5629e66Smrg	IceConn iceConn
149c5629e66Smrg)
150266e564dSmrg{
151266e564dSmrg    return (_IceVersions[iceConn->my_ice_version_index].minor_version);
152266e564dSmrg}
153266e564dSmrg
154266e564dSmrg
155266e564dSmrgint
156c5629e66SmrgIceConnectionNumber (
157c5629e66Smrg	IceConn iceConn
158c5629e66Smrg)
159266e564dSmrg{
160266e564dSmrg    return (_IceTransGetConnectionNumber (iceConn->trans_conn));
161266e564dSmrg}
162266e564dSmrg
163266e564dSmrg
164266e564dSmrgchar *
165c5629e66SmrgIceConnectionString (
166c5629e66Smrg	IceConn iceConn
167c5629e66Smrg)
168266e564dSmrg{
169266e564dSmrg    if (iceConn->connection_string)
170266e564dSmrg    {
171266e564dSmrg	return strdup(iceConn->connection_string);
172266e564dSmrg    }
173266e564dSmrg    else
174266e564dSmrg	return (NULL);
175266e564dSmrg}
176266e564dSmrg
177266e564dSmrg
178266e564dSmrgunsigned long
179c5629e66SmrgIceLastSentSequenceNumber (
180c5629e66Smrg	IceConn iceConn
181c5629e66Smrg)
182266e564dSmrg{
183266e564dSmrg    return (iceConn->send_sequence);
184266e564dSmrg}
185266e564dSmrg
186266e564dSmrg
187266e564dSmrgunsigned long
188c5629e66SmrgIceLastReceivedSequenceNumber (
189c5629e66Smrg	IceConn iceConn
190c5629e66Smrg)
191266e564dSmrg{
192266e564dSmrg    return (iceConn->receive_sequence);
193266e564dSmrg}
194266e564dSmrg
195266e564dSmrg
196266e564dSmrgBool
197c5629e66SmrgIceSwapping (
198c5629e66Smrg	IceConn iceConn
199c5629e66Smrg)
200266e564dSmrg{
201266e564dSmrg    return (iceConn->swap);
202266e564dSmrg}
203266e564dSmrg
204266e564dSmrg
205266e564dSmrg
206266e564dSmrg/*
207266e564dSmrg * Read "n" bytes from a connection.
208266e564dSmrg *
209266e564dSmrg * Return Status 0 if we detected an EXPECTED closed connection.
210266e564dSmrg *
211266e564dSmrg */
212266e564dSmrg
213266e564dSmrgStatus
214c5629e66Smrg_IceRead (
215c5629e66Smrg	register IceConn iceConn,
216c5629e66Smrg	unsigned long	 nbytes,
217c5629e66Smrg	register char	 *ptr
218c5629e66Smrg)
219266e564dSmrg{
220266e564dSmrg    register unsigned long nleft;
221266e564dSmrg
222266e564dSmrg    nleft = nbytes;
223266e564dSmrg    while (nleft > 0)
224266e564dSmrg    {
225266e564dSmrg	int nread;
226266e564dSmrg
227266e564dSmrg	if (iceConn->io_ok)
228266e564dSmrg	    nread = _IceTransRead (iceConn->trans_conn, ptr, (int) nleft);
229266e564dSmrg	else
230266e564dSmrg	    return (1);
231266e564dSmrg
232266e564dSmrg	if (nread <= 0)
233266e564dSmrg	{
234266e564dSmrg#ifdef WIN32
235266e564dSmrg	    errno = WSAGetLastError();
236266e564dSmrg#endif
237266e564dSmrg	    if (iceConn->want_to_close)
238266e564dSmrg	    {
239266e564dSmrg		/*
240266e564dSmrg		 * We sent a WantToClose message and now we detected that
241266e564dSmrg		 * the other side closed the connection.
242266e564dSmrg		 */
243266e564dSmrg
244266e564dSmrg		_IceConnectionClosed (iceConn);	    /* invoke watch procs */
245266e564dSmrg		_IceFreeConnection (iceConn);
246266e564dSmrg
247266e564dSmrg		return (0);
248266e564dSmrg	    }
2499ef0b394Smrg	    else
250266e564dSmrg	    {
251266e564dSmrg		/*
252266e564dSmrg		 * Fatal IO error.  First notify each protocol's IceIOErrorProc
253266e564dSmrg		 * callback, then invoke the application IO error handler.
254266e564dSmrg		 */
255266e564dSmrg
256266e564dSmrg		iceConn->io_ok = False;
257266e564dSmrg
258266e564dSmrg		if (iceConn->connection_status == IceConnectPending)
259266e564dSmrg		{
260266e564dSmrg		    /*
261266e564dSmrg		     * Don't invoke IO error handler if we are in the
262266e564dSmrg		     * middle of a connection setup.
263266e564dSmrg		     */
264266e564dSmrg
265266e564dSmrg		    return (1);
266266e564dSmrg		}
267266e564dSmrg
268266e564dSmrg		if (iceConn->process_msg_info)
269266e564dSmrg		{
270266e564dSmrg		    int i;
271266e564dSmrg
272266e564dSmrg		    for (i = iceConn->his_min_opcode;
273266e564dSmrg			i <= iceConn->his_max_opcode; i++)
274266e564dSmrg		    {
275266e564dSmrg			_IceProcessMsgInfo *process;
276266e564dSmrg
277266e564dSmrg			process = &iceConn->process_msg_info[
278266e564dSmrg			    i - iceConn->his_min_opcode];
279266e564dSmrg
280266e564dSmrg			if ((process != NULL) && process->in_use)
281266e564dSmrg			{
282266e564dSmrg			    IceIOErrorProc IOErrProc = process->accept_flag ?
283266e564dSmrg			      process->protocol->accept_client->io_error_proc :
284266e564dSmrg			      process->protocol->orig_client->io_error_proc;
285266e564dSmrg
286266e564dSmrg			    if (IOErrProc)
287266e564dSmrg				(*IOErrProc) (iceConn);
288266e564dSmrg			}
289266e564dSmrg		    }
290266e564dSmrg		}
291266e564dSmrg
292266e564dSmrg		(*_IceIOErrorHandler) (iceConn);
293266e564dSmrg		return (1);
294266e564dSmrg	    }
295266e564dSmrg	}
296266e564dSmrg
297266e564dSmrg	nleft -= nread;
298266e564dSmrg	ptr   += nread;
299266e564dSmrg    }
300266e564dSmrg
301266e564dSmrg    return (1);
302266e564dSmrg}
303266e564dSmrg
304266e564dSmrg
305266e564dSmrg
306266e564dSmrg/*
307266e564dSmrg * If we read a message header with a bad major or minor opcode,
308266e564dSmrg * we need to advance to the end of the message.  This way, the next
309266e564dSmrg * message can be processed correctly.
310266e564dSmrg */
311266e564dSmrg
312266e564dSmrgvoid
313c5629e66Smrg_IceReadSkip (
314c5629e66Smrg	register IceConn	iceConn,
315c5629e66Smrg	register unsigned long	nbytes
316c5629e66Smrg)
317266e564dSmrg{
318266e564dSmrg    char temp[512];
319266e564dSmrg
320266e564dSmrg    while (nbytes > 0)
321266e564dSmrg    {
322266e564dSmrg	unsigned long rbytes = nbytes > 512 ? 512 : nbytes;
323266e564dSmrg
324266e564dSmrg	_IceRead (iceConn, rbytes, temp);
325266e564dSmrg	nbytes -= rbytes;
326266e564dSmrg    }
327266e564dSmrg}
328266e564dSmrg
329266e564dSmrg
330266e564dSmrg
331266e564dSmrg/*
332266e564dSmrg * Write "n" bytes to a connection.
333266e564dSmrg */
334266e564dSmrg
335266e564dSmrgvoid
336c5629e66Smrg_IceWrite (
337c5629e66Smrg	register IceConn iceConn,
338c5629e66Smrg	unsigned long	 nbytes,
339c5629e66Smrg	register char	 *ptr
340c5629e66Smrg)
341266e564dSmrg{
342266e564dSmrg    register unsigned long nleft;
343266e564dSmrg
344266e564dSmrg    nleft = nbytes;
345266e564dSmrg    while (nleft > 0)
346266e564dSmrg    {
347266e564dSmrg	int nwritten;
348266e564dSmrg
349266e564dSmrg	if (iceConn->io_ok)
350266e564dSmrg	    nwritten = _IceTransWrite (iceConn->trans_conn, ptr, (int) nleft);
351266e564dSmrg	else
352266e564dSmrg	    return;
353266e564dSmrg
354266e564dSmrg	if (nwritten <= 0)
355266e564dSmrg	{
356266e564dSmrg#ifdef WIN32
357266e564dSmrg	    errno = WSAGetLastError();
358266e564dSmrg#endif
359266e564dSmrg	    /*
360266e564dSmrg	     * Fatal IO error.  First notify each protocol's IceIOErrorProc
361266e564dSmrg	     * callback, then invoke the application IO error handler.
362266e564dSmrg	     */
363266e564dSmrg
364266e564dSmrg	    iceConn->io_ok = False;
365266e564dSmrg
366266e564dSmrg	    if (iceConn->connection_status == IceConnectPending)
367266e564dSmrg	    {
368266e564dSmrg		/*
369266e564dSmrg		 * Don't invoke IO error handler if we are in the
370266e564dSmrg		 * middle of a connection setup.
371266e564dSmrg		 */
372266e564dSmrg
373266e564dSmrg		return;
374266e564dSmrg	    }
375266e564dSmrg
376266e564dSmrg	    if (iceConn->process_msg_info)
377266e564dSmrg	    {
378266e564dSmrg		int i;
379266e564dSmrg
380266e564dSmrg		for (i = iceConn->his_min_opcode;
381266e564dSmrg		     i <= iceConn->his_max_opcode; i++)
382266e564dSmrg		{
383266e564dSmrg		    _IceProcessMsgInfo *process;
384266e564dSmrg
385266e564dSmrg		    process = &iceConn->process_msg_info[
386266e564dSmrg			i - iceConn->his_min_opcode];
387266e564dSmrg
388266e564dSmrg		    if (process->in_use)
389266e564dSmrg		    {
390266e564dSmrg			IceIOErrorProc IOErrProc = process->accept_flag ?
391266e564dSmrg			    process->protocol->accept_client->io_error_proc :
392266e564dSmrg			    process->protocol->orig_client->io_error_proc;
393266e564dSmrg
394266e564dSmrg			if (IOErrProc)
395266e564dSmrg			    (*IOErrProc) (iceConn);
396266e564dSmrg		    }
397266e564dSmrg		}
398266e564dSmrg	    }
399266e564dSmrg
400266e564dSmrg	    (*_IceIOErrorHandler) (iceConn);
401266e564dSmrg	    return;
402266e564dSmrg	}
403266e564dSmrg
404266e564dSmrg	nleft -= nwritten;
405266e564dSmrg	ptr   += nwritten;
406266e564dSmrg    }
407266e564dSmrg}
408266e564dSmrg
409266e564dSmrg
410266e564dSmrg
411266e564dSmrgvoid
412c5629e66Smrg_IceAddOpcodeMapping (
413c5629e66Smrg	IceConn	iceConn,
414c5629e66Smrg	int 	hisOpcode,
415c5629e66Smrg	int 	myOpcode
416c5629e66Smrg)
417266e564dSmrg{
418266e564dSmrg    if (hisOpcode <= 0 || hisOpcode > 255)
419266e564dSmrg    {
420266e564dSmrg	return;
421266e564dSmrg    }
422266e564dSmrg    else if (iceConn->process_msg_info == NULL)
423266e564dSmrg    {
424fb5e8d76Smrg	iceConn->process_msg_info = malloc (sizeof (_IceProcessMsgInfo));
425266e564dSmrg	iceConn->his_min_opcode = iceConn->his_max_opcode = hisOpcode;
426266e564dSmrg    }
427266e564dSmrg    else if (hisOpcode < iceConn->his_min_opcode)
428266e564dSmrg    {
429266e564dSmrg	_IceProcessMsgInfo *oldVec = iceConn->process_msg_info;
430266e564dSmrg	int oldsize = iceConn->his_max_opcode - iceConn->his_min_opcode + 1;
431266e564dSmrg	int newsize = iceConn->his_max_opcode - hisOpcode + 1;
432266e564dSmrg	int i;
433266e564dSmrg
434fb5e8d76Smrg	iceConn->process_msg_info = malloc (
435266e564dSmrg	    newsize * sizeof (_IceProcessMsgInfo));
436266e564dSmrg
437266e564dSmrg	memcpy (&iceConn->process_msg_info[
438266e564dSmrg	    iceConn->his_min_opcode - hisOpcode], oldVec,
439266e564dSmrg	    oldsize * sizeof (_IceProcessMsgInfo));
440266e564dSmrg
441fb5e8d76Smrg	free (oldVec);
442266e564dSmrg
443266e564dSmrg	for (i = hisOpcode + 1; i < iceConn->his_min_opcode; i++)
444266e564dSmrg	{
445266e564dSmrg	    iceConn->process_msg_info[i -
446266e564dSmrg		iceConn->his_min_opcode].in_use = False;
447266e564dSmrg
448266e564dSmrg	    iceConn->process_msg_info[i -
449266e564dSmrg		iceConn->his_min_opcode].protocol = NULL;
450266e564dSmrg	}
451266e564dSmrg
452266e564dSmrg	iceConn->his_min_opcode = hisOpcode;
453266e564dSmrg    }
454266e564dSmrg    else if (hisOpcode > iceConn->his_max_opcode)
455266e564dSmrg    {
456266e564dSmrg	_IceProcessMsgInfo *oldVec = iceConn->process_msg_info;
457266e564dSmrg	int oldsize = iceConn->his_max_opcode - iceConn->his_min_opcode + 1;
458266e564dSmrg	int newsize = hisOpcode - iceConn->his_min_opcode + 1;
459266e564dSmrg	int i;
460266e564dSmrg
461fb5e8d76Smrg	iceConn->process_msg_info = malloc (
462266e564dSmrg	    newsize * sizeof (_IceProcessMsgInfo));
463266e564dSmrg
464266e564dSmrg	memcpy (iceConn->process_msg_info, oldVec,
465266e564dSmrg	    oldsize * sizeof (_IceProcessMsgInfo));
466266e564dSmrg
467fb5e8d76Smrg	free (oldVec);
468266e564dSmrg
469266e564dSmrg	for (i = iceConn->his_max_opcode + 1; i < hisOpcode; i++)
470266e564dSmrg	{
471266e564dSmrg	    iceConn->process_msg_info[i -
472266e564dSmrg		iceConn->his_min_opcode].in_use = False;
473266e564dSmrg
474266e564dSmrg	    iceConn->process_msg_info[i -
475266e564dSmrg		iceConn->his_min_opcode].protocol = NULL;
476266e564dSmrg	}
477266e564dSmrg
478266e564dSmrg	iceConn->his_max_opcode = hisOpcode;
479266e564dSmrg    }
480266e564dSmrg
481266e564dSmrg    iceConn->process_msg_info[hisOpcode -
482266e564dSmrg	iceConn->his_min_opcode].in_use = True;
483266e564dSmrg
484266e564dSmrg    iceConn->process_msg_info[hisOpcode -
485266e564dSmrg	iceConn->his_min_opcode].my_opcode = myOpcode;
486266e564dSmrg
487266e564dSmrg    iceConn->process_msg_info[hisOpcode -
488266e564dSmrg	iceConn->his_min_opcode].protocol = &_IceProtocols[myOpcode - 1];
489266e564dSmrg}
490266e564dSmrg
491266e564dSmrg
492266e564dSmrg
493266e564dSmrgchar *
494266e564dSmrgIceGetPeerName (IceConn iceConn)
495266e564dSmrg{
496266e564dSmrg    return (_IceTransGetPeerNetworkId (iceConn->trans_conn));
497266e564dSmrg}
498266e564dSmrg
499266e564dSmrg
500266e564dSmrgchar *
501266e564dSmrg_IceGetPeerName (IceConn iceConn)
502266e564dSmrg{
503266e564dSmrg    return (IceGetPeerName(iceConn));
504266e564dSmrg}
505