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