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