misc.c revision a3129944
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
44a3129944Smrg
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    {
57a3129944Smrg	free (iceConn->scratch);
58266e564dSmrg
59fb5e8d76Smrg	iceConn->scratch = malloc (size);
60266e564dSmrg	iceConn->scratch_size = size;
61266e564dSmrg    }
62266e564dSmrg
63266e564dSmrg    return (iceConn->scratch);
64266e564dSmrg}
65266e564dSmrg
66266e564dSmrg
67a3129944Smrg
68266e564dSmrg/*
69266e564dSmrg * Output/Input buffer functions
70266e564dSmrg */
71266e564dSmrg
72266e564dSmrgint
73c5629e66SmrgIceFlush (
74c5629e66Smrg	IceConn iceConn
75c5629e66Smrg)
76266e564dSmrg{
77266e564dSmrg    _IceWrite (iceConn,
78266e564dSmrg	(unsigned long) (iceConn->outbufptr - iceConn->outbuf),
79266e564dSmrg	iceConn->outbuf);
80266e564dSmrg
81266e564dSmrg    iceConn->outbufptr = iceConn->outbuf;
82266e564dSmrg    return 1;
83266e564dSmrg}
84266e564dSmrg
85266e564dSmrg
86266e564dSmrgint
87c5629e66SmrgIceGetOutBufSize (
88c5629e66Smrg	IceConn iceConn
89c5629e66Smrg)
90266e564dSmrg{
91266e564dSmrg    return (iceConn->outbufmax - iceConn->outbuf);
92266e564dSmrg}
93266e564dSmrg
94266e564dSmrg
95266e564dSmrgint
96c5629e66SmrgIceGetInBufSize (
97c5629e66Smrg	IceConn iceConn
98c5629e66Smrg)
99266e564dSmrg{
100266e564dSmrg    return (iceConn->inbufmax - iceConn->inbuf);
101266e564dSmrg}
102266e564dSmrg
103266e564dSmrg
104a3129944Smrg
105266e564dSmrg/*
106266e564dSmrg * informational functions
107266e564dSmrg */
108266e564dSmrg
109266e564dSmrgIceConnectStatus
110c5629e66SmrgIceConnectionStatus (
111c5629e66Smrg	IceConn iceConn
112c5629e66Smrg)
113266e564dSmrg{
114266e564dSmrg    return (iceConn->connection_status);
115266e564dSmrg}
116266e564dSmrg
117266e564dSmrg
118266e564dSmrgchar *
119c5629e66SmrgIceVendor (
120c5629e66Smrg	IceConn iceConn
121c5629e66Smrg)
122266e564dSmrg{
123266e564dSmrg    return strdup(iceConn->vendor);
124266e564dSmrg}
125266e564dSmrg
126266e564dSmrg
127266e564dSmrgchar *
128c5629e66SmrgIceRelease (
129c5629e66Smrg	IceConn iceConn
130c5629e66Smrg)
131266e564dSmrg{
132266e564dSmrg    return strdup(iceConn->release);
133266e564dSmrg}
134266e564dSmrg
135266e564dSmrg
136266e564dSmrgint
137c5629e66SmrgIceProtocolVersion (
138c5629e66Smrg	IceConn iceConn
139c5629e66Smrg)
140266e564dSmrg{
141266e564dSmrg    return (_IceVersions[iceConn->my_ice_version_index].major_version);
142266e564dSmrg}
143266e564dSmrg
144266e564dSmrg
145266e564dSmrgint
146c5629e66SmrgIceProtocolRevision (
147c5629e66Smrg	IceConn iceConn
148c5629e66Smrg)
149266e564dSmrg{
150266e564dSmrg    return (_IceVersions[iceConn->my_ice_version_index].minor_version);
151266e564dSmrg}
152266e564dSmrg
153266e564dSmrg
154266e564dSmrgint
155c5629e66SmrgIceConnectionNumber (
156c5629e66Smrg	IceConn iceConn
157c5629e66Smrg)
158266e564dSmrg{
159266e564dSmrg    return (_IceTransGetConnectionNumber (iceConn->trans_conn));
160266e564dSmrg}
161266e564dSmrg
162266e564dSmrg
163266e564dSmrgchar *
164c5629e66SmrgIceConnectionString (
165c5629e66Smrg	IceConn iceConn
166c5629e66Smrg)
167266e564dSmrg{
168266e564dSmrg    if (iceConn->connection_string)
169266e564dSmrg    {
170266e564dSmrg	return strdup(iceConn->connection_string);
171266e564dSmrg    }
172266e564dSmrg    else
173266e564dSmrg	return (NULL);
174266e564dSmrg}
175266e564dSmrg
176266e564dSmrg
177266e564dSmrgunsigned long
178c5629e66SmrgIceLastSentSequenceNumber (
179c5629e66Smrg	IceConn iceConn
180c5629e66Smrg)
181266e564dSmrg{
182266e564dSmrg    return (iceConn->send_sequence);
183266e564dSmrg}
184266e564dSmrg
185266e564dSmrg
186266e564dSmrgunsigned long
187c5629e66SmrgIceLastReceivedSequenceNumber (
188c5629e66Smrg	IceConn iceConn
189c5629e66Smrg)
190266e564dSmrg{
191266e564dSmrg    return (iceConn->receive_sequence);
192266e564dSmrg}
193266e564dSmrg
194266e564dSmrg
195266e564dSmrgBool
196c5629e66SmrgIceSwapping (
197c5629e66Smrg	IceConn iceConn
198c5629e66Smrg)
199266e564dSmrg{
200266e564dSmrg    return (iceConn->swap);
201266e564dSmrg}
202266e564dSmrg
203266e564dSmrg
204a3129944Smrg
205266e564dSmrg/*
206266e564dSmrg * Read "n" bytes from a connection.
207266e564dSmrg *
208266e564dSmrg * Return Status 0 if we detected an EXPECTED closed connection.
209266e564dSmrg *
210266e564dSmrg */
211266e564dSmrg
212266e564dSmrgStatus
213c5629e66Smrg_IceRead (
214c5629e66Smrg	register IceConn iceConn,
215c5629e66Smrg	unsigned long	 nbytes,
216c5629e66Smrg	register char	 *ptr
217c5629e66Smrg)
218266e564dSmrg{
219266e564dSmrg    register unsigned long nleft;
220266e564dSmrg
221266e564dSmrg    nleft = nbytes;
222266e564dSmrg    while (nleft > 0)
223266e564dSmrg    {
224266e564dSmrg	int nread;
225266e564dSmrg
226266e564dSmrg	if (iceConn->io_ok)
227266e564dSmrg	    nread = _IceTransRead (iceConn->trans_conn, ptr, (int) nleft);
228266e564dSmrg	else
229266e564dSmrg	    return (1);
230266e564dSmrg
231266e564dSmrg	if (nread <= 0)
232266e564dSmrg	{
233266e564dSmrg#ifdef WIN32
234266e564dSmrg	    errno = WSAGetLastError();
235266e564dSmrg#endif
236266e564dSmrg	    if (iceConn->want_to_close)
237266e564dSmrg	    {
238266e564dSmrg		/*
239266e564dSmrg		 * We sent a WantToClose message and now we detected that
240266e564dSmrg		 * the other side closed the connection.
241266e564dSmrg		 */
242266e564dSmrg
243266e564dSmrg		_IceConnectionClosed (iceConn);	    /* invoke watch procs */
244266e564dSmrg
245266e564dSmrg		return (0);
246266e564dSmrg	    }
2479ef0b394Smrg	    else
248266e564dSmrg	    {
249266e564dSmrg		/*
250266e564dSmrg		 * Fatal IO error.  First notify each protocol's IceIOErrorProc
251266e564dSmrg		 * callback, then invoke the application IO error handler.
252266e564dSmrg		 */
253266e564dSmrg
254266e564dSmrg		iceConn->io_ok = False;
255266e564dSmrg
256266e564dSmrg		if (iceConn->connection_status == IceConnectPending)
257266e564dSmrg		{
258266e564dSmrg		    /*
259266e564dSmrg		     * Don't invoke IO error handler if we are in the
260266e564dSmrg		     * middle of a connection setup.
261266e564dSmrg		     */
262266e564dSmrg
263266e564dSmrg		    return (1);
264266e564dSmrg		}
265266e564dSmrg
266266e564dSmrg		if (iceConn->process_msg_info)
267266e564dSmrg		{
268266e564dSmrg		    int i;
269266e564dSmrg
270266e564dSmrg		    for (i = iceConn->his_min_opcode;
271266e564dSmrg			i <= iceConn->his_max_opcode; i++)
272266e564dSmrg		    {
273266e564dSmrg			_IceProcessMsgInfo *process;
274266e564dSmrg
275266e564dSmrg			process = &iceConn->process_msg_info[
276266e564dSmrg			    i - iceConn->his_min_opcode];
277266e564dSmrg
278266e564dSmrg			if ((process != NULL) && process->in_use)
279266e564dSmrg			{
280266e564dSmrg			    IceIOErrorProc IOErrProc = process->accept_flag ?
281266e564dSmrg			      process->protocol->accept_client->io_error_proc :
282266e564dSmrg			      process->protocol->orig_client->io_error_proc;
283266e564dSmrg
284266e564dSmrg			    if (IOErrProc)
285266e564dSmrg				(*IOErrProc) (iceConn);
286266e564dSmrg			}
287266e564dSmrg		    }
288266e564dSmrg		}
289266e564dSmrg
290266e564dSmrg		(*_IceIOErrorHandler) (iceConn);
291266e564dSmrg		return (1);
292266e564dSmrg	    }
293266e564dSmrg	}
294266e564dSmrg
295266e564dSmrg	nleft -= nread;
296266e564dSmrg	ptr   += nread;
297266e564dSmrg    }
298266e564dSmrg
299266e564dSmrg    return (1);
300266e564dSmrg}
301266e564dSmrg
302266e564dSmrg
303a3129944Smrg
304266e564dSmrg/*
305266e564dSmrg * If we read a message header with a bad major or minor opcode,
306266e564dSmrg * we need to advance to the end of the message.  This way, the next
307266e564dSmrg * message can be processed correctly.
308266e564dSmrg */
309266e564dSmrg
310266e564dSmrgvoid
311c5629e66Smrg_IceReadSkip (
312c5629e66Smrg	register IceConn	iceConn,
313c5629e66Smrg	register unsigned long	nbytes
314c5629e66Smrg)
315266e564dSmrg{
316266e564dSmrg    char temp[512];
317266e564dSmrg
318266e564dSmrg    while (nbytes > 0)
319266e564dSmrg    {
320266e564dSmrg	unsigned long rbytes = nbytes > 512 ? 512 : nbytes;
321266e564dSmrg
322266e564dSmrg	_IceRead (iceConn, rbytes, temp);
323266e564dSmrg	nbytes -= rbytes;
324266e564dSmrg    }
325266e564dSmrg}
326266e564dSmrg
327266e564dSmrg
328a3129944Smrg
329266e564dSmrg/*
330266e564dSmrg * Write "n" bytes to a connection.
331266e564dSmrg */
332266e564dSmrg
333266e564dSmrgvoid
334c5629e66Smrg_IceWrite (
335c5629e66Smrg	register IceConn iceConn,
336c5629e66Smrg	unsigned long	 nbytes,
337c5629e66Smrg	register char	 *ptr
338c5629e66Smrg)
339266e564dSmrg{
340266e564dSmrg    register unsigned long nleft;
341266e564dSmrg
342266e564dSmrg    nleft = nbytes;
343266e564dSmrg    while (nleft > 0)
344266e564dSmrg    {
345266e564dSmrg	int nwritten;
346266e564dSmrg
347266e564dSmrg	if (iceConn->io_ok)
348266e564dSmrg	    nwritten = _IceTransWrite (iceConn->trans_conn, ptr, (int) nleft);
349266e564dSmrg	else
350266e564dSmrg	    return;
351266e564dSmrg
352266e564dSmrg	if (nwritten <= 0)
353266e564dSmrg	{
354266e564dSmrg#ifdef WIN32
355266e564dSmrg	    errno = WSAGetLastError();
356266e564dSmrg#endif
357266e564dSmrg	    /*
358266e564dSmrg	     * Fatal IO error.  First notify each protocol's IceIOErrorProc
359266e564dSmrg	     * callback, then invoke the application IO error handler.
360266e564dSmrg	     */
361266e564dSmrg
362266e564dSmrg	    iceConn->io_ok = False;
363266e564dSmrg
364266e564dSmrg	    if (iceConn->connection_status == IceConnectPending)
365266e564dSmrg	    {
366266e564dSmrg		/*
367266e564dSmrg		 * Don't invoke IO error handler if we are in the
368266e564dSmrg		 * middle of a connection setup.
369266e564dSmrg		 */
370266e564dSmrg
371266e564dSmrg		return;
372266e564dSmrg	    }
373266e564dSmrg
374266e564dSmrg	    if (iceConn->process_msg_info)
375266e564dSmrg	    {
376266e564dSmrg		int i;
377266e564dSmrg
378266e564dSmrg		for (i = iceConn->his_min_opcode;
379266e564dSmrg		     i <= iceConn->his_max_opcode; i++)
380266e564dSmrg		{
381266e564dSmrg		    _IceProcessMsgInfo *process;
382266e564dSmrg
383266e564dSmrg		    process = &iceConn->process_msg_info[
384266e564dSmrg			i - iceConn->his_min_opcode];
385266e564dSmrg
386266e564dSmrg		    if (process->in_use)
387266e564dSmrg		    {
388266e564dSmrg			IceIOErrorProc IOErrProc = process->accept_flag ?
389266e564dSmrg			    process->protocol->accept_client->io_error_proc :
390266e564dSmrg			    process->protocol->orig_client->io_error_proc;
391266e564dSmrg
392266e564dSmrg			if (IOErrProc)
393266e564dSmrg			    (*IOErrProc) (iceConn);
394266e564dSmrg		    }
395266e564dSmrg		}
396266e564dSmrg	    }
397266e564dSmrg
398266e564dSmrg	    (*_IceIOErrorHandler) (iceConn);
399266e564dSmrg	    return;
400266e564dSmrg	}
401266e564dSmrg
402266e564dSmrg	nleft -= nwritten;
403266e564dSmrg	ptr   += nwritten;
404266e564dSmrg    }
405266e564dSmrg}
406266e564dSmrg
407266e564dSmrg
408a3129944Smrg
409266e564dSmrgvoid
410c5629e66Smrg_IceAddOpcodeMapping (
411c5629e66Smrg	IceConn	iceConn,
412c5629e66Smrg	int 	hisOpcode,
413c5629e66Smrg	int 	myOpcode
414c5629e66Smrg)
415266e564dSmrg{
416266e564dSmrg    if (hisOpcode <= 0 || hisOpcode > 255)
417266e564dSmrg    {
418266e564dSmrg	return;
419266e564dSmrg    }
420266e564dSmrg    else if (iceConn->process_msg_info == NULL)
421266e564dSmrg    {
422fb5e8d76Smrg	iceConn->process_msg_info = malloc (sizeof (_IceProcessMsgInfo));
423266e564dSmrg	iceConn->his_min_opcode = iceConn->his_max_opcode = hisOpcode;
424266e564dSmrg    }
425266e564dSmrg    else if (hisOpcode < iceConn->his_min_opcode)
426266e564dSmrg    {
427266e564dSmrg	_IceProcessMsgInfo *oldVec = iceConn->process_msg_info;
428266e564dSmrg	int oldsize = iceConn->his_max_opcode - iceConn->his_min_opcode + 1;
429266e564dSmrg	int newsize = iceConn->his_max_opcode - hisOpcode + 1;
430266e564dSmrg	int i;
431266e564dSmrg
432fb5e8d76Smrg	iceConn->process_msg_info = malloc (
433266e564dSmrg	    newsize * sizeof (_IceProcessMsgInfo));
434266e564dSmrg
435266e564dSmrg	memcpy (&iceConn->process_msg_info[
436266e564dSmrg	    iceConn->his_min_opcode - hisOpcode], oldVec,
437266e564dSmrg	    oldsize * sizeof (_IceProcessMsgInfo));
438266e564dSmrg
439fb5e8d76Smrg	free (oldVec);
440266e564dSmrg
441266e564dSmrg	for (i = hisOpcode + 1; i < iceConn->his_min_opcode; i++)
442266e564dSmrg	{
443266e564dSmrg	    iceConn->process_msg_info[i -
444266e564dSmrg		iceConn->his_min_opcode].in_use = False;
445266e564dSmrg
446266e564dSmrg	    iceConn->process_msg_info[i -
447266e564dSmrg		iceConn->his_min_opcode].protocol = NULL;
448266e564dSmrg	}
449266e564dSmrg
450266e564dSmrg	iceConn->his_min_opcode = hisOpcode;
451266e564dSmrg    }
452266e564dSmrg    else if (hisOpcode > iceConn->his_max_opcode)
453266e564dSmrg    {
454266e564dSmrg	_IceProcessMsgInfo *oldVec = iceConn->process_msg_info;
455266e564dSmrg	int oldsize = iceConn->his_max_opcode - iceConn->his_min_opcode + 1;
456266e564dSmrg	int newsize = hisOpcode - iceConn->his_min_opcode + 1;
457266e564dSmrg	int i;
458266e564dSmrg
459fb5e8d76Smrg	iceConn->process_msg_info = malloc (
460266e564dSmrg	    newsize * sizeof (_IceProcessMsgInfo));
461266e564dSmrg
462266e564dSmrg	memcpy (iceConn->process_msg_info, oldVec,
463266e564dSmrg	    oldsize * sizeof (_IceProcessMsgInfo));
464266e564dSmrg
465fb5e8d76Smrg	free (oldVec);
466266e564dSmrg
467266e564dSmrg	for (i = iceConn->his_max_opcode + 1; i < hisOpcode; i++)
468266e564dSmrg	{
469266e564dSmrg	    iceConn->process_msg_info[i -
470266e564dSmrg		iceConn->his_min_opcode].in_use = False;
471266e564dSmrg
472266e564dSmrg	    iceConn->process_msg_info[i -
473266e564dSmrg		iceConn->his_min_opcode].protocol = NULL;
474266e564dSmrg	}
475266e564dSmrg
476266e564dSmrg	iceConn->his_max_opcode = hisOpcode;
477266e564dSmrg    }
478266e564dSmrg
479266e564dSmrg    iceConn->process_msg_info[hisOpcode -
480266e564dSmrg	iceConn->his_min_opcode].in_use = True;
481266e564dSmrg
482266e564dSmrg    iceConn->process_msg_info[hisOpcode -
483266e564dSmrg	iceConn->his_min_opcode].my_opcode = myOpcode;
484266e564dSmrg
485266e564dSmrg    iceConn->process_msg_info[hisOpcode -
486266e564dSmrg	iceConn->his_min_opcode].protocol = &_IceProtocols[myOpcode - 1];
487266e564dSmrg}
488266e564dSmrg
489266e564dSmrg
490a3129944Smrg
491266e564dSmrgchar *
492266e564dSmrgIceGetPeerName (IceConn iceConn)
493266e564dSmrg{
494266e564dSmrg    return (_IceTransGetPeerNetworkId (iceConn->trans_conn));
495266e564dSmrg}
496266e564dSmrg
497a3129944Smrg
498266e564dSmrgchar *
499266e564dSmrg_IceGetPeerName (IceConn iceConn)
500266e564dSmrg{
501266e564dSmrg    return (IceGetPeerName(iceConn));
502266e564dSmrg}
503