sm_client.c revision 0a6b08f8
1126a8a12Smrg/* 2126a8a12Smrg 3126a8a12SmrgCopyright 1993, 1998 The Open Group 4126a8a12Smrg 5126a8a12SmrgPermission to use, copy, modify, distribute, and sell this software and its 6126a8a12Smrgdocumentation for any purpose is hereby granted without fee, provided that 7126a8a12Smrgthe above copyright notice appear in all copies and that both that 8126a8a12Smrgcopyright notice and this permission notice appear in supporting 9126a8a12Smrgdocumentation. 10126a8a12Smrg 11126a8a12SmrgThe above copyright notice and this permission notice shall be included in 12126a8a12Smrgall copies or substantial portions of the Software. 13126a8a12Smrg 14126a8a12SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15126a8a12SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16126a8a12SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17126a8a12SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18126a8a12SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19126a8a12SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20126a8a12Smrg 21126a8a12SmrgExcept as contained in this notice, the name of The Open Group shall not be 22126a8a12Smrgused in advertising or otherwise to promote the sale, use or other dealings 23126a8a12Smrgin this Software without prior written authorization from The Open Group. 24126a8a12Smrg 25126a8a12Smrg*/ 26126a8a12Smrg 27126a8a12Smrg/* 28126a8a12Smrg * Author: Ralph Mor, X Consortium 29126a8a12Smrg */ 30126a8a12Smrg 31126a8a12Smrg#ifdef HAVE_CONFIG_H 32126a8a12Smrg#include <config.h> 33126a8a12Smrg#endif 34126a8a12Smrg#include <X11/SM/SMlib.h> 35126a8a12Smrg#include "SMlibint.h" 36126a8a12Smrg 37d656433aSmrgint _SmcOpcode = 0; 38d656433aSmrgint _SmsOpcode = 0; 39d656433aSmrg 40d656433aSmrgSmsNewClientProc _SmsNewClientProc; 41d656433aSmrgSmPointer _SmsNewClientData; 42d656433aSmrg 43d656433aSmrgSmcErrorHandler _SmcErrorHandler = _SmcDefaultErrorHandler; 44d656433aSmrgSmsErrorHandler _SmsErrorHandler = _SmsDefaultErrorHandler; 45d656433aSmrg 46d656433aSmrg 47d656433aSmrgstatic void 48d656433aSmrgset_callbacks(SmcConn smcConn, unsigned long mask, SmcCallbacks *callbacks); 49126a8a12Smrg 50126a8a12Smrg 51126a8a12SmrgSmcConn 52d656433aSmrgSmcOpenConnection(char *networkIdsList, SmPointer context, 53d656433aSmrg int xsmpMajorRev, int xsmpMinorRev, 54d656433aSmrg unsigned long mask, SmcCallbacks *callbacks, 550a6b08f8Smrg const char *previousId, char **clientIdRet, 56d656433aSmrg int errorLength, char *errorStringRet) 57126a8a12Smrg{ 58126a8a12Smrg SmcConn smcConn; 59126a8a12Smrg IceConn iceConn; 60126a8a12Smrg char *ids; 61126a8a12Smrg IceProtocolSetupStatus setupstat; 62126a8a12Smrg int majorVersion; 63126a8a12Smrg int minorVersion; 64126a8a12Smrg char *vendor = NULL; 65126a8a12Smrg char *release = NULL; 66126a8a12Smrg smRegisterClientMsg *pMsg; 67126a8a12Smrg char *pData; 680a6b08f8Smrg unsigned int extra, len; 69126a8a12Smrg IceReplyWaitInfo replyWait; 70126a8a12Smrg _SmcRegisterClientReply reply; 71126a8a12Smrg Bool gotReply, ioErrorOccured; 72126a8a12Smrg 73126a8a12Smrg const char *auth_names[] = {"MIT-MAGIC-COOKIE-1"}; 74126a8a12Smrg IcePoAuthProc auth_procs[] = {_IcePoMagicCookie1Proc}; 75126a8a12Smrg int auth_count = 1; 76126a8a12Smrg 77126a8a12Smrg IcePoVersionRec versions[] = { 78126a8a12Smrg {SmProtoMajor, SmProtoMinor, _SmcProcessMessage} 79126a8a12Smrg }; 80126a8a12Smrg int version_count = 1; 81126a8a12Smrg 82126a8a12Smrg 83126a8a12Smrg *clientIdRet = NULL; 84126a8a12Smrg 85126a8a12Smrg if (errorStringRet && errorLength > 0) 86126a8a12Smrg *errorStringRet = '\0'; 87126a8a12Smrg 88126a8a12Smrg if (!_SmcOpcode) 89126a8a12Smrg { 90126a8a12Smrg /* 91126a8a12Smrg * For now, there is only one version of XSMP, so we don't 92126a8a12Smrg * have to check {xsmpMajorRev, xsmpMinorRev}. In the future, 93126a8a12Smrg * we will check against versions and generate the list 94126a8a12Smrg * of versions the application actually supports. 95126a8a12Smrg */ 96126a8a12Smrg 97126a8a12Smrg if ((_SmcOpcode = IceRegisterForProtocolSetup ("XSMP", 98126a8a12Smrg SmVendorString, SmReleaseString, version_count, versions, 99126a8a12Smrg auth_count, auth_names, auth_procs, NULL)) < 0) 100126a8a12Smrg { 101126a8a12Smrg if (errorStringRet && errorLength > 0) { 102126a8a12Smrg strncpy (errorStringRet, 103126a8a12Smrg "Could not register XSMP protocol with ICE", 104126a8a12Smrg errorLength); 105126a8a12Smrg errorStringRet[errorLength - 1] = '\0'; 106126a8a12Smrg } 107126a8a12Smrg 108126a8a12Smrg return (NULL); 109126a8a12Smrg } 110126a8a12Smrg } 111126a8a12Smrg 112126a8a12Smrg if (networkIdsList == NULL || *networkIdsList == '\0') 113126a8a12Smrg { 114126a8a12Smrg if ((ids = (char *) getenv ("SESSION_MANAGER")) == NULL) 115126a8a12Smrg { 116126a8a12Smrg if (errorStringRet && errorLength > 0) { 117126a8a12Smrg strncpy (errorStringRet, 118126a8a12Smrg "SESSION_MANAGER environment variable not defined", 119126a8a12Smrg errorLength); 120126a8a12Smrg errorStringRet[errorLength - 1] = '\0'; 121126a8a12Smrg } 122126a8a12Smrg return (NULL); 123126a8a12Smrg } 124126a8a12Smrg } 125126a8a12Smrg else 126126a8a12Smrg { 127126a8a12Smrg ids = networkIdsList; 128126a8a12Smrg } 129126a8a12Smrg 130126a8a12Smrg if ((iceConn = IceOpenConnection ( 131126a8a12Smrg ids, context, 0, _SmcOpcode, errorLength, errorStringRet)) == NULL) 132126a8a12Smrg { 133126a8a12Smrg return (NULL); 134126a8a12Smrg } 135126a8a12Smrg 1363c15da26Smrg if ((smcConn = malloc (sizeof (struct _SmcConn))) == NULL) 137126a8a12Smrg { 138126a8a12Smrg if (errorStringRet && errorLength > 0) { 139126a8a12Smrg strncpy (errorStringRet, "Can't malloc", errorLength); 140126a8a12Smrg errorStringRet[errorLength - 1] = '\0'; 141126a8a12Smrg } 142126a8a12Smrg IceCloseConnection (iceConn); 143126a8a12Smrg return (NULL); 144126a8a12Smrg } 145126a8a12Smrg 146126a8a12Smrg setupstat = IceProtocolSetup (iceConn, _SmcOpcode, 147126a8a12Smrg (IcePointer) smcConn, 148126a8a12Smrg False /* mustAuthenticate */, 149126a8a12Smrg &majorVersion, &minorVersion, 150126a8a12Smrg &vendor, &release, errorLength, errorStringRet); 151126a8a12Smrg 152126a8a12Smrg if (setupstat == IceProtocolSetupFailure || 153126a8a12Smrg setupstat == IceProtocolSetupIOError) 154126a8a12Smrg { 155126a8a12Smrg IceCloseConnection (iceConn); 1563c15da26Smrg free (smcConn); 157126a8a12Smrg return (NULL); 158126a8a12Smrg } 159126a8a12Smrg else if (setupstat == IceProtocolAlreadyActive) 160126a8a12Smrg { 161126a8a12Smrg /* 162126a8a12Smrg * This case should never happen, because when we called 163126a8a12Smrg * IceOpenConnection, we required that the ICE connection 164126a8a12Smrg * may not already have XSMP active on it. 165126a8a12Smrg */ 166126a8a12Smrg 1673c15da26Smrg free (smcConn); 168126a8a12Smrg if (errorStringRet && errorLength > 0) { 169126a8a12Smrg strncpy (errorStringRet, "Internal error in IceOpenConnection", 170126a8a12Smrg errorLength); 171126a8a12Smrg errorStringRet[errorLength - 1] = '\0'; 172126a8a12Smrg } 173126a8a12Smrg return (NULL); 174126a8a12Smrg } 175126a8a12Smrg 176126a8a12Smrg smcConn->iceConn = iceConn; 177126a8a12Smrg smcConn->proto_major_version = majorVersion; 178126a8a12Smrg smcConn->proto_minor_version = minorVersion; 179126a8a12Smrg smcConn->vendor = vendor; 180126a8a12Smrg smcConn->release = release; 181126a8a12Smrg smcConn->client_id = NULL; 182126a8a12Smrg 183126a8a12Smrg bzero ((char *) &smcConn->callbacks, sizeof (SmcCallbacks)); 184126a8a12Smrg set_callbacks (smcConn, mask, callbacks); 185126a8a12Smrg 186126a8a12Smrg smcConn->interact_waits = NULL; 187126a8a12Smrg smcConn->phase2_wait = NULL; 188126a8a12Smrg smcConn->prop_reply_waits = NULL; 189126a8a12Smrg 190126a8a12Smrg smcConn->save_yourself_in_progress = False; 191126a8a12Smrg smcConn->shutdown_in_progress = False; 192126a8a12Smrg 193126a8a12Smrg 194126a8a12Smrg /* 195126a8a12Smrg * Now register the client 196126a8a12Smrg */ 197126a8a12Smrg 198d656433aSmrg if (!previousId) 199d656433aSmrg previousId = ""; 200d656433aSmrg len = strlen (previousId); 201126a8a12Smrg extra = ARRAY8_BYTES (len); 202126a8a12Smrg 203126a8a12Smrg IceGetHeaderExtra (iceConn, _SmcOpcode, SM_RegisterClient, 204126a8a12Smrg SIZEOF (smRegisterClientMsg), WORD64COUNT (extra), 205126a8a12Smrg smRegisterClientMsg, pMsg, pData); 206126a8a12Smrg 207126a8a12Smrg STORE_ARRAY8 (pData, len, previousId); 208126a8a12Smrg 209126a8a12Smrg IceFlush (iceConn); 210126a8a12Smrg 211126a8a12Smrg replyWait.sequence_of_request = IceLastSentSequenceNumber (iceConn); 212126a8a12Smrg replyWait.major_opcode_of_request = _SmcOpcode; 213126a8a12Smrg replyWait.minor_opcode_of_request = SM_RegisterClient; 214126a8a12Smrg replyWait.reply = (IcePointer) &reply; 215126a8a12Smrg 216126a8a12Smrg gotReply = False; 217126a8a12Smrg ioErrorOccured = False; 218126a8a12Smrg 219126a8a12Smrg while (!gotReply && !ioErrorOccured) 220126a8a12Smrg { 221126a8a12Smrg ioErrorOccured = (IceProcessMessages ( 222126a8a12Smrg iceConn, &replyWait, &gotReply) == IceProcessMessagesIOError); 223126a8a12Smrg 224126a8a12Smrg if (ioErrorOccured) 225126a8a12Smrg { 226126a8a12Smrg if (errorStringRet && errorLength > 0) { 227126a8a12Smrg strncpy (errorStringRet, "IO error occured opening connection", 228126a8a12Smrg errorLength); 229126a8a12Smrg errorStringRet[errorLength - 1] = '\0'; 230126a8a12Smrg } 231126a8a12Smrg free (smcConn->vendor); 232126a8a12Smrg free (smcConn->release); 2333c15da26Smrg free (smcConn); 234126a8a12Smrg 235126a8a12Smrg return (NULL); 236126a8a12Smrg } 237126a8a12Smrg else if (gotReply) 238126a8a12Smrg { 239126a8a12Smrg if (reply.status == 1) 240126a8a12Smrg { 241126a8a12Smrg /* 242126a8a12Smrg * The client successfully registered. 243126a8a12Smrg */ 244126a8a12Smrg 245126a8a12Smrg *clientIdRet = reply.client_id; 246126a8a12Smrg 2473c15da26Smrg smcConn->client_id = strdup (*clientIdRet); 248126a8a12Smrg } 249126a8a12Smrg else 250126a8a12Smrg { 251126a8a12Smrg /* 252126a8a12Smrg * Could not register the client because the previous ID 253126a8a12Smrg * was bad. So now we register the client with the 254126a8a12Smrg * previous ID set to NULL. 255126a8a12Smrg */ 256126a8a12Smrg 257126a8a12Smrg extra = ARRAY8_BYTES (0); 258126a8a12Smrg 259126a8a12Smrg IceGetHeaderExtra (iceConn, _SmcOpcode, SM_RegisterClient, 260126a8a12Smrg SIZEOF (smRegisterClientMsg), WORD64COUNT (extra), 261126a8a12Smrg smRegisterClientMsg, pMsg, pData); 262126a8a12Smrg 263d656433aSmrg STORE_ARRAY8 (pData, 0, ""); 264126a8a12Smrg 265126a8a12Smrg IceFlush (iceConn); 266126a8a12Smrg 267126a8a12Smrg replyWait.sequence_of_request = 268126a8a12Smrg IceLastSentSequenceNumber (iceConn); 269126a8a12Smrg 270126a8a12Smrg gotReply = False; 271126a8a12Smrg } 272126a8a12Smrg } 273126a8a12Smrg } 274126a8a12Smrg 275126a8a12Smrg return (smcConn); 276126a8a12Smrg} 277126a8a12Smrg 278126a8a12Smrg 279126a8a12Smrg 280126a8a12SmrgSmcCloseStatus 281d656433aSmrgSmcCloseConnection(SmcConn smcConn, int count, char **reasonMsgs) 282126a8a12Smrg{ 283126a8a12Smrg IceConn iceConn = smcConn->iceConn; 284126a8a12Smrg smCloseConnectionMsg *pMsg; 285126a8a12Smrg char *pData; 286126a8a12Smrg int extra, i; 287126a8a12Smrg IceCloseStatus closeStatus; 288126a8a12Smrg SmcCloseStatus statusRet; 289126a8a12Smrg 290126a8a12Smrg extra = 8; 291126a8a12Smrg 292126a8a12Smrg for (i = 0; i < count; i++) 293126a8a12Smrg extra += ARRAY8_BYTES (strlen (reasonMsgs[i])); 294126a8a12Smrg 295126a8a12Smrg IceGetHeaderExtra (iceConn, _SmcOpcode, SM_CloseConnection, 296126a8a12Smrg SIZEOF (smCloseConnectionMsg), WORD64COUNT (extra), 297126a8a12Smrg smCloseConnectionMsg, pMsg, pData); 298126a8a12Smrg 2990a6b08f8Smrg STORE_CARD32 (pData, (CARD32) count); 300126a8a12Smrg pData += 4; 301126a8a12Smrg 302126a8a12Smrg for (i = 0; i < count; i++) 3033c15da26Smrg STORE_ARRAY8 (pData, strlen (reasonMsgs[i]), reasonMsgs[i]); 304126a8a12Smrg 305126a8a12Smrg IceFlush (iceConn); 306126a8a12Smrg 307126a8a12Smrg IceProtocolShutdown (iceConn, _SmcOpcode); 308126a8a12Smrg IceSetShutdownNegotiation (iceConn, False); 309126a8a12Smrg closeStatus = IceCloseConnection (iceConn); 310126a8a12Smrg 311126a8a12Smrg if (smcConn->vendor) 312126a8a12Smrg free (smcConn->vendor); 313126a8a12Smrg 314126a8a12Smrg if (smcConn->release) 315126a8a12Smrg free (smcConn->release); 316126a8a12Smrg 317126a8a12Smrg if (smcConn->client_id) 318126a8a12Smrg free (smcConn->client_id); 319126a8a12Smrg 320126a8a12Smrg if (smcConn->prop_reply_waits) 321126a8a12Smrg { 322126a8a12Smrg _SmcPropReplyWait *ptr = smcConn->prop_reply_waits; 323126a8a12Smrg _SmcPropReplyWait *next; 324126a8a12Smrg 325126a8a12Smrg while (ptr) 326126a8a12Smrg { 327126a8a12Smrg next = ptr->next; 3283c15da26Smrg free (ptr); 329126a8a12Smrg ptr = next; 330126a8a12Smrg } 3313c15da26Smrg 332126a8a12Smrg } 333126a8a12Smrg 3343c15da26Smrg free (smcConn); 335126a8a12Smrg 336126a8a12Smrg if (closeStatus == IceClosedNow) 337126a8a12Smrg statusRet = SmcClosedNow; 338126a8a12Smrg else if (closeStatus == IceClosedASAP) 339126a8a12Smrg statusRet = SmcClosedASAP; 340126a8a12Smrg else 341126a8a12Smrg statusRet = SmcConnectionInUse; 342126a8a12Smrg 343126a8a12Smrg return (statusRet); 344126a8a12Smrg} 345126a8a12Smrg 346126a8a12Smrg 347126a8a12Smrg 348126a8a12Smrgvoid 349d656433aSmrgSmcModifyCallbacks(SmcConn smcConn, unsigned long mask, SmcCallbacks *callbacks) 350126a8a12Smrg{ 351126a8a12Smrg set_callbacks (smcConn, mask, callbacks); 352126a8a12Smrg} 353126a8a12Smrg 354126a8a12Smrg 355126a8a12Smrg 356126a8a12Smrgvoid 357d656433aSmrgSmcSetProperties(SmcConn smcConn, int numProps, SmProp **props) 358126a8a12Smrg{ 359126a8a12Smrg IceConn iceConn = smcConn->iceConn; 360126a8a12Smrg smSetPropertiesMsg *pMsg; 361126a8a12Smrg char *pBuf; 362126a8a12Smrg char *pStart; 3630a6b08f8Smrg unsigned int bytes; 364126a8a12Smrg 365126a8a12Smrg IceGetHeader (iceConn, _SmcOpcode, SM_SetProperties, 366126a8a12Smrg SIZEOF (smSetPropertiesMsg), smSetPropertiesMsg, pMsg); 367126a8a12Smrg 368126a8a12Smrg LISTOF_PROP_BYTES (numProps, props, bytes); 369126a8a12Smrg pMsg->length += WORD64COUNT (bytes); 370126a8a12Smrg 371126a8a12Smrg pBuf = pStart = IceAllocScratch (iceConn, bytes); 372d656433aSmrg memset(pStart, 0, bytes); 373126a8a12Smrg 374126a8a12Smrg STORE_LISTOF_PROPERTY (pBuf, numProps, props); 375126a8a12Smrg 376126a8a12Smrg IceWriteData (iceConn, bytes, pStart); 377126a8a12Smrg IceFlush (iceConn); 378126a8a12Smrg} 379126a8a12Smrg 380126a8a12Smrg 381126a8a12Smrg 382126a8a12Smrgvoid 383d656433aSmrgSmcDeleteProperties(SmcConn smcConn, int numProps, char **propNames) 384126a8a12Smrg{ 385126a8a12Smrg IceConn iceConn = smcConn->iceConn; 386126a8a12Smrg smDeletePropertiesMsg *pMsg; 387126a8a12Smrg char *pData; 388126a8a12Smrg int extra, i; 389126a8a12Smrg 390126a8a12Smrg extra = 8; 391126a8a12Smrg 392126a8a12Smrg for (i = 0; i < numProps; i++) 393126a8a12Smrg extra += ARRAY8_BYTES (strlen (propNames[i])); 394126a8a12Smrg 395126a8a12Smrg IceGetHeaderExtra (iceConn, _SmcOpcode, SM_DeleteProperties, 396126a8a12Smrg SIZEOF (smDeletePropertiesMsg), WORD64COUNT (extra), 397126a8a12Smrg smDeletePropertiesMsg, pMsg, pData); 398126a8a12Smrg 399126a8a12Smrg STORE_CARD32 (pData, numProps); 400126a8a12Smrg pData += 4; 401126a8a12Smrg 402126a8a12Smrg for (i = 0; i < numProps; i++) 4033c15da26Smrg STORE_ARRAY8 (pData, strlen (propNames[i]), propNames[i]); 404126a8a12Smrg 405126a8a12Smrg IceFlush (iceConn); 406126a8a12Smrg} 407126a8a12Smrg 408126a8a12Smrg 409126a8a12Smrg 410126a8a12SmrgStatus 411d656433aSmrgSmcGetProperties(SmcConn smcConn, SmcPropReplyProc propReplyProc, 412d656433aSmrg SmPointer clientData) 413126a8a12Smrg{ 414126a8a12Smrg IceConn iceConn = smcConn->iceConn; 415126a8a12Smrg _SmcPropReplyWait *wait, *ptr; 416126a8a12Smrg 4173c15da26Smrg if ((wait = malloc (sizeof (_SmcPropReplyWait))) == NULL) 418126a8a12Smrg { 419126a8a12Smrg return (0); 420126a8a12Smrg } 421126a8a12Smrg 422126a8a12Smrg wait->prop_reply_proc = propReplyProc; 423126a8a12Smrg wait->client_data = clientData; 424126a8a12Smrg wait->next = NULL; 425126a8a12Smrg 426126a8a12Smrg ptr = smcConn->prop_reply_waits; 427126a8a12Smrg while (ptr && ptr->next) 428126a8a12Smrg ptr = ptr->next; 429126a8a12Smrg 430126a8a12Smrg if (ptr == NULL) 431126a8a12Smrg smcConn->prop_reply_waits = wait; 432126a8a12Smrg else 433126a8a12Smrg ptr->next = wait; 434126a8a12Smrg 435126a8a12Smrg IceSimpleMessage (iceConn, _SmcOpcode, SM_GetProperties); 436126a8a12Smrg IceFlush (iceConn); 437126a8a12Smrg 438126a8a12Smrg return (1); 439126a8a12Smrg} 440126a8a12Smrg 441126a8a12Smrg 442126a8a12Smrg 443126a8a12SmrgStatus 444d656433aSmrgSmcInteractRequest(SmcConn smcConn, int dialogType, 445d656433aSmrg SmcInteractProc interactProc, SmPointer clientData) 446126a8a12Smrg{ 447126a8a12Smrg IceConn iceConn = smcConn->iceConn; 448126a8a12Smrg smInteractRequestMsg *pMsg; 449126a8a12Smrg _SmcInteractWait *wait, *ptr; 450126a8a12Smrg 4513c15da26Smrg if ((wait = malloc (sizeof (_SmcInteractWait))) == NULL) 452126a8a12Smrg { 453126a8a12Smrg return (0); 454126a8a12Smrg } 455126a8a12Smrg 456126a8a12Smrg wait->interact_proc = interactProc; 457126a8a12Smrg wait->client_data = clientData; 458126a8a12Smrg wait->next = NULL; 459126a8a12Smrg 460126a8a12Smrg ptr = smcConn->interact_waits; 461126a8a12Smrg while (ptr && ptr->next) 462126a8a12Smrg ptr = ptr->next; 463126a8a12Smrg 464126a8a12Smrg if (ptr == NULL) 465126a8a12Smrg smcConn->interact_waits = wait; 466126a8a12Smrg else 467126a8a12Smrg ptr->next = wait; 468126a8a12Smrg 469126a8a12Smrg IceGetHeader (iceConn, _SmcOpcode, SM_InteractRequest, 470126a8a12Smrg SIZEOF (smInteractRequestMsg), smInteractRequestMsg, pMsg); 471126a8a12Smrg 472126a8a12Smrg pMsg->dialogType = dialogType; 473126a8a12Smrg 474126a8a12Smrg IceFlush (iceConn); 475126a8a12Smrg 476126a8a12Smrg return (1); 477126a8a12Smrg} 478126a8a12Smrg 479126a8a12Smrg 480126a8a12Smrg 481126a8a12Smrgvoid 482d656433aSmrgSmcInteractDone(SmcConn smcConn, Bool cancelShutdown) 483126a8a12Smrg{ 484126a8a12Smrg IceConn iceConn = smcConn->iceConn; 485126a8a12Smrg smInteractDoneMsg *pMsg; 486126a8a12Smrg 487126a8a12Smrg IceGetHeader (iceConn, _SmcOpcode, SM_InteractDone, 488126a8a12Smrg SIZEOF (smInteractDoneMsg), smInteractDoneMsg, pMsg); 489126a8a12Smrg 490126a8a12Smrg pMsg->cancelShutdown = cancelShutdown; 491126a8a12Smrg 492126a8a12Smrg IceFlush (iceConn); 493126a8a12Smrg} 494126a8a12Smrg 495126a8a12Smrg 496126a8a12Smrg 497126a8a12Smrgvoid 498d656433aSmrgSmcRequestSaveYourself(SmcConn smcConn, int saveType, Bool shutdown, 499d656433aSmrg int interactStyle, Bool fast, Bool global) 500126a8a12Smrg{ 501126a8a12Smrg IceConn iceConn = smcConn->iceConn; 502126a8a12Smrg smSaveYourselfRequestMsg *pMsg; 503126a8a12Smrg 504126a8a12Smrg IceGetHeader (iceConn, _SmcOpcode, SM_SaveYourselfRequest, 505126a8a12Smrg SIZEOF (smSaveYourselfRequestMsg), smSaveYourselfRequestMsg, pMsg); 506126a8a12Smrg 507126a8a12Smrg pMsg->saveType = saveType; 508126a8a12Smrg pMsg->shutdown = shutdown; 509126a8a12Smrg pMsg->interactStyle = interactStyle; 510126a8a12Smrg pMsg->fast = fast; 511126a8a12Smrg pMsg->global = global; 512126a8a12Smrg 513126a8a12Smrg IceFlush (iceConn); 514126a8a12Smrg} 515126a8a12Smrg 516126a8a12Smrg 517126a8a12Smrg 518126a8a12SmrgStatus 519d656433aSmrgSmcRequestSaveYourselfPhase2(SmcConn smcConn, 520d656433aSmrg SmcSaveYourselfPhase2Proc saveYourselfPhase2Proc, 521d656433aSmrg SmPointer clientData) 522126a8a12Smrg{ 523126a8a12Smrg IceConn iceConn = smcConn->iceConn; 524126a8a12Smrg _SmcPhase2Wait *wait; 525126a8a12Smrg 526126a8a12Smrg if (smcConn->phase2_wait) 527126a8a12Smrg wait = smcConn->phase2_wait; 528126a8a12Smrg else 529126a8a12Smrg { 5303c15da26Smrg if ((wait = malloc (sizeof (_SmcPhase2Wait))) == NULL) 531126a8a12Smrg { 532126a8a12Smrg return (0); 533126a8a12Smrg } 534126a8a12Smrg } 535126a8a12Smrg 536126a8a12Smrg wait->phase2_proc = saveYourselfPhase2Proc; 537126a8a12Smrg wait->client_data = clientData; 538126a8a12Smrg 539126a8a12Smrg smcConn->phase2_wait = wait; 540126a8a12Smrg 541126a8a12Smrg IceSimpleMessage (iceConn, _SmcOpcode, SM_SaveYourselfPhase2Request); 542126a8a12Smrg IceFlush (iceConn); 543126a8a12Smrg 544126a8a12Smrg return (1); 545126a8a12Smrg} 546126a8a12Smrg 547126a8a12Smrg 548126a8a12Smrg 549126a8a12Smrgvoid 550d656433aSmrgSmcSaveYourselfDone(SmcConn smcConn, Bool success) 551126a8a12Smrg{ 552126a8a12Smrg IceConn iceConn = smcConn->iceConn; 553126a8a12Smrg smSaveYourselfDoneMsg *pMsg; 554126a8a12Smrg 555126a8a12Smrg IceGetHeader (iceConn, _SmcOpcode, SM_SaveYourselfDone, 556126a8a12Smrg SIZEOF (smSaveYourselfDoneMsg), smSaveYourselfDoneMsg, pMsg); 557126a8a12Smrg 558126a8a12Smrg pMsg->success = success; 559126a8a12Smrg 560126a8a12Smrg IceFlush (iceConn); 561126a8a12Smrg} 562126a8a12Smrg 563126a8a12Smrg 564126a8a12Smrg 565126a8a12Smrgstatic void 566d656433aSmrgset_callbacks(SmcConn smcConn, unsigned long mask, SmcCallbacks *callbacks) 567126a8a12Smrg{ 568126a8a12Smrg if (mask & SmcSaveYourselfProcMask) 569126a8a12Smrg { 570126a8a12Smrg smcConn->callbacks.save_yourself.callback = 571126a8a12Smrg callbacks->save_yourself.callback; 572126a8a12Smrg smcConn->callbacks.save_yourself.client_data = 573126a8a12Smrg callbacks->save_yourself.client_data; 574126a8a12Smrg } 575126a8a12Smrg 576126a8a12Smrg if (mask & SmcDieProcMask) 577126a8a12Smrg { 578126a8a12Smrg smcConn->callbacks.die.callback = callbacks->die.callback; 579126a8a12Smrg smcConn->callbacks.die.client_data = callbacks->die.client_data; 580126a8a12Smrg } 581126a8a12Smrg 582126a8a12Smrg if (mask & SmcSaveCompleteProcMask) 583126a8a12Smrg { 584126a8a12Smrg smcConn->callbacks.save_complete.callback = 585126a8a12Smrg callbacks->save_complete.callback; 586126a8a12Smrg smcConn->callbacks.save_complete.client_data = 587126a8a12Smrg callbacks->save_complete.client_data; 588126a8a12Smrg } 589126a8a12Smrg 590126a8a12Smrg if (mask & SmcShutdownCancelledProcMask) 591126a8a12Smrg { 592126a8a12Smrg smcConn->callbacks.shutdown_cancelled.callback = 593126a8a12Smrg callbacks->shutdown_cancelled.callback; 594126a8a12Smrg smcConn->callbacks.shutdown_cancelled.client_data = 595126a8a12Smrg callbacks->shutdown_cancelled.client_data; 596126a8a12Smrg } 597126a8a12Smrg} 598