| File: | sm_client.c |
| Location: | line 212, 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 | } |