1 /*
2 
3 Copyright 1993, 1998  The Open Group
4 
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
9 documentation.
10 
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13 
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
24 
25 */
26 
27 /*
28  * Author: Ralph Mor, X Consortium
29  */
30 
31 #ifdef HAVE_CONFIG_H
32 #include <config.h>
33 #endif
34 #include <X11/SM/SMlib.h>
35 #include "SMlibint.h"
36 #include <stdio.h>
37 
38 
39 
40 /*
41  * Default Smc error handler.
42  */
43 
44 void
_SmcDefaultErrorHandler(SmcConn smcConn,Bool swap,int offendingMinorOpcode,unsigned long offendingSequence,int errorClass,int severity,SmPointer values)45 _SmcDefaultErrorHandler(SmcConn smcConn, Bool swap, int offendingMinorOpcode,
46 			unsigned long offendingSequence, int errorClass,
47 			int severity, SmPointer values)
48 {
49     char *pData = (char *) values;
50     const char *str;
51 
52     switch (offendingMinorOpcode)
53     {
54         case SM_RegisterClient:
55             str = "RegisterClient";
56 	    break;
57         case SM_InteractRequest:
58             str = "InteractRequest";
59 	    break;
60         case SM_InteractDone:
61             str = "InteractDone";
62 	    break;
63         case SM_SaveYourselfDone:
64             str = "SaveYourselfDone";
65 	    break;
66         case SM_CloseConnection:
67             str = "CloseConnection";
68 	    break;
69         case SM_SetProperties:
70             str = "SetProperties";
71 	    break;
72         case SM_GetProperties:
73             str = "GetProperties";
74 	    break;
75 	default:
76 	    str = "";
77 	}
78 
79     fprintf (stderr, "\n");
80 
81     fprintf (stderr, "XSMP error:  Offending minor opcode    = %d (%s)\n",
82 	offendingMinorOpcode, str);
83 
84     fprintf (stderr, "             Offending sequence number = %ld\n",
85 	offendingSequence);
86 
87     switch (errorClass)
88     {
89         case IceBadMinor:
90             str = "BadMinor";
91             break;
92         case IceBadState:
93             str = "BadState";
94             break;
95         case IceBadLength:
96             str = "BadLength";
97             break;
98         case IceBadValue:
99             str = "BadValue";
100             break;
101 	default:
102 	    str = "???";
103     }
104 
105     fprintf (stderr, "             Error class               = %s\n", str);
106 
107     if (severity == IceCanContinue)
108 	str = "CanContinue";
109     else if (severity == IceFatalToProtocol)
110 	str = "FatalToProtocol";
111     else if (severity == IceFatalToConnection)
112 	str = "FatalToConnection";
113     else
114 	str = "???";
115 
116     fprintf (stderr, "             Severity                  = %s\n", str);
117 
118     switch (errorClass)
119     {
120         case IceBadValue:
121         {
122 	    unsigned int offset, length, val;
123 
124 	    EXTRACT_CARD32 (pData, swap, offset);
125 	    EXTRACT_CARD32 (pData, swap, length);
126 
127 	    fprintf (stderr,
128 		"             BadValue Offset           = %d\n", offset);
129 	    fprintf (stderr,
130 		"             BadValue Length           = %d\n", length);
131 
132 	    if (length <= 4)
133 	    {
134 		if (length == 1)
135 		    val = (unsigned int) *pData;
136 		else if (length == 2)
137 		{
138 		    EXTRACT_CARD16 (pData, swap, val);
139 		}
140 		else
141 		{
142 		    EXTRACT_CARD32 (pData, swap, val);
143 		}
144 
145 		fprintf (stderr,
146 	            "             BadValue                  = %d\n", val);
147 	    }
148             break;
149 	}
150 
151 	default:
152 	    break;
153     }
154 
155     fprintf (stderr, "\n");
156 
157     if (severity != IceCanContinue)
158 	exit (1);
159 }
160 
161 
162 
163 /*
164  * Default Sms error handler.
165  */
166 
167 void
_SmsDefaultErrorHandler(SmsConn smsConn,Bool swap,int offendingMinorOpcode,unsigned long offendingSequence,int errorClass,int severity,SmPointer values)168 _SmsDefaultErrorHandler(SmsConn smsConn, Bool swap, int offendingMinorOpcode,
169 			unsigned long offendingSequence, int errorClass,
170 			int severity, SmPointer values)
171 {
172     char *pData = (char *) values;
173     const char *str;
174 
175     switch (offendingMinorOpcode)
176     {
177         case SM_SaveYourself:
178             str = "SaveYourself";
179 	    break;
180         case SM_Interact:
181             str = "Interact";
182 	    break;
183         case SM_Die:
184             str = "Die";
185 	    break;
186         case SM_ShutdownCancelled:
187             str = "ShutdownCancelled";
188 	    break;
189 	default:
190 	    str = "";
191 	}
192 
193     fprintf (stderr, "\n");
194 
195     fprintf (stderr, "XSMP error:  Offending minor opcode    = %d (%s)\n",
196 	offendingMinorOpcode, str);
197 
198     fprintf (stderr, "             Offending sequence number = %ld\n",
199 	offendingSequence);
200 
201     switch (errorClass)
202     {
203         case IceBadMinor:
204             str = "BadMinor";
205             break;
206         case IceBadState:
207             str = "BadState";
208             break;
209         case IceBadLength:
210             str = "BadLength";
211             break;
212         case IceBadValue:
213             str = "BadValue";
214             break;
215 	default:
216 	    str = "???";
217     }
218 
219     fprintf (stderr, "             Error class               = %s\n", str);
220 
221     if (severity == IceCanContinue)
222 	str = "CanContinue";
223     else if (severity == IceFatalToProtocol)
224 	str = "FatalToProtocol";
225     else if (severity == IceFatalToConnection)
226 	str = "FatalToConnection";
227     else
228 	str = "???";
229 
230     fprintf (stderr, "             Severity                  = %s\n", str);
231 
232     switch (errorClass)
233     {
234         case IceBadValue:
235         {
236 	    unsigned int offset, length, val;
237 
238 	    EXTRACT_CARD32 (pData, swap, offset);
239 	    EXTRACT_CARD32 (pData, swap, length);
240 
241 	    fprintf (stderr,
242 		"             BadValue Offset           = %d\n", offset);
243 	    fprintf (stderr,
244 		"             BadValue Length           = %d\n", length);
245 
246 	    if (length <= 4)
247 	    {
248 		if (length == 1)
249 		    val = (unsigned int) *pData;
250 		else if (length == 2)
251 		{
252 		    EXTRACT_CARD16 (pData, swap, val);
253 		}
254 		else
255 		{
256 		    EXTRACT_CARD32 (pData, swap, val);
257 		}
258 
259 		fprintf (stderr,
260 	            "             BadValue                  = %d\n", val);
261 	    }
262             break;
263 	}
264 
265 	default:
266 	    break;
267     }
268 
269     fprintf (stderr, "\n\n");
270 
271     /* don't exit() - that would kill the SM - pretty devastating */
272 }
273 
274 
275 
276 /*
277  * This procedure sets the Smc error handler to be the specified
278  * routine.  If NULL is passed in the default error handler is restored.
279  * The function's return value is the previous error handler.
280  */
281 
282 SmcErrorHandler
SmcSetErrorHandler(SmcErrorHandler handler)283 SmcSetErrorHandler(SmcErrorHandler handler)
284 {
285     SmcErrorHandler oldHandler = _SmcErrorHandler;
286 
287     if (handler != NULL)
288 	_SmcErrorHandler = handler;
289     else
290 	_SmcErrorHandler = _SmcDefaultErrorHandler;
291 
292     return (oldHandler);
293 }
294 
295 
296 
297 /*
298  * This procedure sets the Sms error handler to be the specified
299  * routine.  If NULL is passed in the default error handler is restored.
300  * The function's return value is the previous error handler.
301  */
302 
303 SmsErrorHandler
SmsSetErrorHandler(SmsErrorHandler handler)304 SmsSetErrorHandler(SmsErrorHandler handler)
305 {
306     SmsErrorHandler oldHandler = _SmsErrorHandler;
307 
308     if (handler != NULL)
309 	_SmsErrorHandler = handler;
310     else
311 	_SmsErrorHandler = _SmsDefaultErrorHandler;
312 
313     return (oldHandler);
314 }
315