1/******************************************************************************
2
3
4Copyright 1993, 1998  The Open Group
5
6Permission to use, copy, modify, distribute, and sell this software and its
7documentation for any purpose is hereby granted without fee, provided that
8the above copyright notice appear in all copies and that both that
9copyright notice and this permission notice appear in supporting
10documentation.
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall not be
23used in advertising or otherwise to promote the sale, use or other dealings
24in this Software without prior written authorization from The Open Group.
25
26Author: 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 <stdio.h>
35#include <unistd.h>
36#include <errno.h>
37
38void
39_IceErrorBadMinor (
40	IceConn	iceConn,
41	int	majorOpcode,
42	int	offendingMinor,
43	int	severity
44)
45{
46    IceErrorHeader (iceConn,
47	majorOpcode, offendingMinor,
48	iceConn->receive_sequence,
49	severity,
50	IceBadMinor,
51	0);
52
53    IceFlush (iceConn);
54}
55
56
57void
58_IceErrorBadState (
59	IceConn	iceConn,
60	int	majorOpcode,
61	int	offendingMinor,
62	int	severity
63)
64{
65    IceErrorHeader (iceConn,
66	majorOpcode, offendingMinor,
67	iceConn->receive_sequence,
68	severity,
69	IceBadState,
70	0);
71
72    IceFlush (iceConn);
73}
74
75
76void
77_IceErrorBadLength (
78	IceConn	iceConn,
79	int	majorOpcode,
80	int	offendingMinor,
81	int	severity
82)
83{
84    IceErrorHeader (iceConn,
85	majorOpcode, offendingMinor,
86	iceConn->receive_sequence,
87	severity,
88	IceBadLength,
89	0);
90
91    IceFlush (iceConn);
92}
93
94
95void
96_IceErrorBadValue (
97	IceConn		iceConn,
98	int		majorOpcode,
99	int		offendingMinor,
100	int		offset,
101	int		length,		/* in bytes */
102	IcePointer	value
103)
104{
105    IceErrorHeader (iceConn,
106	majorOpcode, offendingMinor,
107	iceConn->receive_sequence,
108	IceCanContinue,
109	IceBadValue,
110	WORD64COUNT (8 + length));
111
112    IceWriteData32 (iceConn, 4, &offset);
113    IceWriteData32 (iceConn, 4, &length);
114    IceWriteData (iceConn, length, (char *) value);
115
116    if (PAD64 (length))
117	IceWritePad (iceConn, PAD64 (length));
118
119    IceFlush (iceConn);
120}
121
122
123void
124_IceErrorNoAuthentication (
125	IceConn	iceConn,
126	int	offendingMinor
127)
128{
129    int severity = (offendingMinor == ICE_ConnectionSetup) ?
130	IceFatalToConnection : IceFatalToProtocol;
131
132    IceErrorHeader (iceConn,
133	0, offendingMinor,
134	iceConn->receive_sequence,
135	severity,
136	IceNoAuth,
137	0);
138
139    IceFlush (iceConn);
140}
141
142
143void
144_IceErrorNoVersion (
145	IceConn	iceConn,
146	int	offendingMinor
147)
148{
149    int severity = (offendingMinor == ICE_ConnectionSetup) ?
150	IceFatalToConnection : IceFatalToProtocol;
151
152    IceErrorHeader (iceConn,
153	0, offendingMinor,
154	iceConn->receive_sequence,
155	severity,
156	IceNoVersion,
157	0);
158
159    IceFlush (iceConn);
160}
161
162
163void
164_IceErrorSetupFailed (
165	IceConn	iceConn,
166	int	offendingMinor,
167	const char	*reason
168)
169{
170    char *pBuf, *pStart;
171    int bytes;
172    int severity = (offendingMinor == ICE_ConnectionSetup) ?
173	IceFatalToConnection : IceFatalToProtocol;
174
175    if (!reason)
176	reason = "";
177    bytes = STRING_BYTES (reason);
178
179    IceErrorHeader (iceConn,
180	0, offendingMinor,
181	iceConn->receive_sequence,
182	severity,
183	IceSetupFailed,
184	WORD64COUNT (bytes));
185
186    pBuf = pStart = IceAllocScratch (iceConn, PADDED_BYTES64 (bytes));
187    if (pStart != NULL)
188    {
189        STORE_STRING (pBuf, reason);
190        IceWriteData (iceConn, PADDED_BYTES64 (bytes), pStart);
191    }
192    IceFlush (iceConn);
193}
194
195
196void
197_IceErrorAuthenticationRejected (
198	IceConn	iceConn,
199	int	offendingMinor,
200	const char	*reason
201)
202{
203    char *pBuf, *pStart;
204    int bytes;
205
206    if (!reason)
207	reason = "";
208    bytes = STRING_BYTES (reason);
209
210    IceErrorHeader (iceConn,
211	0, offendingMinor,
212	iceConn->receive_sequence,
213	IceFatalToProtocol,
214	IceAuthRejected,
215	WORD64COUNT (bytes));
216
217    pBuf = pStart = IceAllocScratch (iceConn, PADDED_BYTES64 (bytes));
218    if (pStart != NULL)
219    {
220        STORE_STRING (pBuf, reason);
221        IceWriteData (iceConn, PADDED_BYTES64 (bytes), pStart);
222    }
223    IceFlush (iceConn);
224}
225
226
227void
228_IceErrorAuthenticationFailed (
229	IceConn	iceConn,
230	int	offendingMinor,
231	const char	*reason
232)
233{
234    char *pBuf, *pStart;
235    int bytes;
236
237    if (!reason)
238	reason = "";
239    bytes = STRING_BYTES (reason);
240
241    IceErrorHeader (iceConn,
242	0, offendingMinor,
243	iceConn->receive_sequence,
244	IceFatalToProtocol,
245	IceAuthFailed,
246	WORD64COUNT (bytes));
247
248    pBuf = pStart = IceAllocScratch (iceConn, PADDED_BYTES64 (bytes));
249    if (pStart != NULL)
250    {
251        STORE_STRING (pBuf, reason);
252        IceWriteData (iceConn, PADDED_BYTES64 (bytes), pStart);
253    }
254    IceFlush (iceConn);
255}
256
257
258void
259_IceErrorProtocolDuplicate (
260	IceConn	iceConn,
261	const char	*protocolName
262)
263{
264    char *pBuf, *pStart;
265    int bytes;
266
267    if (!protocolName)
268	protocolName = "";
269    bytes = STRING_BYTES (protocolName);
270
271    IceErrorHeader (iceConn,
272	0, ICE_ProtocolSetup,
273	iceConn->receive_sequence,
274	IceFatalToProtocol,
275	IceProtocolDuplicate,
276	WORD64COUNT (bytes));
277
278    pBuf = pStart = IceAllocScratch (iceConn, PADDED_BYTES64 (bytes));
279    if (pStart != NULL)
280    {
281        STORE_STRING (pBuf, protocolName);
282        IceWriteData (iceConn, PADDED_BYTES64 (bytes), pStart);
283    }
284    IceFlush (iceConn);
285}
286
287
288void
289_IceErrorMajorOpcodeDuplicate (
290	IceConn	iceConn,
291	int	majorOpcode
292)
293{
294    char mOp[8] = { (char) majorOpcode };
295
296    IceErrorHeader (iceConn,
297	0, ICE_ProtocolSetup,
298	iceConn->receive_sequence,
299	IceFatalToProtocol,
300	IceMajorOpcodeDuplicate,
301	1 /* length */);
302
303    IceWriteData (iceConn, 8, mOp);
304    IceFlush (iceConn);
305}
306
307
308void
309_IceErrorUnknownProtocol (
310	IceConn	iceConn,
311	const char	*protocolName
312)
313{
314    char *pBuf, *pStart;
315    int bytes;
316
317    if (!protocolName)
318	protocolName = "";
319    bytes = STRING_BYTES (protocolName);
320
321    IceErrorHeader (iceConn,
322	0, ICE_ProtocolSetup,
323	iceConn->receive_sequence,
324	IceFatalToProtocol,
325	IceUnknownProtocol,
326	WORD64COUNT (bytes));
327
328    pBuf = pStart = IceAllocScratch (iceConn, PADDED_BYTES64 (bytes));
329    if (pStart != NULL)
330    {
331        STORE_STRING (pBuf, protocolName);
332        IceWriteData (iceConn, PADDED_BYTES64 (bytes), pStart);
333    }
334    IceFlush (iceConn);
335}
336
337
338void
339_IceErrorBadMajor (
340	IceConn	iceConn,
341	int     offendingMajor,
342	int     offendingMinor,
343	int	severity
344)
345{
346    char maj[8] = { (char) offendingMajor };
347
348    IceErrorHeader (iceConn,
349	0, offendingMinor,
350	iceConn->receive_sequence,
351	severity,
352	IceBadMajor,
353	1 /* length */);
354
355    IceWriteData (iceConn, 8, maj);
356    IceFlush (iceConn);
357}
358
359
360
361/*
362 * Default error handler.
363 */
364
365static void
366_IceDefaultErrorHandler (
367	IceConn		iceConn,
368	Bool		swap,
369	int		offendingMinorOpcode,
370	unsigned long	offendingSequence,
371	int 		errorClass,
372	int		severity,
373	IcePointer	values
374)
375{
376    const char *str;
377    char *estr;
378    char *pData = (char *) values;
379
380    switch (offendingMinorOpcode)
381    {
382        case ICE_ConnectionSetup:
383            str = "ConnectionSetup";
384	    break;
385        case ICE_AuthRequired:
386            str = "AuthRequired";
387	    break;
388        case ICE_AuthReply:
389            str = "AuthReply";
390	    break;
391        case ICE_AuthNextPhase:
392            str = "AuthNextPhase";
393	    break;
394        case ICE_ConnectionReply:
395            str = "ConnectionReply";
396	    break;
397        case ICE_ProtocolSetup:
398            str = "ProtocolSetup";
399	    break;
400        case ICE_ProtocolReply:
401            str = "ProtocolReply";
402	    break;
403        case ICE_Ping:
404            str = "Ping";
405	    break;
406        case ICE_PingReply:
407            str = "PingReply";
408	    break;
409        case ICE_WantToClose:
410            str = "WantToClose";
411	    break;
412        case ICE_NoClose:
413            str = "NoClose";
414	    break;
415	default:
416	    str = "";
417	}
418
419    fprintf (stderr, "\n");
420
421    fprintf (stderr, "ICE error:  Offending minor opcode    = %d (%s)\n",
422	offendingMinorOpcode, str);
423
424    fprintf (stderr, "            Offending sequence number = %lu\n",
425	offendingSequence);
426
427    switch (errorClass)
428    {
429        case IceBadMinor:
430            str = "BadMinor";
431            break;
432        case IceBadState:
433            str = "BadState";
434            break;
435        case IceBadLength:
436            str = "BadLength";
437            break;
438        case IceBadValue:
439            str = "BadValue";
440            break;
441        case IceBadMajor:
442            str = "BadMajor";
443            break;
444        case IceNoAuth:
445            str = "NoAuthentication";
446            break;
447        case IceNoVersion:
448            str = "NoVersion";
449            break;
450        case IceSetupFailed:
451            str = "SetupFailed";
452            break;
453        case IceAuthRejected:
454            str = "AuthenticationRejected";
455            break;
456        case IceAuthFailed:
457            str = "AuthenticationFailed";
458            break;
459        case IceProtocolDuplicate:
460            str = "ProtocolDuplicate";
461            break;
462        case IceMajorOpcodeDuplicate:
463            str = "MajorOpcodeDuplicate";
464            break;
465        case IceUnknownProtocol:
466            str = "UnknownProtocol";
467            break;
468	default:
469	    str = "???";
470    }
471
472    fprintf (stderr, "            Error class               = %s\n", str);
473
474    if (severity == IceCanContinue)
475	str = "CanContinue";
476    else if (severity == IceFatalToProtocol)
477	str = "FatalToProtocol";
478    else if (severity == IceFatalToConnection)
479	str = "FatalToConnection";
480    else
481	str = "???";
482
483    fprintf (stderr, "            Severity                  = %s\n", str);
484
485    switch (errorClass)
486    {
487        case IceBadValue:
488        {
489	    int offset, length, val;
490
491	    EXTRACT_CARD32 (pData, swap, offset);
492	    EXTRACT_CARD32 (pData, swap, length);
493
494	    fprintf (stderr,
495		"            BadValue Offset           = %d\n", offset);
496	    fprintf (stderr,
497		"            BadValue Length           = %d\n", length);
498
499	    if (length <= 4)
500	    {
501		if (length == 1)
502		    val = (int) *pData;
503		else if (length == 2)
504		{
505		    EXTRACT_CARD16 (pData, swap, val);
506		}
507		else
508		{
509		    EXTRACT_CARD32 (pData, swap, val);
510		}
511
512		fprintf (stderr,
513	            "            BadValue                  = %d\n", val);
514	    }
515            break;
516	}
517
518        case IceBadMajor:
519
520	    fprintf (stderr, "Major opcode : %d\n", (int) *pData);
521            break;
522
523        case IceSetupFailed:
524
525            EXTRACT_STRING (pData, swap, estr);
526            fprintf (stderr, "Reason : %s\n", estr);
527            free(estr);
528            break;
529
530        case IceAuthRejected:
531
532            EXTRACT_STRING (pData, swap, estr);
533            fprintf (stderr, "Reason : %s\n", estr);
534            free(estr);
535            break;
536
537        case IceAuthFailed:
538
539            EXTRACT_STRING (pData, swap, estr);
540            fprintf (stderr, "Reason : %s\n", estr);
541            free(estr);
542            break;
543
544        case IceProtocolDuplicate:
545
546            EXTRACT_STRING (pData, swap, estr);
547            fprintf (stderr, "Protocol name : %s\n", estr);
548            free(estr);
549            break;
550
551        case IceMajorOpcodeDuplicate:
552
553            fprintf (stderr, "Major opcode : %d\n", (int) *pData);
554            break;
555
556        case IceUnknownProtocol:
557
558            EXTRACT_STRING (pData, swap, estr);
559            fprintf (stderr, "Protocol name : %s\n", estr);
560            free(estr);
561            break;
562
563	default:
564	    break;
565    }
566
567    fprintf (stderr, "\n");
568
569    if (severity != IceCanContinue)
570	exit (1);
571}
572
573IceErrorHandler   _IceErrorHandler   = _IceDefaultErrorHandler;
574
575
576/*
577 * This procedure sets the ICE error handler to be the specified
578 * routine.  If NULL is passed in the default error handler is restored.
579 * The function's return value is the previous error handler.
580 */
581
582IceErrorHandler
583IceSetErrorHandler (
584	IceErrorHandler handler
585)
586{
587    IceErrorHandler oldHandler = _IceErrorHandler;
588
589    if (handler != NULL)
590	_IceErrorHandler = handler;
591    else
592	_IceErrorHandler = _IceDefaultErrorHandler;
593
594    return (oldHandler);
595}
596
597
598
599/*
600 * Default IO error handler.
601 */
602
603static void
604_IceDefaultIOErrorHandler (
605	IceConn		iceConn
606)
607{
608    fprintf (stderr,
609	"ICE default IO error handler doing an exit(), pid = %ld, errno = %d\n",
610	(long)getpid(), errno);
611
612    exit (1);
613}
614
615IceIOErrorHandler _IceIOErrorHandler = _IceDefaultIOErrorHandler;
616
617
618/*
619 * This procedure sets the ICE fatal I/O error handler to be the
620 * specified routine.  If NULL is passed in the default error
621 * handler is restored.   The function's return value is the
622 * previous error handler.
623 */
624
625IceIOErrorHandler
626IceSetIOErrorHandler (
627	IceIOErrorHandler handler
628)
629{
630    IceIOErrorHandler oldHandler = _IceIOErrorHandler;
631
632    if (handler != NULL)
633	_IceIOErrorHandler = handler;
634    else
635	_IceIOErrorHandler = _IceDefaultIOErrorHandler;
636
637    return (oldHandler);
638}
639