protosetup.c revision 266e564d
1266e564dSmrg/* $Xorg: protosetup.c,v 1.4 2001/02/09 02:03:26 xorgcvs Exp $ */ 2266e564dSmrg/****************************************************************************** 3266e564dSmrg 4266e564dSmrg 5266e564dSmrgCopyright 1993, 1998 The Open Group 6266e564dSmrg 7266e564dSmrgPermission to use, copy, modify, distribute, and sell this software and its 8266e564dSmrgdocumentation for any purpose is hereby granted without fee, provided that 9266e564dSmrgthe above copyright notice appear in all copies and that both that 10266e564dSmrgcopyright notice and this permission notice appear in supporting 11266e564dSmrgdocumentation. 12266e564dSmrg 13266e564dSmrgThe above copyright notice and this permission notice shall be included in 14266e564dSmrgall copies or substantial portions of the Software. 15266e564dSmrg 16266e564dSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17266e564dSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18266e564dSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19266e564dSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 20266e564dSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21266e564dSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22266e564dSmrg 23266e564dSmrgExcept as contained in this notice, the name of The Open Group shall not be 24266e564dSmrgused in advertising or otherwise to promote the sale, use or other dealings 25266e564dSmrgin this Software without prior written authorization from The Open Group. 26266e564dSmrg 27266e564dSmrgAuthor: Ralph Mor, X Consortium 28266e564dSmrg******************************************************************************/ 29266e564dSmrg/* $XFree86: xc/lib/ICE/protosetup.c,v 1.2 2001/10/28 03:32:28 tsi Exp $ */ 30266e564dSmrg 31266e564dSmrg#ifdef HAVE_CONFIG_H 32266e564dSmrg#include <config.h> 33266e564dSmrg#endif 34266e564dSmrg#include <X11/ICE/ICElib.h> 35266e564dSmrg#include "ICElibint.h" 36266e564dSmrg 37266e564dSmrg 38266e564dSmrgIceProtocolSetupStatus 39266e564dSmrgIceProtocolSetup (iceConn, myOpcode, clientData, mustAuthenticate, 40266e564dSmrg majorVersionRet, minorVersionRet, vendorRet, releaseRet, 41266e564dSmrg errorLength, errorStringRet) 42266e564dSmrg 43266e564dSmrgIceConn iceConn; 44266e564dSmrgint myOpcode; 45266e564dSmrgIcePointer clientData; 46266e564dSmrgBool mustAuthenticate; 47266e564dSmrgint *majorVersionRet; 48266e564dSmrgint *minorVersionRet; 49266e564dSmrgchar **vendorRet; 50266e564dSmrgchar **releaseRet; 51266e564dSmrgint errorLength; 52266e564dSmrgchar *errorStringRet; 53266e564dSmrg 54266e564dSmrg{ 55266e564dSmrg iceProtocolSetupMsg *pMsg; 56266e564dSmrg char *pData; 57266e564dSmrg _IceProtocol *myProtocol; 58266e564dSmrg int extra; 59266e564dSmrg Bool gotReply, ioErrorOccured; 60266e564dSmrg int accepted, i; 61266e564dSmrg int hisOpcode; 62266e564dSmrg unsigned long setup_sequence; 63266e564dSmrg IceReplyWaitInfo replyWait; 64266e564dSmrg _IceReply reply; 65266e564dSmrg IcePoVersionRec *versionRec = NULL; 66266e564dSmrg int authCount; 67266e564dSmrg int *authIndices; 68266e564dSmrg 69266e564dSmrg if (errorStringRet && errorLength > 0) 70266e564dSmrg *errorStringRet = '\0'; 71266e564dSmrg 72266e564dSmrg *majorVersionRet = 0; 73266e564dSmrg *minorVersionRet = 0; 74266e564dSmrg *vendorRet = NULL; 75266e564dSmrg *releaseRet = NULL; 76266e564dSmrg 77266e564dSmrg if (myOpcode < 1 || myOpcode > _IceLastMajorOpcode) 78266e564dSmrg { 79266e564dSmrg strncpy (errorStringRet, "myOpcode out of range", errorLength); 80266e564dSmrg return (IceProtocolSetupFailure); 81266e564dSmrg } 82266e564dSmrg 83266e564dSmrg myProtocol = &_IceProtocols[myOpcode - 1]; 84266e564dSmrg 85266e564dSmrg if (myProtocol->orig_client == NULL) 86266e564dSmrg { 87266e564dSmrg strncpy (errorStringRet, 88266e564dSmrg "IceRegisterForProtocolSetup was not called", errorLength); 89266e564dSmrg return (IceProtocolSetupFailure); 90266e564dSmrg } 91266e564dSmrg 92266e564dSmrg 93266e564dSmrg /* 94266e564dSmrg * Make sure this protocol hasn't been activated already. 95266e564dSmrg */ 96266e564dSmrg 97266e564dSmrg if (iceConn->process_msg_info) 98266e564dSmrg { 99266e564dSmrg for (i = iceConn->his_min_opcode; i <= iceConn->his_max_opcode; i++) 100266e564dSmrg { 101266e564dSmrg if (iceConn->process_msg_info[ 102266e564dSmrg i - iceConn->his_min_opcode].in_use && 103266e564dSmrg iceConn->process_msg_info[ 104266e564dSmrg i - iceConn->his_min_opcode ].my_opcode == myOpcode) 105266e564dSmrg break; 106266e564dSmrg } 107266e564dSmrg 108266e564dSmrg if (i <= iceConn->his_max_opcode) 109266e564dSmrg { 110266e564dSmrg return (IceProtocolAlreadyActive); 111266e564dSmrg } 112266e564dSmrg } 113266e564dSmrg 114266e564dSmrg /* 115266e564dSmrg * Generate the message. 116266e564dSmrg */ 117266e564dSmrg 118266e564dSmrg if (myProtocol->orig_client->auth_count > 0) 119266e564dSmrg { 120266e564dSmrg authIndices = (int *) malloc ( 121266e564dSmrg myProtocol->orig_client->auth_count * sizeof (int)); 122266e564dSmrg 123266e564dSmrg _IceGetPoValidAuthIndices (myProtocol->protocol_name, 124266e564dSmrg iceConn->connection_string, 125266e564dSmrg myProtocol->orig_client->auth_count, 126266e564dSmrg myProtocol->orig_client->auth_names, 127266e564dSmrg &authCount, authIndices); 128266e564dSmrg 129266e564dSmrg } 130266e564dSmrg else 131266e564dSmrg { 132266e564dSmrg authCount = 0; 133266e564dSmrg authIndices = NULL; 134266e564dSmrg } 135266e564dSmrg 136266e564dSmrg extra = STRING_BYTES (myProtocol->protocol_name) + 137266e564dSmrg STRING_BYTES (myProtocol->orig_client->vendor) + 138266e564dSmrg STRING_BYTES (myProtocol->orig_client->release); 139266e564dSmrg 140266e564dSmrg for (i = 0; i < authCount; i++) 141266e564dSmrg { 142266e564dSmrg extra += STRING_BYTES (myProtocol->orig_client->auth_names[ 143266e564dSmrg authIndices[i]]); 144266e564dSmrg } 145266e564dSmrg 146266e564dSmrg extra += (myProtocol->orig_client->version_count * 4); 147266e564dSmrg 148266e564dSmrg IceGetHeaderExtra (iceConn, 0, ICE_ProtocolSetup, 149266e564dSmrg SIZEOF (iceProtocolSetupMsg), WORD64COUNT (extra), 150266e564dSmrg iceProtocolSetupMsg, pMsg, pData); 151266e564dSmrg 152266e564dSmrg setup_sequence = iceConn->send_sequence; 153266e564dSmrg 154266e564dSmrg pMsg->protocolOpcode = myOpcode; 155266e564dSmrg pMsg->versionCount = myProtocol->orig_client->version_count; 156266e564dSmrg pMsg->authCount = authCount; 157266e564dSmrg pMsg->mustAuthenticate = mustAuthenticate; 158266e564dSmrg 159266e564dSmrg STORE_STRING (pData, myProtocol->protocol_name); 160266e564dSmrg STORE_STRING (pData, myProtocol->orig_client->vendor); 161266e564dSmrg STORE_STRING (pData, myProtocol->orig_client->release); 162266e564dSmrg 163266e564dSmrg for (i = 0; i < authCount; i++) 164266e564dSmrg { 165266e564dSmrg STORE_STRING (pData, myProtocol->orig_client->auth_names[ 166266e564dSmrg authIndices[i]]); 167266e564dSmrg } 168266e564dSmrg 169266e564dSmrg for (i = 0; i < myProtocol->orig_client->version_count; i++) 170266e564dSmrg { 171266e564dSmrg STORE_CARD16 (pData, 172266e564dSmrg myProtocol->orig_client->version_recs[i].major_version); 173266e564dSmrg STORE_CARD16 (pData, 174266e564dSmrg myProtocol->orig_client->version_recs[i].minor_version); 175266e564dSmrg } 176266e564dSmrg 177266e564dSmrg IceFlush (iceConn); 178266e564dSmrg 179266e564dSmrg 180266e564dSmrg /* 181266e564dSmrg * Process messages until we get a Protocol Reply. 182266e564dSmrg */ 183266e564dSmrg 184266e564dSmrg replyWait.sequence_of_request = setup_sequence; 185266e564dSmrg replyWait.major_opcode_of_request = 0; 186266e564dSmrg replyWait.minor_opcode_of_request = ICE_ProtocolSetup; 187266e564dSmrg replyWait.reply = (IcePointer) &reply; 188266e564dSmrg 189266e564dSmrg iceConn->protosetup_to_you = (_IceProtoSetupToYouInfo *) malloc ( 190266e564dSmrg sizeof (_IceProtoSetupToYouInfo)); 191266e564dSmrg iceConn->protosetup_to_you->my_opcode = myOpcode; 192266e564dSmrg iceConn->protosetup_to_you->my_auth_count = authCount; 193266e564dSmrg iceConn->protosetup_to_you->auth_active = 0; 194266e564dSmrg iceConn->protosetup_to_you->my_auth_indices = authIndices; 195266e564dSmrg 196266e564dSmrg gotReply = False; 197266e564dSmrg ioErrorOccured = False; 198266e564dSmrg accepted = 0; 199266e564dSmrg 200266e564dSmrg while (!gotReply && !ioErrorOccured) 201266e564dSmrg { 202266e564dSmrg ioErrorOccured = (IceProcessMessages ( 203266e564dSmrg iceConn, &replyWait, &gotReply) == IceProcessMessagesIOError); 204266e564dSmrg 205266e564dSmrg if (ioErrorOccured) 206266e564dSmrg { 207266e564dSmrg strncpy (errorStringRet, 208266e564dSmrg "IO error occured doing Protocol Setup on connection", 209266e564dSmrg errorLength); 210266e564dSmrg return (IceProtocolSetupIOError); 211266e564dSmrg } 212266e564dSmrg else if (gotReply) 213266e564dSmrg { 214266e564dSmrg if (reply.type == ICE_PROTOCOL_REPLY) 215266e564dSmrg { 216266e564dSmrg if (reply.protocol_reply.version_index >= 217266e564dSmrg myProtocol->orig_client->version_count) 218266e564dSmrg { 219266e564dSmrg strncpy (errorStringRet, 220266e564dSmrg "Got a bad version index in the Protocol Reply", 221266e564dSmrg errorLength); 222266e564dSmrg 223266e564dSmrg free (reply.protocol_reply.vendor); 224266e564dSmrg free (reply.protocol_reply.release); 225266e564dSmrg } 226266e564dSmrg else 227266e564dSmrg { 228266e564dSmrg versionRec = &(myProtocol->orig_client->version_recs[ 229266e564dSmrg reply.protocol_reply.version_index]); 230266e564dSmrg 231266e564dSmrg accepted = 1; 232266e564dSmrg } 233266e564dSmrg } 234266e564dSmrg else /* reply.type == ICE_PROTOCOL_ERROR */ 235266e564dSmrg { 236266e564dSmrg /* Protocol Setup failed */ 237266e564dSmrg 238266e564dSmrg strncpy (errorStringRet, reply.protocol_error.error_message, 239266e564dSmrg errorLength); 240266e564dSmrg 241266e564dSmrg free (reply.protocol_error.error_message); 242266e564dSmrg } 243266e564dSmrg 244266e564dSmrg if (iceConn->protosetup_to_you->my_auth_indices) 245266e564dSmrg free ((char *) iceConn->protosetup_to_you->my_auth_indices); 246266e564dSmrg free ((char *) iceConn->protosetup_to_you); 247266e564dSmrg iceConn->protosetup_to_you = NULL; 248266e564dSmrg } 249266e564dSmrg } 250266e564dSmrg 251266e564dSmrg if (accepted) 252266e564dSmrg { 253266e564dSmrg _IceProcessMsgInfo *process_msg_info; 254266e564dSmrg 255266e564dSmrg *majorVersionRet = versionRec->major_version; 256266e564dSmrg *minorVersionRet = versionRec->minor_version; 257266e564dSmrg *vendorRet = reply.protocol_reply.vendor; 258266e564dSmrg *releaseRet = reply.protocol_reply.release; 259266e564dSmrg 260266e564dSmrg 261266e564dSmrg /* 262266e564dSmrg * Increase the reference count for the number of active protocols. 263266e564dSmrg */ 264266e564dSmrg 265266e564dSmrg iceConn->proto_ref_count++; 266266e564dSmrg 267266e564dSmrg 268266e564dSmrg /* 269266e564dSmrg * We may be using a different major opcode for this protocol 270266e564dSmrg * than the other client. Whenever we get a message, we must 271266e564dSmrg * map to our own major opcode. 272266e564dSmrg */ 273266e564dSmrg 274266e564dSmrg hisOpcode = reply.protocol_reply.major_opcode; 275266e564dSmrg 276266e564dSmrg _IceAddOpcodeMapping (iceConn, hisOpcode, myOpcode); 277266e564dSmrg 278266e564dSmrg process_msg_info = &iceConn->process_msg_info[hisOpcode - 279266e564dSmrg iceConn->his_min_opcode]; 280266e564dSmrg 281266e564dSmrg process_msg_info->client_data = clientData; 282266e564dSmrg process_msg_info->accept_flag = 0; 283266e564dSmrg 284266e564dSmrg process_msg_info->process_msg_proc.orig_client = 285266e564dSmrg versionRec->process_msg_proc; 286266e564dSmrg 287266e564dSmrg return (IceProtocolSetupSuccess); 288266e564dSmrg } 289266e564dSmrg else 290266e564dSmrg { 291266e564dSmrg return (IceProtocolSetupFailure); 292266e564dSmrg } 293266e564dSmrg} 294