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