Bug Summary

File:sm_client.c
Location:line 304, column 5
Description:Dereference of null pointer

Annotated Source Code

1/*
2
3Copyright 1993, 1998 The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in 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_H1
32#include <config.h>
33#endif
34#include <X11/SM/SMlib.h>
35#include "SMlibint.h"
36
37int _SmcOpcode = 0;
38int _SmsOpcode = 0;
39
40#ifndef __UNIXOS2__
41SmsNewClientProc _SmsNewClientProc;
42SmPointer _SmsNewClientData;
43#else
44SmsNewClientProc _SmsNewClientProc = 0;
45SmPointer _SmsNewClientData = 0;
46#endif
47
48SmcErrorHandler _SmcErrorHandler = _SmcDefaultErrorHandler;
49SmsErrorHandler _SmsErrorHandler = _SmsDefaultErrorHandler;
50
51
52static void
53set_callbacks(SmcConn smcConn, unsigned long mask, SmcCallbacks *callbacks);
54
55
56SmcConn
57SmcOpenConnection(char *networkIdsList, SmPointer context,
58 int xsmpMajorRev, int xsmpMinorRev,
59 unsigned long mask, SmcCallbacks *callbacks,
60 char *previousId, char **clientIdRet,
61 int errorLength, char *errorStringRet)
62{
63 SmcConn smcConn;
64 IceConn iceConn;
65 char *ids;
66 IceProtocolSetupStatus setupstat;
67 int majorVersion;
68 int minorVersion;
69 char *vendor = NULL((void*)0);
70 char *release = NULL((void*)0);
71 smRegisterClientMsg *pMsg;
72 char *pData;
73 int extra, len;
74 IceReplyWaitInfo replyWait;
75 _SmcRegisterClientReply reply;
76 Boolint gotReply, ioErrorOccured;
77
78 const char *auth_names[] = {"MIT-MAGIC-COOKIE-1"};
79 IcePoAuthProc auth_procs[] = {_IcePoMagicCookie1Proc};
80 int auth_count = 1;
81
82 IcePoVersionRec versions[] = {
83 {SmProtoMajor1, SmProtoMinor0, _SmcProcessMessage}
84 };
85 int version_count = 1;
86
87
88 *clientIdRet = NULL((void*)0);
89
90 if (errorStringRet && errorLength > 0)
91 *errorStringRet = '\0';
92
93 if (!_SmcOpcode)
94 {
95 /*
96 * For now, there is only one version of XSMP, so we don't
97 * have to check {xsmpMajorRev, xsmpMinorRev}. In the future,
98 * we will check against versions and generate the list
99 * of versions the application actually supports.
100 */
101
102 if ((_SmcOpcode = IceRegisterForProtocolSetup ("XSMP",
103 SmVendorString"MIT", SmReleaseString"1.0", version_count, versions,
104 auth_count, auth_names, auth_procs, NULL((void*)0))) < 0)
105 {
106 if (errorStringRet && errorLength > 0) {
107 strncpy (errorStringRet,
108 "Could not register XSMP protocol with ICE",
109 errorLength);
110 errorStringRet[errorLength - 1] = '\0';
111 }
112
113 return (NULL((void*)0));
114 }
115 }
116
117 if (networkIdsList == NULL((void*)0) || *networkIdsList == '\0')
118 {
119 if ((ids = (char *) getenv ("SESSION_MANAGER")) == NULL((void*)0))
120 {
121 if (errorStringRet && errorLength > 0) {
122 strncpy (errorStringRet,
123 "SESSION_MANAGER environment variable not defined",
124 errorLength);
125 errorStringRet[errorLength - 1] = '\0';
126 }
127 return (NULL((void*)0));
128 }
129 }
130 else
131 {
132 ids = networkIdsList;
133 }
134
135 if ((iceConn = IceOpenConnection (
136 ids, context, 0, _SmcOpcode, errorLength, errorStringRet)) == NULL((void*)0))
137 {
138 return (NULL((void*)0));
139 }
140
141 if ((smcConn = malloc (sizeof (struct _SmcConn))) == NULL((void*)0))
142 {
143 if (errorStringRet && errorLength > 0) {
144 strncpy (errorStringRet, "Can't malloc", errorLength);
145 errorStringRet[errorLength - 1] = '\0';
146 }
147 IceCloseConnection (iceConn);
148 return (NULL((void*)0));
149 }
150
151 setupstat = IceProtocolSetup (iceConn, _SmcOpcode,
152 (IcePointer) smcConn,
153 False0 /* mustAuthenticate */,
154 &majorVersion, &minorVersion,
155 &vendor, &release, errorLength, errorStringRet);
156
157 if (setupstat == IceProtocolSetupFailure ||
158 setupstat == IceProtocolSetupIOError)
159 {
160 IceCloseConnection (iceConn);
161 free (smcConn);
162 return (NULL((void*)0));
163 }
164 else if (setupstat == IceProtocolAlreadyActive)
165 {
166 /*
167 * This case should never happen, because when we called
168 * IceOpenConnection, we required that the ICE connection
169 * may not already have XSMP active on it.
170 */
171
172 free (smcConn);
173 if (errorStringRet && errorLength > 0) {
174 strncpy (errorStringRet, "Internal error in IceOpenConnection",
175 errorLength);
176 errorStringRet[errorLength - 1] = '\0';
177 }
178 return (NULL((void*)0));
179 }
180
181 smcConn->iceConn = iceConn;
182 smcConn->proto_major_version = majorVersion;
183 smcConn->proto_minor_version = minorVersion;
184 smcConn->vendor = vendor;
185 smcConn->release = release;
186 smcConn->client_id = NULL((void*)0);
187
188 bzero ((char *) &smcConn->callbacks, sizeof (SmcCallbacks))memset((char *) &smcConn->callbacks,0,sizeof (SmcCallbacks
))
;
189 set_callbacks (smcConn, mask, callbacks);
190
191 smcConn->interact_waits = NULL((void*)0);
192 smcConn->phase2_wait = NULL((void*)0);
193 smcConn->prop_reply_waits = NULL((void*)0);
194
195 smcConn->save_yourself_in_progress = False0;
196 smcConn->shutdown_in_progress = False0;
197
198
199 /*
200 * Now register the client
201 */
202
203 if (!previousId)
204 previousId = "";
205 len = strlen (previousId);
206 extra = ARRAY8_BYTES (len)(4 + len + ((8 - ((unsigned int) (4 + len) % 8)) % 8));
207
208 IceGetHeaderExtra (iceConn, _SmcOpcode, SM_RegisterClient,if ((iceConn->outbufptr + 8 + (((((unsigned int) ((extra) +
7)) >> 3)) << 3)) > iceConn->outbufmax) IceFlush
(iceConn); pMsg = (smRegisterClientMsg *) iceConn->outbufptr
; if ((iceConn->outbufptr + 8 + (((((unsigned int) ((extra
) + 7)) >> 3)) << 3)) <= iceConn->outbufmax
) pData = (char *) pMsg + 8; else pData = ((void*)0); pMsg->
majorOpcode = _SmcOpcode; pMsg->minorOpcode = 1; pMsg->
length = ((8 - 8) >> 3) + ((((unsigned int) ((extra) + 7
)) >> 3)); iceConn->outbufptr += (8 + (((((unsigned int
) ((extra) + 7)) >> 3)) << 3)); iceConn->send_sequence
++
209 SIZEOF (smRegisterClientMsg), WORD64COUNT (extra),if ((iceConn->outbufptr + 8 + (((((unsigned int) ((extra) +
7)) >> 3)) << 3)) > iceConn->outbufmax) IceFlush
(iceConn); pMsg = (smRegisterClientMsg *) iceConn->outbufptr
; if ((iceConn->outbufptr + 8 + (((((unsigned int) ((extra
) + 7)) >> 3)) << 3)) <= iceConn->outbufmax
) pData = (char *) pMsg + 8; else pData = ((void*)0); pMsg->
majorOpcode = _SmcOpcode; pMsg->minorOpcode = 1; pMsg->
length = ((8 - 8) >> 3) + ((((unsigned int) ((extra) + 7
)) >> 3)); iceConn->outbufptr += (8 + (((((unsigned int
) ((extra) + 7)) >> 3)) << 3)); iceConn->send_sequence
++
210 smRegisterClientMsg, pMsg, pData)if ((iceConn->outbufptr + 8 + (((((unsigned int) ((extra) +
7)) >> 3)) << 3)) > iceConn->outbufmax) IceFlush
(iceConn); pMsg = (smRegisterClientMsg *) iceConn->outbufptr
; if ((iceConn->outbufptr + 8 + (((((unsigned int) ((extra
) + 7)) >> 3)) << 3)) <= iceConn->outbufmax
) pData = (char *) pMsg + 8; else pData = ((void*)0); pMsg->
majorOpcode = _SmcOpcode; pMsg->minorOpcode = 1; pMsg->
length = ((8 - 8) >> 3) + ((((unsigned int) ((extra) + 7
)) >> 3)); iceConn->outbufptr += (8 + (((((unsigned int
) ((extra) + 7)) >> 3)) << 3)); iceConn->send_sequence
++
;
211
212 STORE_ARRAY8 (pData, len, previousId){ { *((CARD32 *) pData) = len; pData += 4; }; if (len) memcpy
(pData, previousId, len); pData += len + ((8 - ((unsigned int
) (4 + len) % 8)) % 8); }
;
213
214 IceFlush (iceConn);
215
216 replyWait.sequence_of_request = IceLastSentSequenceNumber (iceConn);
217 replyWait.major_opcode_of_request = _SmcOpcode;
218 replyWait.minor_opcode_of_request = SM_RegisterClient1;
219 replyWait.reply = (IcePointer) &reply;
220
221 gotReply = False0;
222 ioErrorOccured = False0;
223
224 while (!gotReply && !ioErrorOccured)
225 {
226 ioErrorOccured = (IceProcessMessages (
227 iceConn, &replyWait, &gotReply) == IceProcessMessagesIOError);
228
229 if (ioErrorOccured)
230 {
231 if (errorStringRet && errorLength > 0) {
232 strncpy (errorStringRet, "IO error occured opening connection",
233 errorLength);
234 errorStringRet[errorLength - 1] = '\0';
235 }
236 free (smcConn->vendor);
237 free (smcConn->release);
238 free (smcConn);
239
240 return (NULL((void*)0));
241 }
242 else if (gotReply)
243 {
244 if (reply.status == 1)
245 {
246 /*
247 * The client successfully registered.
248 */
249
250 *clientIdRet = reply.client_id;
251
252 smcConn->client_id = strdup (*clientIdRet);
253 }
254 else
255 {
256 /*
257 * Could not register the client because the previous ID
258 * was bad. So now we register the client with the
259 * previous ID set to NULL.
260 */
261
262 extra = ARRAY8_BYTES (0)(4 + 0 + ((8 - ((unsigned int) (4 + 0) % 8)) % 8));
263
264 IceGetHeaderExtra (iceConn, _SmcOpcode, SM_RegisterClient,if ((iceConn->outbufptr + 8 + (((((unsigned int) ((extra) +
7)) >> 3)) << 3)) > iceConn->outbufmax) IceFlush
(iceConn); pMsg = (smRegisterClientMsg *) iceConn->outbufptr
; if ((iceConn->outbufptr + 8 + (((((unsigned int) ((extra
) + 7)) >> 3)) << 3)) <= iceConn->outbufmax
) pData = (char *) pMsg + 8; else pData = ((void*)0); pMsg->
majorOpcode = _SmcOpcode; pMsg->minorOpcode = 1; pMsg->
length = ((8 - 8) >> 3) + ((((unsigned int) ((extra) + 7
)) >> 3)); iceConn->outbufptr += (8 + (((((unsigned int
) ((extra) + 7)) >> 3)) << 3)); iceConn->send_sequence
++
265 SIZEOF (smRegisterClientMsg), WORD64COUNT (extra),if ((iceConn->outbufptr + 8 + (((((unsigned int) ((extra) +
7)) >> 3)) << 3)) > iceConn->outbufmax) IceFlush
(iceConn); pMsg = (smRegisterClientMsg *) iceConn->outbufptr
; if ((iceConn->outbufptr + 8 + (((((unsigned int) ((extra
) + 7)) >> 3)) << 3)) <= iceConn->outbufmax
) pData = (char *) pMsg + 8; else pData = ((void*)0); pMsg->
majorOpcode = _SmcOpcode; pMsg->minorOpcode = 1; pMsg->
length = ((8 - 8) >> 3) + ((((unsigned int) ((extra) + 7
)) >> 3)); iceConn->outbufptr += (8 + (((((unsigned int
) ((extra) + 7)) >> 3)) << 3)); iceConn->send_sequence
++
266 smRegisterClientMsg, pMsg, pData)if ((iceConn->outbufptr + 8 + (((((unsigned int) ((extra) +
7)) >> 3)) << 3)) > iceConn->outbufmax) IceFlush
(iceConn); pMsg = (smRegisterClientMsg *) iceConn->outbufptr
; if ((iceConn->outbufptr + 8 + (((((unsigned int) ((extra
) + 7)) >> 3)) << 3)) <= iceConn->outbufmax
) pData = (char *) pMsg + 8; else pData = ((void*)0); pMsg->
majorOpcode = _SmcOpcode; pMsg->minorOpcode = 1; pMsg->
length = ((8 - 8) >> 3) + ((((unsigned int) ((extra) + 7
)) >> 3)); iceConn->outbufptr += (8 + (((((unsigned int
) ((extra) + 7)) >> 3)) << 3)); iceConn->send_sequence
++
;
267
268 STORE_ARRAY8 (pData, 0, ""){ { *((CARD32 *) pData) = 0; pData += 4; }; if (0) memcpy (pData
, "", 0); pData += 0 + ((8 - ((unsigned int) (4 + 0) % 8)) % 8
); }
;
269
270 IceFlush (iceConn);
271
272 replyWait.sequence_of_request =
273 IceLastSentSequenceNumber (iceConn);
274
275 gotReply = False0;
276 }
277 }
278 }
279
280 return (smcConn);
281}
282
283
284
285SmcCloseStatus
286SmcCloseConnection(SmcConn smcConn, int count, char **reasonMsgs)
287{
288 IceConn iceConn = smcConn->iceConn;
289 smCloseConnectionMsg *pMsg;
290 char *pData;
291 int extra, i;
292 IceCloseStatus closeStatus;
293 SmcCloseStatus statusRet;
294
295 extra = 8;
296
297 for (i = 0; i < count; i++)
1
Assuming 'i' is >= 'count'
2
Loop condition is false. Execution continues on line 300
298 extra += ARRAY8_BYTES (strlen (reasonMsgs[i]))(4 + strlen (reasonMsgs[i]) + ((8 - ((unsigned int) (4 + strlen
(reasonMsgs[i])) % 8)) % 8))
;
299
300 IceGetHeaderExtra (iceConn, _SmcOpcode, SM_CloseConnection,if ((iceConn->outbufptr + 8 + (((((unsigned int) ((extra) +
7)) >> 3)) << 3)) > iceConn->outbufmax) IceFlush
(iceConn); pMsg = (smCloseConnectionMsg *) iceConn->outbufptr
; if ((iceConn->outbufptr + 8 + (((((unsigned int) ((extra
) + 7)) >> 3)) << 3)) <= iceConn->outbufmax
) pData = (char *) pMsg + 8; else pData = ((void*)0); pMsg->
majorOpcode = _SmcOpcode; pMsg->minorOpcode = 11; pMsg->
length = ((8 - 8) >> 3) + ((((unsigned int) ((extra) + 7
)) >> 3)); iceConn->outbufptr += (8 + (((((unsigned int
) ((extra) + 7)) >> 3)) << 3)); iceConn->send_sequence
++
301 SIZEOF (smCloseConnectionMsg), WORD64COUNT (extra),if ((iceConn->outbufptr + 8 + (((((unsigned int) ((extra) +
7)) >> 3)) << 3)) > iceConn->outbufmax) IceFlush
(iceConn); pMsg = (smCloseConnectionMsg *) iceConn->outbufptr
; if ((iceConn->outbufptr + 8 + (((((unsigned int) ((extra
) + 7)) >> 3)) << 3)) <= iceConn->outbufmax
) pData = (char *) pMsg + 8; else pData = ((void*)0); pMsg->
majorOpcode = _SmcOpcode; pMsg->minorOpcode = 11; pMsg->
length = ((8 - 8) >> 3) + ((((unsigned int) ((extra) + 7
)) >> 3)); iceConn->outbufptr += (8 + (((((unsigned int
) ((extra) + 7)) >> 3)) << 3)); iceConn->send_sequence
++
302 smCloseConnectionMsg, pMsg, pData)if ((iceConn->outbufptr + 8 + (((((unsigned int) ((extra) +
7)) >> 3)) << 3)) > iceConn->outbufmax) IceFlush
(iceConn); pMsg = (smCloseConnectionMsg *) iceConn->outbufptr
; if ((iceConn->outbufptr + 8 + (((((unsigned int) ((extra
) + 7)) >> 3)) << 3)) <= iceConn->outbufmax
) pData = (char *) pMsg + 8; else pData = ((void*)0); pMsg->
majorOpcode = _SmcOpcode; pMsg->minorOpcode = 11; pMsg->
length = ((8 - 8) >> 3) + ((((unsigned int) ((extra) + 7
)) >> 3)); iceConn->outbufptr += (8 + (((((unsigned int
) ((extra) + 7)) >> 3)) << 3)); iceConn->send_sequence
++
;
303
304 STORE_CARD32 (pData, count){ *((CARD32 *) pData) = count; pData += 4; };
3
Within the expansion of the macro 'STORE_CARD32':
a
Dereference of null pointer
305 pData += 4;
306
307 for (i = 0; i < count; i++)
308 STORE_ARRAY8 (pData, strlen (reasonMsgs[i]), reasonMsgs[i]){ { *((CARD32 *) pData) = strlen (reasonMsgs[i]); pData += 4;
}; if (strlen (reasonMsgs[i])) memcpy (pData, reasonMsgs[i],
strlen (reasonMsgs[i])); pData += strlen (reasonMsgs[i]) + (
(8 - ((unsigned int) (4 + strlen (reasonMsgs[i])) % 8)) % 8);
}
;
309
310 IceFlush (iceConn);
311
312 IceProtocolShutdown (iceConn, _SmcOpcode);
313 IceSetShutdownNegotiation (iceConn, False0);
314 closeStatus = IceCloseConnection (iceConn);
315
316 if (smcConn->vendor)
317 free (smcConn->vendor);
318
319 if (smcConn->release)
320 free (smcConn->release);
321
322 if (smcConn->client_id)
323 free (smcConn->client_id);
324
325 if (smcConn->prop_reply_waits)
326 {
327 _SmcPropReplyWait *ptr = smcConn->prop_reply_waits;
328 _SmcPropReplyWait *next;
329
330 while (ptr)
331 {
332 next = ptr->next;
333 free (ptr);
334 ptr = next;
335 }
336
337 }
338
339 free (smcConn);
340
341 if (closeStatus == IceClosedNow)
342 statusRet = SmcClosedNow;
343 else if (closeStatus == IceClosedASAP)
344 statusRet = SmcClosedASAP;
345 else
346 statusRet = SmcConnectionInUse;
347
348 return (statusRet);
349}
350
351
352
353void
354SmcModifyCallbacks(SmcConn smcConn, unsigned long mask, SmcCallbacks *callbacks)
355{
356 set_callbacks (smcConn, mask, callbacks);
357}
358
359
360
361void
362SmcSetProperties(SmcConn smcConn, int numProps, SmProp **props)
363{
364 IceConn iceConn = smcConn->iceConn;
365 smSetPropertiesMsg *pMsg;
366 char *pBuf;
367 char *pStart;
368 int bytes;
369
370 IceGetHeader (iceConn, _SmcOpcode, SM_SetProperties,if ((iceConn->outbufptr + 8) > iceConn->outbufmax) IceFlush
(iceConn); pMsg = (smSetPropertiesMsg *) iceConn->outbufptr
; pMsg->majorOpcode = _SmcOpcode; pMsg->minorOpcode = 12
; pMsg->length = (8 - 8) >> 3; iceConn->outbufptr
+= 8; iceConn->send_sequence++
371 SIZEOF (smSetPropertiesMsg), smSetPropertiesMsg, pMsg)if ((iceConn->outbufptr + 8) > iceConn->outbufmax) IceFlush
(iceConn); pMsg = (smSetPropertiesMsg *) iceConn->outbufptr
; pMsg->majorOpcode = _SmcOpcode; pMsg->minorOpcode = 12
; pMsg->length = (8 - 8) >> 3; iceConn->outbufptr
+= 8; iceConn->send_sequence++
;
372
373 LISTOF_PROP_BYTES (numProps, props, bytes){ int _i, _j; bytes = 8; for (_i = 0; _i < numProps; _i++)
{ bytes += (8 + (4 + strlen (props[_i]->name) + ((8 - ((unsigned
int) (4 + strlen (props[_i]->name)) % 8)) % 8)) + (4 + strlen
(props[_i]->type) + ((8 - ((unsigned int) (4 + strlen (props
[_i]->type)) % 8)) % 8))); for (_j = 0; _j < props[_i]->
num_vals; _j++) bytes += (4 + props[_i]->vals[_j].length +
((8 - ((unsigned int) (4 + props[_i]->vals[_j].length) % 8
)) % 8)); } }
;
374 pMsg->length += WORD64COUNT (bytes)(((unsigned int) ((bytes) + 7)) >> 3);
375
376 pBuf = pStart = IceAllocScratch (iceConn, bytes);
377 memset(pStart, 0, bytes);
378
379 STORE_LISTOF_PROPERTY (pBuf, numProps, props){ int _i, _j; { *((CARD32 *) pBuf) = numProps; pBuf += 4; }; pBuf
+= 4; for (_i = 0; _i < numProps; _i++) { { { *((CARD32 *
) pBuf) = strlen (props[_i]->name); pBuf += 4; }; if (strlen
(props[_i]->name)) memcpy (pBuf, props[_i]->name, strlen
(props[_i]->name)); pBuf += strlen (props[_i]->name) +
((8 - ((unsigned int) (4 + strlen (props[_i]->name)) % 8)
) % 8); }; { { *((CARD32 *) pBuf) = strlen (props[_i]->type
); pBuf += 4; }; if (strlen (props[_i]->type)) memcpy (pBuf
, props[_i]->type, strlen (props[_i]->type)); pBuf += strlen
(props[_i]->type) + ((8 - ((unsigned int) (4 + strlen (props
[_i]->type)) % 8)) % 8); }; { *((CARD32 *) pBuf) = props[_i
]->num_vals; pBuf += 4; }; pBuf += 4; for (_j = 0; _j <
props[_i]->num_vals; _j++) { { { *((CARD32 *) pBuf) = props
[_i]->vals[_j].length; pBuf += 4; }; if (props[_i]->vals
[_j].length) memcpy (pBuf, (char *) props[_i]->vals[_j].value
, props[_i]->vals[_j].length); pBuf += props[_i]->vals[
_j].length + ((8 - ((unsigned int) (4 + props[_i]->vals[_j
].length) % 8)) % 8); }; } } }
;
380
381 IceWriteData (iceConn, bytes, pStart){ if ((iceConn->outbufptr + (bytes)) > iceConn->outbufmax
) { IceFlush (iceConn); _IceWrite (iceConn, (unsigned long) (
bytes), pStart); } else { memcpy (iceConn->outbufptr, pStart
, bytes); iceConn->outbufptr += (bytes); } }
;
382 IceFlush (iceConn);
383}
384
385
386
387void
388SmcDeleteProperties(SmcConn smcConn, int numProps, char **propNames)
389{
390 IceConn iceConn = smcConn->iceConn;
391 smDeletePropertiesMsg *pMsg;
392 char *pData;
393 int extra, i;
394
395 extra = 8;
396
397 for (i = 0; i < numProps; i++)
398 extra += ARRAY8_BYTES (strlen (propNames[i]))(4 + strlen (propNames[i]) + ((8 - ((unsigned int) (4 + strlen
(propNames[i])) % 8)) % 8))
;
399
400 IceGetHeaderExtra (iceConn, _SmcOpcode, SM_DeleteProperties,if ((iceConn->outbufptr + 8 + (((((unsigned int) ((extra) +
7)) >> 3)) << 3)) > iceConn->outbufmax) IceFlush
(iceConn); pMsg = (smDeletePropertiesMsg *) iceConn->outbufptr
; if ((iceConn->outbufptr + 8 + (((((unsigned int) ((extra
) + 7)) >> 3)) << 3)) <= iceConn->outbufmax
) pData = (char *) pMsg + 8; else pData = ((void*)0); pMsg->
majorOpcode = _SmcOpcode; pMsg->minorOpcode = 13; pMsg->
length = ((8 - 8) >> 3) + ((((unsigned int) ((extra) + 7
)) >> 3)); iceConn->outbufptr += (8 + (((((unsigned int
) ((extra) + 7)) >> 3)) << 3)); iceConn->send_sequence
++
401 SIZEOF (smDeletePropertiesMsg), WORD64COUNT (extra),if ((iceConn->outbufptr + 8 + (((((unsigned int) ((extra) +
7)) >> 3)) << 3)) > iceConn->outbufmax) IceFlush
(iceConn); pMsg = (smDeletePropertiesMsg *) iceConn->outbufptr
; if ((iceConn->outbufptr + 8 + (((((unsigned int) ((extra
) + 7)) >> 3)) << 3)) <= iceConn->outbufmax
) pData = (char *) pMsg + 8; else pData = ((void*)0); pMsg->
majorOpcode = _SmcOpcode; pMsg->minorOpcode = 13; pMsg->
length = ((8 - 8) >> 3) + ((((unsigned int) ((extra) + 7
)) >> 3)); iceConn->outbufptr += (8 + (((((unsigned int
) ((extra) + 7)) >> 3)) << 3)); iceConn->send_sequence
++
402 smDeletePropertiesMsg, pMsg, pData)if ((iceConn->outbufptr + 8 + (((((unsigned int) ((extra) +
7)) >> 3)) << 3)) > iceConn->outbufmax) IceFlush
(iceConn); pMsg = (smDeletePropertiesMsg *) iceConn->outbufptr
; if ((iceConn->outbufptr + 8 + (((((unsigned int) ((extra
) + 7)) >> 3)) << 3)) <= iceConn->outbufmax
) pData = (char *) pMsg + 8; else pData = ((void*)0); pMsg->
majorOpcode = _SmcOpcode; pMsg->minorOpcode = 13; pMsg->
length = ((8 - 8) >> 3) + ((((unsigned int) ((extra) + 7
)) >> 3)); iceConn->outbufptr += (8 + (((((unsigned int
) ((extra) + 7)) >> 3)) << 3)); iceConn->send_sequence
++
;
403
404 STORE_CARD32 (pData, numProps){ *((CARD32 *) pData) = numProps; pData += 4; };
405 pData += 4;
406
407 for (i = 0; i < numProps; i++)
408 STORE_ARRAY8 (pData, strlen (propNames[i]), propNames[i]){ { *((CARD32 *) pData) = strlen (propNames[i]); pData += 4; }
; if (strlen (propNames[i])) memcpy (pData, propNames[i], strlen
(propNames[i])); pData += strlen (propNames[i]) + ((8 - ((unsigned
int) (4 + strlen (propNames[i])) % 8)) % 8); }
;
409
410 IceFlush (iceConn);
411}
412
413
414
415Statusint
416SmcGetProperties(SmcConn smcConn, SmcPropReplyProc propReplyProc,
417 SmPointer clientData)
418{
419 IceConn iceConn = smcConn->iceConn;
420 _SmcPropReplyWait *wait, *ptr;
421
422 if ((wait = malloc (sizeof (_SmcPropReplyWait))) == NULL((void*)0))
423 {
424 return (0);
425 }
426
427 wait->prop_reply_proc = propReplyProc;
428 wait->client_data = clientData;
429 wait->next = NULL((void*)0);
430
431 ptr = smcConn->prop_reply_waits;
432 while (ptr && ptr->next)
433 ptr = ptr->next;
434
435 if (ptr == NULL((void*)0))
436 smcConn->prop_reply_waits = wait;
437 else
438 ptr->next = wait;
439
440 IceSimpleMessage (iceConn, _SmcOpcode, SM_GetProperties){ iceMsg *_pMsg; if ((iceConn->outbufptr + 8) > iceConn
->outbufmax) IceFlush (iceConn); _pMsg = (iceMsg *) iceConn
->outbufptr; _pMsg->majorOpcode = _SmcOpcode; _pMsg->
minorOpcode = 14; _pMsg->length = (8 - 8) >> 3; iceConn
->outbufptr += 8; iceConn->send_sequence++; }
;
441 IceFlush (iceConn);
442
443 return (1);
444}
445
446
447
448Statusint
449SmcInteractRequest(SmcConn smcConn, int dialogType,
450 SmcInteractProc interactProc, SmPointer clientData)
451{
452 IceConn iceConn = smcConn->iceConn;
453 smInteractRequestMsg *pMsg;
454 _SmcInteractWait *wait, *ptr;
455
456 if ((wait = malloc (sizeof (_SmcInteractWait))) == NULL((void*)0))
457 {
458 return (0);
459 }
460
461 wait->interact_proc = interactProc;
462 wait->client_data = clientData;
463 wait->next = NULL((void*)0);
464
465 ptr = smcConn->interact_waits;
466 while (ptr && ptr->next)
467 ptr = ptr->next;
468
469 if (ptr == NULL((void*)0))
470 smcConn->interact_waits = wait;
471 else
472 ptr->next = wait;
473
474 IceGetHeader (iceConn, _SmcOpcode, SM_InteractRequest,if ((iceConn->outbufptr + 8) > iceConn->outbufmax) IceFlush
(iceConn); pMsg = (smInteractRequestMsg *) iceConn->outbufptr
; pMsg->majorOpcode = _SmcOpcode; pMsg->minorOpcode = 5
; pMsg->length = (8 - 8) >> 3; iceConn->outbufptr
+= 8; iceConn->send_sequence++
475 SIZEOF (smInteractRequestMsg), smInteractRequestMsg, pMsg)if ((iceConn->outbufptr + 8) > iceConn->outbufmax) IceFlush
(iceConn); pMsg = (smInteractRequestMsg *) iceConn->outbufptr
; pMsg->majorOpcode = _SmcOpcode; pMsg->minorOpcode = 5
; pMsg->length = (8 - 8) >> 3; iceConn->outbufptr
+= 8; iceConn->send_sequence++
;
476
477 pMsg->dialogType = dialogType;
478
479 IceFlush (iceConn);
480
481 return (1);
482}
483
484
485
486void
487SmcInteractDone(SmcConn smcConn, Boolint cancelShutdown)
488{
489 IceConn iceConn = smcConn->iceConn;
490 smInteractDoneMsg *pMsg;
491
492 IceGetHeader (iceConn, _SmcOpcode, SM_InteractDone,if ((iceConn->outbufptr + 8) > iceConn->outbufmax) IceFlush
(iceConn); pMsg = (smInteractDoneMsg *) iceConn->outbufptr
; pMsg->majorOpcode = _SmcOpcode; pMsg->minorOpcode = 7
; pMsg->length = (8 - 8) >> 3; iceConn->outbufptr
+= 8; iceConn->send_sequence++
493 SIZEOF (smInteractDoneMsg), smInteractDoneMsg, pMsg)if ((iceConn->outbufptr + 8) > iceConn->outbufmax) IceFlush
(iceConn); pMsg = (smInteractDoneMsg *) iceConn->outbufptr
; pMsg->majorOpcode = _SmcOpcode; pMsg->minorOpcode = 7
; pMsg->length = (8 - 8) >> 3; iceConn->outbufptr
+= 8; iceConn->send_sequence++
;
494
495 pMsg->cancelShutdown = cancelShutdown;
496
497 IceFlush (iceConn);
498}
499
500
501
502void
503SmcRequestSaveYourself(SmcConn smcConn, int saveType, Boolint shutdown,
504 int interactStyle, Boolint fast, Boolint global)
505{
506 IceConn iceConn = smcConn->iceConn;
507 smSaveYourselfRequestMsg *pMsg;
508
509 IceGetHeader (iceConn, _SmcOpcode, SM_SaveYourselfRequest,if ((iceConn->outbufptr + 16) > iceConn->outbufmax) IceFlush
(iceConn); pMsg = (smSaveYourselfRequestMsg *) iceConn->outbufptr
; pMsg->majorOpcode = _SmcOpcode; pMsg->minorOpcode = 4
; pMsg->length = (16 - 8) >> 3; iceConn->outbufptr
+= 16; iceConn->send_sequence++
510 SIZEOF (smSaveYourselfRequestMsg), smSaveYourselfRequestMsg, pMsg)if ((iceConn->outbufptr + 16) > iceConn->outbufmax) IceFlush
(iceConn); pMsg = (smSaveYourselfRequestMsg *) iceConn->outbufptr
; pMsg->majorOpcode = _SmcOpcode; pMsg->minorOpcode = 4
; pMsg->length = (16 - 8) >> 3; iceConn->outbufptr
+= 16; iceConn->send_sequence++
;
511
512 pMsg->saveType = saveType;
513 pMsg->shutdown = shutdown;
514 pMsg->interactStyle = interactStyle;
515 pMsg->fast = fast;
516 pMsg->global = global;
517
518 IceFlush (iceConn);
519}
520
521
522
523Statusint
524SmcRequestSaveYourselfPhase2(SmcConn smcConn,
525 SmcSaveYourselfPhase2Proc saveYourselfPhase2Proc,
526 SmPointer clientData)
527{
528 IceConn iceConn = smcConn->iceConn;
529 _SmcPhase2Wait *wait;
530
531 if (smcConn->phase2_wait)
532 wait = smcConn->phase2_wait;
533 else
534 {
535 if ((wait = malloc (sizeof (_SmcPhase2Wait))) == NULL((void*)0))
536 {
537 return (0);
538 }
539 }
540
541 wait->phase2_proc = saveYourselfPhase2Proc;
542 wait->client_data = clientData;
543
544 smcConn->phase2_wait = wait;
545
546 IceSimpleMessage (iceConn, _SmcOpcode, SM_SaveYourselfPhase2Request){ iceMsg *_pMsg; if ((iceConn->outbufptr + 8) > iceConn
->outbufmax) IceFlush (iceConn); _pMsg = (iceMsg *) iceConn
->outbufptr; _pMsg->majorOpcode = _SmcOpcode; _pMsg->
minorOpcode = 16; _pMsg->length = (8 - 8) >> 3; iceConn
->outbufptr += 8; iceConn->send_sequence++; }
;
547 IceFlush (iceConn);
548
549 return (1);
550}
551
552
553
554void
555SmcSaveYourselfDone(SmcConn smcConn, Boolint success)
556{
557 IceConn iceConn = smcConn->iceConn;
558 smSaveYourselfDoneMsg *pMsg;
559
560 IceGetHeader (iceConn, _SmcOpcode, SM_SaveYourselfDone,if ((iceConn->outbufptr + 8) > iceConn->outbufmax) IceFlush
(iceConn); pMsg = (smSaveYourselfDoneMsg *) iceConn->outbufptr
; pMsg->majorOpcode = _SmcOpcode; pMsg->minorOpcode = 8
; pMsg->length = (8 - 8) >> 3; iceConn->outbufptr
+= 8; iceConn->send_sequence++
561 SIZEOF (smSaveYourselfDoneMsg), smSaveYourselfDoneMsg, pMsg)if ((iceConn->outbufptr + 8) > iceConn->outbufmax) IceFlush
(iceConn); pMsg = (smSaveYourselfDoneMsg *) iceConn->outbufptr
; pMsg->majorOpcode = _SmcOpcode; pMsg->minorOpcode = 8
; pMsg->length = (8 - 8) >> 3; iceConn->outbufptr
+= 8; iceConn->send_sequence++
;
562
563 pMsg->success = success;
564
565 IceFlush (iceConn);
566}
567
568
569
570static void
571set_callbacks(SmcConn smcConn, unsigned long mask, SmcCallbacks *callbacks)
572{
573 if (mask & SmcSaveYourselfProcMask(1L << 0))
574 {
575 smcConn->callbacks.save_yourself.callback =
576 callbacks->save_yourself.callback;
577 smcConn->callbacks.save_yourself.client_data =
578 callbacks->save_yourself.client_data;
579 }
580
581 if (mask & SmcDieProcMask(1L << 1))
582 {
583 smcConn->callbacks.die.callback = callbacks->die.callback;
584 smcConn->callbacks.die.client_data = callbacks->die.client_data;
585 }
586
587 if (mask & SmcSaveCompleteProcMask(1L << 2))
588 {
589 smcConn->callbacks.save_complete.callback =
590 callbacks->save_complete.callback;
591 smcConn->callbacks.save_complete.client_data =
592 callbacks->save_complete.client_data;
593 }
594
595 if (mask & SmcShutdownCancelledProcMask(1L << 3))
596 {
597 smcConn->callbacks.shutdown_cancelled.callback =
598 callbacks->shutdown_cancelled.callback;
599 smcConn->callbacks.shutdown_cancelled.client_data =
600 callbacks->shutdown_cancelled.client_data;
601 }
602}