sm_manager.c revision 126a8a12
1/* $XdotOrg: $ */ 2/* $Xorg: sm_manager.c,v 1.4 2001/02/09 02:03:30 xorgcvs Exp $ */ 3 4/* 5 6Copyright 1993, 1998 The Open Group 7 8Permission to use, copy, modify, distribute, and sell this software and its 9documentation for any purpose is hereby granted without fee, provided that 10the above copyright notice appear in all copies and that both that 11copyright notice and this permission notice appear in supporting 12documentation. 13 14The above copyright notice and this permission notice shall be included in 15all copies or substantial portions of the Software. 16 17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 24Except as contained in this notice, the name of The Open Group shall not be 25used in advertising or otherwise to promote the sale, use or other dealings 26in this Software without prior written authorization from The Open Group. 27 28*/ 29 30/* 31 * Author: Ralph Mor, X Consortium 32 */ 33 34#ifdef HAVE_CONFIG_H 35#include <config.h> 36#endif 37#include <X11/SM/SMlib.h> 38#include "SMlibint.h" 39#include <X11/Xtrans/Xtrans.h> 40 41#ifdef __UNIXWARE__ 42#undef shutdown 43#endif 44 45extern IcePaAuthStatus _IcePaMagicCookie1Proc (); 46extern void _SmsProcessMessage (); 47 48 49 50static Status 51_SmsProtocolSetupProc (IceConn iceConn, 52 int majorVersion, 53 int minorVersion, 54 char *vendor, 55 char *release, 56 IcePointer *clientDataRet, 57 char **failureReasonRet) 58{ 59 SmsConn smsConn; 60 unsigned long mask; 61 Status status; 62 63 /* 64 * vendor/release are undefined for ProtocolSetup in XSMP. 65 */ 66 67 if (vendor) 68 free (vendor); 69 if (release) 70 free (release); 71 72 73 /* 74 * Allocate new SmsConn. 75 */ 76 77 if ((smsConn = (SmsConn) malloc (sizeof (struct _SmsConn))) == NULL) 78 { 79 const char *str = "Memory allocation failed"; 80 81 if ((*failureReasonRet = (char *) malloc (strlen (str) + 1)) != NULL) 82 strcpy (*failureReasonRet, str); 83 84 return (0); 85 } 86 87 smsConn->iceConn = iceConn; 88 smsConn->proto_major_version = majorVersion; 89 smsConn->proto_minor_version = minorVersion; 90 smsConn->client_id = NULL; 91 92 smsConn->save_yourself_in_progress = False; 93 smsConn->interaction_allowed = SmInteractStyleNone; 94 smsConn->can_cancel_shutdown = False; 95 smsConn->interact_in_progress = False; 96 97 *clientDataRet = (IcePointer) smsConn; 98 99 100 /* 101 * Now give the session manager the new smsConn and get back the 102 * callbacks to invoke when messages arrive from the client. 103 * 104 * In the future, we can use the mask return value to check 105 * if the SM is expecting an older rev of SMlib. 106 */ 107 108 bzero ((char *) &smsConn->callbacks, sizeof (SmsCallbacks)); 109 110 status = (*_SmsNewClientProc) (smsConn, _SmsNewClientData, 111 &mask, &smsConn->callbacks, failureReasonRet); 112 113 return (status); 114} 115 116 117 118 119Status 120SmsInitialize (vendor, release, newClientProc, managerData, 121 hostBasedAuthProc, errorLength, errorStringRet) 122 123char *vendor; 124char *release; 125SmsNewClientProc newClientProc; 126SmPointer managerData; 127IceHostBasedAuthProc hostBasedAuthProc; 128int errorLength; 129char *errorStringRet; 130 131{ 132 const char *auth_names[] = {"MIT-MAGIC-COOKIE-1"}; 133 IcePaAuthProc auth_procs[] = {_IcePaMagicCookie1Proc}; 134 int auth_count = 1; 135 136 IcePaVersionRec versions[] = { 137 {SmProtoMajor, SmProtoMinor, _SmsProcessMessage} 138 }; 139 int version_count = 1; 140 141 if (errorStringRet && errorLength > 0) 142 *errorStringRet = '\0'; 143 144 if (!newClientProc) 145 { 146 if (errorStringRet && errorLength > 0) { 147 strncpy (errorStringRet, 148 "The SmsNewClientProc callback can't be NULL", 149 errorLength); 150 errorStringRet[errorLength - 1] = '\0'; 151 } 152 153 return (0); 154 } 155 156 if (!_SmsOpcode) 157 { 158 159 if ((_SmsOpcode = IceRegisterForProtocolReply ("XSMP", 160 vendor, release, version_count, versions, 161 auth_count, auth_names, auth_procs, hostBasedAuthProc, 162 _SmsProtocolSetupProc, 163 NULL, /* IceProtocolActivateProc - we don't care about 164 when the Protocol Reply is sent, because the 165 session manager can not immediately send a 166 message - it must wait for RegisterClient. */ 167 NULL /* IceIOErrorProc */ 168 )) < 0) 169 { 170 if (errorStringRet && errorLength > 0) { 171 strncpy (errorStringRet, 172 "Could not register XSMP protocol with ICE", 173 errorLength); 174 errorStringRet[errorLength - 1] = '\0'; 175 } 176 return (0); 177 } 178 } 179 180 _SmsNewClientProc = newClientProc; 181 _SmsNewClientData = managerData; 182 183 return (1); 184} 185 186 187 188char * 189SmsClientHostName (smsConn) 190 191SmsConn smsConn; 192 193{ 194 return (IceGetPeerName (smsConn->iceConn)); 195} 196 197 198 199Status 200SmsRegisterClientReply (smsConn, clientId) 201 202SmsConn smsConn; 203char *clientId; 204 205{ 206 IceConn iceConn = smsConn->iceConn; 207 int extra; 208 smRegisterClientReplyMsg *pMsg; 209 char *pData; 210 211 if ((smsConn->client_id = (char *) malloc (strlen (clientId) + 1)) == NULL) 212 { 213 return (0); 214 } 215 216 strcpy (smsConn->client_id, clientId); 217 218 extra = ARRAY8_BYTES (strlen (clientId)); 219 220 IceGetHeaderExtra (iceConn, _SmsOpcode, SM_RegisterClientReply, 221 SIZEOF (smRegisterClientReplyMsg), WORD64COUNT (extra), 222 smRegisterClientReplyMsg, pMsg, pData); 223 224 STORE_ARRAY8 (pData, strlen (clientId), clientId); 225 226 IceFlush (iceConn); 227 228 return (1); 229} 230 231 232 233void 234SmsSaveYourself (smsConn, saveType, shutdown, interactStyle, fast) 235 236SmsConn smsConn; 237int saveType; 238Bool shutdown; 239int interactStyle; 240Bool fast; 241 242{ 243 IceConn iceConn = smsConn->iceConn; 244 smSaveYourselfMsg *pMsg; 245 246 IceGetHeader (iceConn, _SmsOpcode, SM_SaveYourself, 247 SIZEOF (smSaveYourselfMsg), smSaveYourselfMsg, pMsg); 248 249 pMsg->saveType = saveType; 250 pMsg->shutdown = shutdown; 251 pMsg->interactStyle = interactStyle; 252 pMsg->fast = fast; 253 254 IceFlush (iceConn); 255 256 smsConn->save_yourself_in_progress = True; 257 258 if (interactStyle == SmInteractStyleNone || 259 interactStyle == SmInteractStyleErrors || 260 interactStyle == SmInteractStyleAny) 261 { 262 smsConn->interaction_allowed = interactStyle; 263 } 264 else 265 { 266 smsConn->interaction_allowed = SmInteractStyleNone; 267 } 268 269 smsConn->can_cancel_shutdown = shutdown && 270 (interactStyle == SmInteractStyleAny || 271 interactStyle == SmInteractStyleErrors); 272} 273 274 275 276void 277SmsSaveYourselfPhase2 (smsConn) 278 279SmsConn smsConn; 280 281{ 282 IceConn iceConn = smsConn->iceConn; 283 284 IceSimpleMessage (iceConn, _SmsOpcode, SM_SaveYourselfPhase2); 285 IceFlush (iceConn); 286} 287 288 289 290void 291SmsInteract (smsConn) 292 293SmsConn smsConn; 294 295{ 296 IceConn iceConn = smsConn->iceConn; 297 298 IceSimpleMessage (iceConn, _SmsOpcode, SM_Interact); 299 IceFlush (iceConn); 300 301 smsConn->interact_in_progress = True; 302} 303 304 305 306void 307SmsDie (smsConn) 308 309SmsConn smsConn; 310 311{ 312 IceConn iceConn = smsConn->iceConn; 313 314 IceSimpleMessage (iceConn, _SmsOpcode, SM_Die); 315 IceFlush (iceConn); 316} 317 318 319 320void 321SmsSaveComplete (smsConn) 322 323SmsConn smsConn; 324 325{ 326 IceConn iceConn = smsConn->iceConn; 327 328 IceSimpleMessage (iceConn, _SmsOpcode, SM_SaveComplete); 329 IceFlush (iceConn); 330} 331 332 333 334void 335SmsShutdownCancelled (smsConn) 336 337SmsConn smsConn; 338 339{ 340 IceConn iceConn = smsConn->iceConn; 341 342 IceSimpleMessage (iceConn, _SmsOpcode, SM_ShutdownCancelled); 343 IceFlush (iceConn); 344 345 smsConn->can_cancel_shutdown = False; 346} 347 348 349 350void 351SmsReturnProperties (smsConn, numProps, props) 352 353SmsConn smsConn; 354int numProps; 355SmProp **props; 356 357{ 358 IceConn iceConn = smsConn->iceConn; 359 int bytes; 360 smPropertiesReplyMsg *pMsg; 361 char *pBuf; 362 char *pStart; 363 364 IceGetHeader (iceConn, _SmsOpcode, SM_PropertiesReply, 365 SIZEOF (smPropertiesReplyMsg), smPropertiesReplyMsg, pMsg); 366 367 LISTOF_PROP_BYTES (numProps, props, bytes); 368 pMsg->length += WORD64COUNT (bytes); 369 370 pBuf = pStart = IceAllocScratch (iceConn, bytes); 371 372 STORE_LISTOF_PROPERTY (pBuf, numProps, props); 373 374 IceWriteData (iceConn, bytes, pStart); 375 IceFlush (iceConn); 376} 377 378 379 380void 381SmsCleanUp (smsConn) 382 383SmsConn smsConn; 384 385{ 386 IceProtocolShutdown (smsConn->iceConn, _SmsOpcode); 387 388 if (smsConn->client_id) 389 free (smsConn->client_id); 390 391 free ((char *) smsConn); 392} 393