sm_manager.c revision d656433a
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 45 46 47static Status 48_SmsProtocolSetupProc (IceConn iceConn, 49 int majorVersion, 50 int minorVersion, 51 char *vendor, 52 char *release, 53 IcePointer *clientDataRet, 54 char **failureReasonRet) 55{ 56 SmsConn smsConn; 57 unsigned long mask; 58 Status status; 59 60 /* 61 * vendor/release are undefined for ProtocolSetup in XSMP. 62 */ 63 64 if (vendor) 65 free (vendor); 66 if (release) 67 free (release); 68 69 70 /* 71 * Allocate new SmsConn. 72 */ 73 74 if ((smsConn = (SmsConn) malloc (sizeof (struct _SmsConn))) == NULL) 75 { 76 const char *str = "Memory allocation failed"; 77 78 if ((*failureReasonRet = (char *) malloc (strlen (str) + 1)) != NULL) 79 strcpy (*failureReasonRet, str); 80 81 return (0); 82 } 83 84 smsConn->iceConn = iceConn; 85 smsConn->proto_major_version = majorVersion; 86 smsConn->proto_minor_version = minorVersion; 87 smsConn->client_id = NULL; 88 89 smsConn->save_yourself_in_progress = False; 90 smsConn->interaction_allowed = SmInteractStyleNone; 91 smsConn->can_cancel_shutdown = False; 92 smsConn->interact_in_progress = False; 93 94 *clientDataRet = (IcePointer) smsConn; 95 96 97 /* 98 * Now give the session manager the new smsConn and get back the 99 * callbacks to invoke when messages arrive from the client. 100 * 101 * In the future, we can use the mask return value to check 102 * if the SM is expecting an older rev of SMlib. 103 */ 104 105 bzero ((char *) &smsConn->callbacks, sizeof (SmsCallbacks)); 106 107 status = (*_SmsNewClientProc) (smsConn, _SmsNewClientData, 108 &mask, &smsConn->callbacks, failureReasonRet); 109 110 return (status); 111} 112 113 114 115 116Status 117SmsInitialize(char *vendor, char *release, SmsNewClientProc newClientProc, 118 SmPointer managerData, IceHostBasedAuthProc hostBasedAuthProc, 119 int errorLength, char *errorStringRet) 120{ 121 const char *auth_names[] = {"MIT-MAGIC-COOKIE-1"}; 122 IcePaAuthProc auth_procs[] = {_IcePaMagicCookie1Proc}; 123 int auth_count = 1; 124 125 IcePaVersionRec versions[] = { 126 {SmProtoMajor, SmProtoMinor, _SmsProcessMessage} 127 }; 128 int version_count = 1; 129 130 if (errorStringRet && errorLength > 0) 131 *errorStringRet = '\0'; 132 133 if (!newClientProc) 134 { 135 if (errorStringRet && errorLength > 0) { 136 strncpy (errorStringRet, 137 "The SmsNewClientProc callback can't be NULL", 138 errorLength); 139 errorStringRet[errorLength - 1] = '\0'; 140 } 141 142 return (0); 143 } 144 145 if (!_SmsOpcode) 146 { 147 148 if ((_SmsOpcode = IceRegisterForProtocolReply ("XSMP", 149 vendor, release, version_count, versions, 150 auth_count, auth_names, auth_procs, hostBasedAuthProc, 151 _SmsProtocolSetupProc, 152 NULL, /* IceProtocolActivateProc - we don't care about 153 when the Protocol Reply is sent, because the 154 session manager can not immediately send a 155 message - it must wait for RegisterClient. */ 156 NULL /* IceIOErrorProc */ 157 )) < 0) 158 { 159 if (errorStringRet && errorLength > 0) { 160 strncpy (errorStringRet, 161 "Could not register XSMP protocol with ICE", 162 errorLength); 163 errorStringRet[errorLength - 1] = '\0'; 164 } 165 return (0); 166 } 167 } 168 169 _SmsNewClientProc = newClientProc; 170 _SmsNewClientData = managerData; 171 172 return (1); 173} 174 175 176 177char * 178SmsClientHostName(SmsConn smsConn) 179{ 180 return (IceGetPeerName (smsConn->iceConn)); 181} 182 183 184 185Status 186SmsRegisterClientReply(SmsConn smsConn, char *clientId) 187{ 188 IceConn iceConn = smsConn->iceConn; 189 int extra; 190 smRegisterClientReplyMsg *pMsg; 191 char *pData; 192 193 if ((smsConn->client_id = (char *) malloc (strlen (clientId) + 1)) == NULL) 194 { 195 return (0); 196 } 197 198 strcpy (smsConn->client_id, clientId); 199 200 extra = ARRAY8_BYTES (strlen (clientId)); 201 202 IceGetHeaderExtra (iceConn, _SmsOpcode, SM_RegisterClientReply, 203 SIZEOF (smRegisterClientReplyMsg), WORD64COUNT (extra), 204 smRegisterClientReplyMsg, pMsg, pData); 205 206 STORE_ARRAY8 (pData, strlen (clientId), clientId); 207 208 IceFlush (iceConn); 209 210 return (1); 211} 212 213 214 215void 216SmsSaveYourself(SmsConn smsConn, int saveType, Bool shutdown, 217 int interactStyle, Bool fast) 218{ 219 IceConn iceConn = smsConn->iceConn; 220 smSaveYourselfMsg *pMsg; 221 222 IceGetHeader (iceConn, _SmsOpcode, SM_SaveYourself, 223 SIZEOF (smSaveYourselfMsg), smSaveYourselfMsg, pMsg); 224 225 pMsg->saveType = saveType; 226 pMsg->shutdown = shutdown; 227 pMsg->interactStyle = interactStyle; 228 pMsg->fast = fast; 229 230 IceFlush (iceConn); 231 232 smsConn->save_yourself_in_progress = True; 233 234 if (interactStyle == SmInteractStyleNone || 235 interactStyle == SmInteractStyleErrors || 236 interactStyle == SmInteractStyleAny) 237 { 238 smsConn->interaction_allowed = interactStyle; 239 } 240 else 241 { 242 smsConn->interaction_allowed = SmInteractStyleNone; 243 } 244 245 smsConn->can_cancel_shutdown = shutdown && 246 (interactStyle == SmInteractStyleAny || 247 interactStyle == SmInteractStyleErrors); 248} 249 250 251 252void 253SmsSaveYourselfPhase2(SmsConn smsConn) 254{ 255 IceConn iceConn = smsConn->iceConn; 256 257 IceSimpleMessage (iceConn, _SmsOpcode, SM_SaveYourselfPhase2); 258 IceFlush (iceConn); 259} 260 261 262 263void 264SmsInteract(SmsConn smsConn) 265{ 266 IceConn iceConn = smsConn->iceConn; 267 268 IceSimpleMessage (iceConn, _SmsOpcode, SM_Interact); 269 IceFlush (iceConn); 270 271 smsConn->interact_in_progress = True; 272} 273 274 275 276void 277SmsDie(SmsConn smsConn) 278{ 279 IceConn iceConn = smsConn->iceConn; 280 281 IceSimpleMessage (iceConn, _SmsOpcode, SM_Die); 282 IceFlush (iceConn); 283} 284 285 286 287void 288SmsSaveComplete(SmsConn smsConn) 289{ 290 IceConn iceConn = smsConn->iceConn; 291 292 IceSimpleMessage (iceConn, _SmsOpcode, SM_SaveComplete); 293 IceFlush (iceConn); 294} 295 296 297 298void 299SmsShutdownCancelled(SmsConn smsConn) 300{ 301 IceConn iceConn = smsConn->iceConn; 302 303 IceSimpleMessage (iceConn, _SmsOpcode, SM_ShutdownCancelled); 304 IceFlush (iceConn); 305 306 smsConn->can_cancel_shutdown = False; 307} 308 309 310 311void 312SmsReturnProperties(SmsConn smsConn, int numProps, SmProp **props) 313{ 314 IceConn iceConn = smsConn->iceConn; 315 int bytes; 316 smPropertiesReplyMsg *pMsg; 317 char *pBuf; 318 char *pStart; 319 320 IceGetHeader (iceConn, _SmsOpcode, SM_PropertiesReply, 321 SIZEOF (smPropertiesReplyMsg), smPropertiesReplyMsg, pMsg); 322 323 LISTOF_PROP_BYTES (numProps, props, bytes); 324 pMsg->length += WORD64COUNT (bytes); 325 326 pBuf = pStart = IceAllocScratch (iceConn, bytes); 327 328 STORE_LISTOF_PROPERTY (pBuf, numProps, props); 329 330 IceWriteData (iceConn, bytes, pStart); 331 IceFlush (iceConn); 332} 333 334 335 336void 337SmsCleanUp(SmsConn smsConn) 338{ 339 IceProtocolShutdown (smsConn->iceConn, _SmsOpcode); 340 341 if (smsConn->client_id) 342 free (smsConn->client_id); 343 344 free ((char *) smsConn); 345} 346