misc.c revision c5629e66
1/* $Xorg: misc.c,v 1.4 2001/02/09 02:03:26 xorgcvs Exp $ */
2/******************************************************************************
3
4
5Copyright 1993, 1998  The Open Group
6
7Permission to use, copy, modify, distribute, and sell this software and its
8documentation for any purpose is hereby granted without fee, provided that
9the above copyright notice appear in all copies and that both that
10copyright notice and this permission notice appear in supporting
11documentation.
12
13The above copyright notice and this permission notice shall be included in
14all copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
19OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23Except as contained in this notice, the name of The Open Group shall not be
24used in advertising or otherwise to promote the sale, use or other dealings
25in this Software without prior written authorization from The Open Group.
26
27Author: Ralph Mor, X Consortium
28******************************************************************************/
29/* $XFree86: xc/lib/ICE/misc.c,v 1.3 2001/01/17 19:41:29 dawes Exp $ */
30
31#ifdef WIN32
32#define _WILLWINSOCK_
33#endif
34#ifdef HAVE_CONFIG_H
35#include <config.h>
36#endif
37#include <X11/ICE/ICElib.h>
38#include "ICElibint.h"
39#include <X11/Xtrans/Xtrans.h>
40#include <stdio.h>
41#ifdef WIN32
42#include <X11/Xwinsock.h>
43#include <X11/Xw32defs.h>
44#endif
45
46
47/*
48 * scratch buffer
49 */
50
51char *
52IceAllocScratch (
53	IceConn		iceConn,
54	unsigned long	size
55)
56{
57    if (!iceConn->scratch || size > iceConn->scratch_size)
58    {
59	if (iceConn->scratch)
60	    free (iceConn->scratch);
61
62	iceConn->scratch = (char *) malloc ((unsigned) size);
63	iceConn->scratch_size = size;
64    }
65
66    return (iceConn->scratch);
67}
68
69
70
71/*
72 * Output/Input buffer functions
73 */
74
75int
76IceFlush (
77	IceConn iceConn
78)
79{
80    _IceWrite (iceConn,
81	(unsigned long) (iceConn->outbufptr - iceConn->outbuf),
82	iceConn->outbuf);
83
84    iceConn->outbufptr = iceConn->outbuf;
85    return 1;
86}
87
88
89int
90IceGetOutBufSize (
91	IceConn iceConn
92)
93{
94    return (iceConn->outbufmax - iceConn->outbuf);
95}
96
97
98int
99IceGetInBufSize (
100	IceConn iceConn
101)
102{
103    return (iceConn->inbufmax - iceConn->inbuf);
104}
105
106
107
108/*
109 * informational functions
110 */
111
112IceConnectStatus
113IceConnectionStatus (
114	IceConn iceConn
115)
116{
117    return (iceConn->connection_status);
118}
119
120
121char *
122IceVendor (
123	IceConn iceConn
124)
125{
126    return strdup(iceConn->vendor);
127}
128
129
130char *
131IceRelease (
132	IceConn iceConn
133)
134{
135    return strdup(iceConn->release);
136}
137
138
139int
140IceProtocolVersion (
141	IceConn iceConn
142)
143{
144    return (_IceVersions[iceConn->my_ice_version_index].major_version);
145}
146
147
148int
149IceProtocolRevision (
150	IceConn iceConn
151)
152{
153    return (_IceVersions[iceConn->my_ice_version_index].minor_version);
154}
155
156
157int
158IceConnectionNumber (
159	IceConn iceConn
160)
161{
162    return (_IceTransGetConnectionNumber (iceConn->trans_conn));
163}
164
165
166char *
167IceConnectionString (
168	IceConn iceConn
169)
170{
171    if (iceConn->connection_string)
172    {
173	return strdup(iceConn->connection_string);
174    }
175    else
176	return (NULL);
177}
178
179
180unsigned long
181IceLastSentSequenceNumber (
182	IceConn iceConn
183)
184{
185    return (iceConn->send_sequence);
186}
187
188
189unsigned long
190IceLastReceivedSequenceNumber (
191	IceConn iceConn
192)
193{
194    return (iceConn->receive_sequence);
195}
196
197
198Bool
199IceSwapping (
200	IceConn iceConn
201)
202{
203    return (iceConn->swap);
204}
205
206
207
208/*
209 * Read "n" bytes from a connection.
210 *
211 * Return Status 0 if we detected an EXPECTED closed connection.
212 *
213 */
214
215Status
216_IceRead (
217	register IceConn iceConn,
218	unsigned long	 nbytes,
219	register char	 *ptr
220)
221{
222    register unsigned long nleft;
223
224    nleft = nbytes;
225    while (nleft > 0)
226    {
227	int nread;
228
229	if (iceConn->io_ok)
230	    nread = _IceTransRead (iceConn->trans_conn, ptr, (int) nleft);
231	else
232	    return (1);
233
234	if (nread <= 0)
235	{
236#ifdef WIN32
237	    errno = WSAGetLastError();
238#endif
239	    if (iceConn->want_to_close)
240	    {
241		/*
242		 * We sent a WantToClose message and now we detected that
243		 * the other side closed the connection.
244		 */
245
246		_IceConnectionClosed (iceConn);	    /* invoke watch procs */
247		_IceFreeConnection (iceConn);
248
249		return (0);
250	    }
251	    else
252	    {
253		/*
254		 * Fatal IO error.  First notify each protocol's IceIOErrorProc
255		 * callback, then invoke the application IO error handler.
256		 */
257
258		iceConn->io_ok = False;
259
260		if (iceConn->connection_status == IceConnectPending)
261		{
262		    /*
263		     * Don't invoke IO error handler if we are in the
264		     * middle of a connection setup.
265		     */
266
267		    return (1);
268		}
269
270		if (iceConn->process_msg_info)
271		{
272		    int i;
273
274		    for (i = iceConn->his_min_opcode;
275			i <= iceConn->his_max_opcode; i++)
276		    {
277			_IceProcessMsgInfo *process;
278
279			process = &iceConn->process_msg_info[
280			    i - iceConn->his_min_opcode];
281
282			if ((process != NULL) && process->in_use)
283			{
284			    IceIOErrorProc IOErrProc = process->accept_flag ?
285			      process->protocol->accept_client->io_error_proc :
286			      process->protocol->orig_client->io_error_proc;
287
288			    if (IOErrProc)
289				(*IOErrProc) (iceConn);
290			}
291		    }
292		}
293
294		(*_IceIOErrorHandler) (iceConn);
295		return (1);
296	    }
297	}
298
299	nleft -= nread;
300	ptr   += nread;
301    }
302
303    return (1);
304}
305
306
307
308/*
309 * If we read a message header with a bad major or minor opcode,
310 * we need to advance to the end of the message.  This way, the next
311 * message can be processed correctly.
312 */
313
314void
315_IceReadSkip (
316	register IceConn	iceConn,
317	register unsigned long	nbytes
318)
319{
320    char temp[512];
321
322    while (nbytes > 0)
323    {
324	unsigned long rbytes = nbytes > 512 ? 512 : nbytes;
325
326	_IceRead (iceConn, rbytes, temp);
327	nbytes -= rbytes;
328    }
329}
330
331
332
333/*
334 * Write "n" bytes to a connection.
335 */
336
337void
338_IceWrite (
339	register IceConn iceConn,
340	unsigned long	 nbytes,
341	register char	 *ptr
342)
343{
344    register unsigned long nleft;
345
346    nleft = nbytes;
347    while (nleft > 0)
348    {
349	int nwritten;
350
351	if (iceConn->io_ok)
352	    nwritten = _IceTransWrite (iceConn->trans_conn, ptr, (int) nleft);
353	else
354	    return;
355
356	if (nwritten <= 0)
357	{
358#ifdef WIN32
359	    errno = WSAGetLastError();
360#endif
361	    /*
362	     * Fatal IO error.  First notify each protocol's IceIOErrorProc
363	     * callback, then invoke the application IO error handler.
364	     */
365
366	    iceConn->io_ok = False;
367
368	    if (iceConn->connection_status == IceConnectPending)
369	    {
370		/*
371		 * Don't invoke IO error handler if we are in the
372		 * middle of a connection setup.
373		 */
374
375		return;
376	    }
377
378	    if (iceConn->process_msg_info)
379	    {
380		int i;
381
382		for (i = iceConn->his_min_opcode;
383		     i <= iceConn->his_max_opcode; i++)
384		{
385		    _IceProcessMsgInfo *process;
386
387		    process = &iceConn->process_msg_info[
388			i - iceConn->his_min_opcode];
389
390		    if (process->in_use)
391		    {
392			IceIOErrorProc IOErrProc = process->accept_flag ?
393			    process->protocol->accept_client->io_error_proc :
394			    process->protocol->orig_client->io_error_proc;
395
396			if (IOErrProc)
397			    (*IOErrProc) (iceConn);
398		    }
399		}
400	    }
401
402	    (*_IceIOErrorHandler) (iceConn);
403	    return;
404	}
405
406	nleft -= nwritten;
407	ptr   += nwritten;
408    }
409}
410
411#ifdef WORD64
412
413IceWriteData16 (
414	IceConn 	iceConn,
415	unsigned long 	nbytes,
416	short  		*data
417)
418{
419    int numShorts = nbytes / 2;
420    int index = 0;
421
422    while (index < numShorts)
423    {
424	int spaceLeft, count, i;
425	int shortsLeft = numShorts - index;
426
427	spaceLeft = iceConn->outbufmax - iceConn->outbufptr - 1;
428
429	if (spaceLeft < 2)
430	{
431	    IceFlush (iceConn);
432	    spaceLeft = iceConn->outbufmax - iceConn->outbufptr - 1;
433	}
434
435	count = (shortsLeft < spaceLeft / 2) ? shortsLeft : spaceLeft / 2;
436
437	for (i = 0; i < count; i++)
438	    STORE_CARD16 (iceConn->outbufptr, data[index++]);
439    }
440}
441
442
443IceWriteData32 (
444	IceConn 	iceConn,
445	unsigned long  	nbytes,
446	int	 	*data
447)
448{
449    int numLongs = nbytes / 4;
450    int index = 0;
451
452    while (index < numLongs)
453    {
454	int spaceLeft, count, i;
455	int longsLeft = numLongs - index;
456
457	spaceLeft = iceConn->outbufmax - iceConn->outbufptr - 1;
458
459	if (spaceLeft < 4)
460	{
461	    IceFlush (iceConn);
462	    spaceLeft = iceConn->outbufmax - iceConn->outbufptr - 1;
463	}
464
465	count = (longsLeft < spaceLeft / 4) ? longsLeft : spaceLeft / 4;
466
467	for (i = 0; i < count; i++)
468	    STORE_CARD32 (iceConn->outbufptr, data[index++]);
469    }
470}
471
472
473IceReadData16 (
474	IceConn 	iceConn,
475	Bool		swap,
476	unsigned long 	nbytes,
477	short  		*data
478)
479{
480    /* NOT IMPLEMENTED YET */
481}
482
483
484IceReadData32 (
485	IceConn 	iceConn,
486	Bool		swap,
487	unsigned long  	nbytes,
488	int	 	*data
489)
490{
491    /* NOT IMPLEMENTED YET */
492}
493
494#endif  /* WORD64 */
495
496
497
498void
499_IceAddOpcodeMapping (
500	IceConn	iceConn,
501	int 	hisOpcode,
502	int 	myOpcode
503)
504{
505    if (hisOpcode <= 0 || hisOpcode > 255)
506    {
507	return;
508    }
509    else if (iceConn->process_msg_info == NULL)
510    {
511	iceConn->process_msg_info = (_IceProcessMsgInfo *) malloc (
512	    sizeof (_IceProcessMsgInfo));
513	iceConn->his_min_opcode = iceConn->his_max_opcode = hisOpcode;
514    }
515    else if (hisOpcode < iceConn->his_min_opcode)
516    {
517	_IceProcessMsgInfo *oldVec = iceConn->process_msg_info;
518	int oldsize = iceConn->his_max_opcode - iceConn->his_min_opcode + 1;
519	int newsize = iceConn->his_max_opcode - hisOpcode + 1;
520	int i;
521
522	iceConn->process_msg_info = (_IceProcessMsgInfo *) malloc (
523	    newsize * sizeof (_IceProcessMsgInfo));
524
525	memcpy (&iceConn->process_msg_info[
526	    iceConn->his_min_opcode - hisOpcode], oldVec,
527	    oldsize * sizeof (_IceProcessMsgInfo));
528
529	free ((char *) oldVec);
530
531	for (i = hisOpcode + 1; i < iceConn->his_min_opcode; i++)
532	{
533	    iceConn->process_msg_info[i -
534		iceConn->his_min_opcode].in_use = False;
535
536	    iceConn->process_msg_info[i -
537		iceConn->his_min_opcode].protocol = NULL;
538	}
539
540	iceConn->his_min_opcode = hisOpcode;
541    }
542    else if (hisOpcode > iceConn->his_max_opcode)
543    {
544	_IceProcessMsgInfo *oldVec = iceConn->process_msg_info;
545	int oldsize = iceConn->his_max_opcode - iceConn->his_min_opcode + 1;
546	int newsize = hisOpcode - iceConn->his_min_opcode + 1;
547	int i;
548
549	iceConn->process_msg_info = (_IceProcessMsgInfo *) malloc (
550	    newsize * sizeof (_IceProcessMsgInfo));
551
552	memcpy (iceConn->process_msg_info, oldVec,
553	    oldsize * sizeof (_IceProcessMsgInfo));
554
555	free ((char *) oldVec);
556
557	for (i = iceConn->his_max_opcode + 1; i < hisOpcode; i++)
558	{
559	    iceConn->process_msg_info[i -
560		iceConn->his_min_opcode].in_use = False;
561
562	    iceConn->process_msg_info[i -
563		iceConn->his_min_opcode].protocol = NULL;
564	}
565
566	iceConn->his_max_opcode = hisOpcode;
567    }
568
569    iceConn->process_msg_info[hisOpcode -
570	iceConn->his_min_opcode].in_use = True;
571
572    iceConn->process_msg_info[hisOpcode -
573	iceConn->his_min_opcode].my_opcode = myOpcode;
574
575    iceConn->process_msg_info[hisOpcode -
576	iceConn->his_min_opcode].protocol = &_IceProtocols[myOpcode - 1];
577}
578
579
580
581char *
582IceGetPeerName (IceConn iceConn)
583{
584    return (_IceTransGetPeerNetworkId (iceConn->trans_conn));
585}
586
587
588char *
589_IceGetPeerName (IceConn iceConn)
590{
591    return (IceGetPeerName(iceConn));
592}
593