error.c revision a3129944
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    STORE_STRING (pBuf, reason);
188
189    IceWriteData (iceConn, PADDED_BYTES64 (bytes), pStart);
190    IceFlush (iceConn);
191}
192
193
194void
195_IceErrorAuthenticationRejected (
196	IceConn	iceConn,
197	int	offendingMinor,
198	const char	*reason
199)
200{
201    char *pBuf, *pStart;
202    int bytes;
203
204    if (!reason)
205	reason = "";
206    bytes = STRING_BYTES (reason);
207
208    IceErrorHeader (iceConn,
209	0, offendingMinor,
210	iceConn->receive_sequence,
211	IceFatalToProtocol,
212	IceAuthRejected,
213	WORD64COUNT (bytes));
214
215    pBuf = pStart = IceAllocScratch (iceConn, PADDED_BYTES64 (bytes));
216    STORE_STRING (pBuf, reason);
217
218    IceWriteData (iceConn, PADDED_BYTES64 (bytes), pStart);
219    IceFlush (iceConn);
220}
221
222
223void
224_IceErrorAuthenticationFailed (
225	IceConn	iceConn,
226	int	offendingMinor,
227	const char	*reason
228)
229{
230    char *pBuf, *pStart;
231    int bytes;
232
233    if (!reason)
234	reason = "";
235    bytes = STRING_BYTES (reason);
236
237    IceErrorHeader (iceConn,
238	0, offendingMinor,
239	iceConn->receive_sequence,
240	IceFatalToProtocol,
241	IceAuthFailed,
242	WORD64COUNT (bytes));
243
244    pBuf = pStart = IceAllocScratch (iceConn, PADDED_BYTES64 (bytes));
245    STORE_STRING (pBuf, reason);
246
247    IceWriteData (iceConn, PADDED_BYTES64 (bytes), pStart);
248    IceFlush (iceConn);
249}
250
251
252void
253_IceErrorProtocolDuplicate (
254	IceConn	iceConn,
255	const char	*protocolName
256)
257{
258    char *pBuf, *pStart;
259    int bytes;
260
261    if (!protocolName)
262	protocolName = "";
263    bytes = STRING_BYTES (protocolName);
264
265    IceErrorHeader (iceConn,
266	0, ICE_ProtocolSetup,
267	iceConn->receive_sequence,
268	IceFatalToProtocol,
269	IceProtocolDuplicate,
270	WORD64COUNT (bytes));
271
272    pBuf = pStart = IceAllocScratch (iceConn, PADDED_BYTES64 (bytes));
273    STORE_STRING (pBuf, protocolName);
274
275    IceWriteData (iceConn, PADDED_BYTES64 (bytes), pStart);
276    IceFlush (iceConn);
277}
278
279
280void
281_IceErrorMajorOpcodeDuplicate (
282	IceConn	iceConn,
283	int	majorOpcode
284)
285{
286    char mOp[8] = { (char) majorOpcode };
287
288    IceErrorHeader (iceConn,
289	0, ICE_ProtocolSetup,
290	iceConn->receive_sequence,
291	IceFatalToProtocol,
292	IceMajorOpcodeDuplicate,
293	1 /* length */);
294
295    IceWriteData (iceConn, 8, mOp);
296    IceFlush (iceConn);
297}
298
299
300void
301_IceErrorUnknownProtocol (
302	IceConn	iceConn,
303	const char	*protocolName
304)
305{
306    char *pBuf, *pStart;
307    int bytes;
308
309    if (!protocolName)
310	protocolName = "";
311    bytes = STRING_BYTES (protocolName);
312
313    IceErrorHeader (iceConn,
314	0, ICE_ProtocolSetup,
315	iceConn->receive_sequence,
316	IceFatalToProtocol,
317	IceUnknownProtocol,
318	WORD64COUNT (bytes));
319
320    pBuf = pStart = IceAllocScratch (iceConn, PADDED_BYTES64 (bytes));
321    STORE_STRING (pBuf, protocolName);
322
323    IceWriteData (iceConn, PADDED_BYTES64 (bytes), pStart);
324    IceFlush (iceConn);
325}
326
327
328void
329_IceErrorBadMajor (
330	IceConn	iceConn,
331	int     offendingMajor,
332	int     offendingMinor,
333	int	severity
334)
335{
336    char maj[8] = { (char) offendingMajor };
337
338    IceErrorHeader (iceConn,
339	0, offendingMinor,
340	iceConn->receive_sequence,
341	severity,
342	IceBadMajor,
343	1 /* length */);
344
345    IceWriteData (iceConn, 8, maj);
346    IceFlush (iceConn);
347}
348
349
350
351/*
352 * Default error handler.
353 */
354
355static void
356_IceDefaultErrorHandler (
357	IceConn		iceConn,
358	Bool		swap,
359	int		offendingMinorOpcode,
360	unsigned long	offendingSequence,
361	int 		errorClass,
362	int		severity,
363	IcePointer	values
364)
365{
366    const char *str;
367    char *estr;
368    char *pData = (char *) values;
369
370    switch (offendingMinorOpcode)
371    {
372        case ICE_ConnectionSetup:
373            str = "ConnectionSetup";
374	    break;
375        case ICE_AuthRequired:
376            str = "AuthRequired";
377	    break;
378        case ICE_AuthReply:
379            str = "AuthReply";
380	    break;
381        case ICE_AuthNextPhase:
382            str = "AuthNextPhase";
383	    break;
384        case ICE_ConnectionReply:
385            str = "ConnectionReply";
386	    break;
387        case ICE_ProtocolSetup:
388            str = "ProtocolSetup";
389	    break;
390        case ICE_ProtocolReply:
391            str = "ProtocolReply";
392	    break;
393        case ICE_Ping:
394            str = "Ping";
395	    break;
396        case ICE_PingReply:
397            str = "PingReply";
398	    break;
399        case ICE_WantToClose:
400            str = "WantToClose";
401	    break;
402        case ICE_NoClose:
403            str = "NoClose";
404	    break;
405	default:
406	    str = "";
407	}
408
409    fprintf (stderr, "\n");
410
411    fprintf (stderr, "ICE error:  Offending minor opcode    = %d (%s)\n",
412	offendingMinorOpcode, str);
413
414    fprintf (stderr, "            Offending sequence number = %lu\n",
415	offendingSequence);
416
417    switch (errorClass)
418    {
419        case IceBadMinor:
420            str = "BadMinor";
421            break;
422        case IceBadState:
423            str = "BadState";
424            break;
425        case IceBadLength:
426            str = "BadLength";
427            break;
428        case IceBadValue:
429            str = "BadValue";
430            break;
431        case IceBadMajor:
432            str = "BadMajor";
433            break;
434        case IceNoAuth:
435            str = "NoAuthentication";
436            break;
437        case IceNoVersion:
438            str = "NoVersion";
439            break;
440        case IceSetupFailed:
441            str = "SetupFailed";
442            break;
443        case IceAuthRejected:
444            str = "AuthenticationRejected";
445            break;
446        case IceAuthFailed:
447            str = "AuthenticationFailed";
448            break;
449        case IceProtocolDuplicate:
450            str = "ProtocolDuplicate";
451            break;
452        case IceMajorOpcodeDuplicate:
453            str = "MajorOpcodeDuplicate";
454            break;
455        case IceUnknownProtocol:
456            str = "UnknownProtocol";
457            break;
458	default:
459	    str = "???";
460    }
461
462    fprintf (stderr, "            Error class               = %s\n", str);
463
464    if (severity == IceCanContinue)
465	str = "CanContinue";
466    else if (severity == IceFatalToProtocol)
467	str = "FatalToProtocol";
468    else if (severity == IceFatalToConnection)
469	str = "FatalToConnection";
470    else
471	str = "???";
472
473    fprintf (stderr, "            Severity                  = %s\n", str);
474
475    switch (errorClass)
476    {
477        case IceBadValue:
478        {
479	    int offset, length, val;
480
481	    EXTRACT_CARD32 (pData, swap, offset);
482	    EXTRACT_CARD32 (pData, swap, length);
483
484	    fprintf (stderr,
485		"            BadValue Offset           = %d\n", offset);
486	    fprintf (stderr,
487		"            BadValue Length           = %d\n", length);
488
489	    if (length <= 4)
490	    {
491		if (length == 1)
492		    val = (int) *pData;
493		else if (length == 2)
494		{
495		    EXTRACT_CARD16 (pData, swap, val);
496		}
497		else
498		{
499		    EXTRACT_CARD32 (pData, swap, val);
500		}
501
502		fprintf (stderr,
503	            "            BadValue                  = %d\n", val);
504	    }
505            break;
506	}
507
508        case IceBadMajor:
509
510	    fprintf (stderr, "Major opcode : %d\n", (int) *pData);
511            break;
512
513        case IceSetupFailed:
514
515            EXTRACT_STRING (pData, swap, estr);
516            fprintf (stderr, "Reason : %s\n", estr);
517            free(estr);
518            break;
519
520        case IceAuthRejected:
521
522            EXTRACT_STRING (pData, swap, estr);
523            fprintf (stderr, "Reason : %s\n", estr);
524            free(estr);
525            break;
526
527        case IceAuthFailed:
528
529            EXTRACT_STRING (pData, swap, estr);
530            fprintf (stderr, "Reason : %s\n", estr);
531            free(estr);
532            break;
533
534        case IceProtocolDuplicate:
535
536            EXTRACT_STRING (pData, swap, estr);
537            fprintf (stderr, "Protocol name : %s\n", estr);
538            free(estr);
539            break;
540
541        case IceMajorOpcodeDuplicate:
542
543            fprintf (stderr, "Major opcode : %d\n", (int) *pData);
544            break;
545
546        case IceUnknownProtocol:
547
548            EXTRACT_STRING (pData, swap, estr);
549            fprintf (stderr, "Protocol name : %s\n", estr);
550            free(estr);
551            break;
552
553	default:
554	    break;
555    }
556
557    fprintf (stderr, "\n");
558
559    if (severity != IceCanContinue)
560	exit (1);
561}
562
563IceErrorHandler   _IceErrorHandler   = _IceDefaultErrorHandler;
564
565
566/*
567 * This procedure sets the ICE error handler to be the specified
568 * routine.  If NULL is passed in the default error handler is restored.
569 * The function's return value is the previous error handler.
570 */
571
572IceErrorHandler
573IceSetErrorHandler (
574	IceErrorHandler handler
575)
576{
577    IceErrorHandler oldHandler = _IceErrorHandler;
578
579    if (handler != NULL)
580	_IceErrorHandler = handler;
581    else
582	_IceErrorHandler = _IceDefaultErrorHandler;
583
584    return (oldHandler);
585}
586
587
588
589/*
590 * Default IO error handler.
591 */
592
593static void
594_IceDefaultIOErrorHandler (
595	IceConn		iceConn
596)
597{
598    fprintf (stderr,
599	"ICE default IO error handler doing an exit(), pid = %ld, errno = %d\n",
600	(long)getpid(), errno);
601
602    exit (1);
603}
604
605IceIOErrorHandler _IceIOErrorHandler = _IceDefaultIOErrorHandler;
606
607
608/*
609 * This procedure sets the ICE fatal I/O error handler to be the
610 * specified routine.  If NULL is passed in the default error
611 * handler is restored.   The function's return value is the
612 * previous error handler.
613 */
614
615IceIOErrorHandler
616IceSetIOErrorHandler (
617	IceIOErrorHandler handler
618)
619{
620    IceIOErrorHandler oldHandler = _IceIOErrorHandler;
621
622    if (handler != NULL)
623	_IceIOErrorHandler = handler;
624    else
625	_IceIOErrorHandler = _IceDefaultIOErrorHandler;
626
627    return (oldHandler);
628}
629