File: | sm_client.c |
Location: | line 404, column 5 |
Description: | Dereference of null pointer |
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_H1 | ||||
32 | #include <config.h> | ||||
33 | #endif | ||||
34 | #include <X11/SM/SMlib.h> | ||||
35 | #include "SMlibint.h" | ||||
36 | |||||
37 | int _SmcOpcode = 0; | ||||
38 | int _SmsOpcode = 0; | ||||
39 | |||||
40 | #ifndef __UNIXOS2__ | ||||
41 | SmsNewClientProc _SmsNewClientProc; | ||||
42 | SmPointer _SmsNewClientData; | ||||
43 | #else | ||||
44 | SmsNewClientProc _SmsNewClientProc = 0; | ||||
45 | SmPointer _SmsNewClientData = 0; | ||||
46 | #endif | ||||
47 | |||||
48 | SmcErrorHandler _SmcErrorHandler = _SmcDefaultErrorHandler; | ||||
49 | SmsErrorHandler _SmsErrorHandler = _SmsDefaultErrorHandler; | ||||
50 | |||||
51 | |||||
52 | static void | ||||
53 | set_callbacks(SmcConn smcConn, unsigned long mask, SmcCallbacks *callbacks); | ||||
54 | |||||
55 | |||||
56 | SmcConn | ||||
57 | SmcOpenConnection(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 | |||||
285 | SmcCloseStatus | ||||
286 | SmcCloseConnection(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++) | ||||
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; }; | ||||
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 | |||||
353 | void | ||||
354 | SmcModifyCallbacks(SmcConn smcConn, unsigned long mask, SmcCallbacks *callbacks) | ||||
355 | { | ||||
356 | set_callbacks (smcConn, mask, callbacks); | ||||
357 | } | ||||
358 | |||||
359 | |||||
360 | |||||
361 | void | ||||
362 | SmcSetProperties(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 | |||||
387 | void | ||||
388 | SmcDeleteProperties(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 | |||||
415 | Statusint | ||||
416 | SmcGetProperties(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 | |||||
448 | Statusint | ||||
449 | SmcInteractRequest(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 | |||||
486 | void | ||||
487 | SmcInteractDone(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 | |||||
502 | void | ||||
503 | SmcRequestSaveYourself(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 | |||||
523 | Statusint | ||||
524 | SmcRequestSaveYourselfPhase2(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 | |||||
554 | void | ||||
555 | SmcSaveYourselfDone(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 | |||||
570 | static void | ||||
571 | set_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 | } |