connect.c revision 266e564d
1266e564dSmrg/* $Xorg: connect.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/connect.c,v 3.9 2001/12/14 19:53:35 dawes Exp $ */ 30266e564dSmrg 31266e564dSmrg#ifdef HAVE_CONFIG_H 32266e564dSmrg#include <config.h> 33266e564dSmrg#endif 34266e564dSmrg#include <X11/ICE/ICElib.h> 35266e564dSmrg#include "ICElibint.h" 36266e564dSmrg#include <X11/Xtrans/Xtrans.h> 37266e564dSmrg#include "globals.h" 38266e564dSmrg 39266e564dSmrgstatic XtransConnInfo ConnectToPeer(char *networkIdsList, 40266e564dSmrg char **actualConnectionRet); 41266e564dSmrg 42266e564dSmrg#define Strstr strstr 43266e564dSmrg 44266e564dSmrgIceConn 45266e564dSmrgIceOpenConnection (networkIdsList, context, mustAuthenticate, majorOpcodeCheck, 46266e564dSmrg errorLength, errorStringRet) 47266e564dSmrg 48266e564dSmrgchar *networkIdsList; 49266e564dSmrgIcePointer context; 50266e564dSmrgBool mustAuthenticate; 51266e564dSmrgint majorOpcodeCheck; 52266e564dSmrgint errorLength; 53266e564dSmrgchar *errorStringRet; 54266e564dSmrg 55266e564dSmrg{ 56266e564dSmrg IceConn iceConn; 57266e564dSmrg int extra, i, j; 58266e564dSmrg int endian; 59266e564dSmrg Bool gotReply, ioErrorOccured; 60266e564dSmrg unsigned long setup_sequence; 61266e564dSmrg iceByteOrderMsg *pByteOrderMsg; 62266e564dSmrg iceConnectionSetupMsg *pSetupMsg; 63266e564dSmrg char *pData; 64266e564dSmrg IceReplyWaitInfo replyWait; 65266e564dSmrg _IceReply reply; 66266e564dSmrg int authUsableCount; 67266e564dSmrg int authUsableFlags[MAX_ICE_AUTH_NAMES]; 68266e564dSmrg int authIndices[MAX_ICE_AUTH_NAMES]; 69266e564dSmrg 70266e564dSmrg if (errorStringRet && errorLength > 0) 71266e564dSmrg *errorStringRet = '\0'; 72266e564dSmrg 73266e564dSmrg if (networkIdsList == NULL || *networkIdsList == '\0') 74266e564dSmrg { 75266e564dSmrg strncpy (errorStringRet, 76266e564dSmrg "networkIdsList argument is NULL", errorLength); 77266e564dSmrg return (NULL); 78266e564dSmrg } 79266e564dSmrg 80266e564dSmrg /* 81266e564dSmrg * Check to see if we can use a previously created ICE connection. 82266e564dSmrg * 83266e564dSmrg * If iceConn->want_to_close is True, or iceConn->free_asap is True, 84266e564dSmrg * we can not use the iceConn. 85266e564dSmrg * 86266e564dSmrg * If 'context' is non-NULL, we will only use a previously opened ICE 87266e564dSmrg * connection if the specified 'context' is equal to the context 88266e564dSmrg * associated with the ICE connection, or if the context associated 89266e564dSmrg * with the ICE connection is NULL. 90266e564dSmrg * 91266e564dSmrg * If 'majorOpcodeCheck' is non-zero, it will contain a protocol major 92266e564dSmrg * opcode that we should make sure is not already active on the ICE 93266e564dSmrg * connection. Some clients will want two seperate connections for the 94266e564dSmrg * same protocol to the same destination client. 95266e564dSmrg */ 96266e564dSmrg 97266e564dSmrg for (i = 0; i < _IceConnectionCount; i++) 98266e564dSmrg { 99266e564dSmrg char *strptr; 100266e564dSmrg if ((strptr = (char *) Strstr ( 101266e564dSmrg networkIdsList, _IceConnectionStrings[i])) != NULL) 102266e564dSmrg { 103266e564dSmrg char ch = *(strptr + strlen (_IceConnectionStrings[i])); 104266e564dSmrg if (ch == ',' || ch == '\0') 105266e564dSmrg { 106266e564dSmrg /* 107266e564dSmrg * OK, we found a connection. Make sure we can reuse it. 108266e564dSmrg */ 109266e564dSmrg 110266e564dSmrg IceConn iceConn = _IceConnectionObjs[i]; 111266e564dSmrg 112266e564dSmrg if (iceConn->want_to_close || iceConn->free_asap || 113266e564dSmrg (context && iceConn->context && 114266e564dSmrg iceConn->context != context)) 115266e564dSmrg { 116266e564dSmrg /* force a new connection to be created */ 117266e564dSmrg break; 118266e564dSmrg } 119266e564dSmrg 120266e564dSmrg if (majorOpcodeCheck) 121266e564dSmrg { 122266e564dSmrg for (j = iceConn->his_min_opcode; 123266e564dSmrg j <= iceConn->his_max_opcode; j++) 124266e564dSmrg { 125266e564dSmrg if (iceConn->process_msg_info[ 126266e564dSmrg j - iceConn->his_min_opcode].in_use && 127266e564dSmrg iceConn->process_msg_info[ 128266e564dSmrg j - iceConn->his_min_opcode].my_opcode == 129266e564dSmrg majorOpcodeCheck) 130266e564dSmrg break; 131266e564dSmrg } 132266e564dSmrg 133266e564dSmrg if (j <= iceConn->his_max_opcode || 134266e564dSmrg (iceConn->protosetup_to_you && 135266e564dSmrg iceConn->protosetup_to_you->my_opcode == 136266e564dSmrg majorOpcodeCheck)) 137266e564dSmrg { 138266e564dSmrg /* force a new connection to be created */ 139266e564dSmrg break; 140266e564dSmrg } 141266e564dSmrg } 142266e564dSmrg 143266e564dSmrg iceConn->open_ref_count++; 144266e564dSmrg if (context && !iceConn->context) 145266e564dSmrg iceConn->context = context; 146266e564dSmrg return (iceConn); 147266e564dSmrg } 148266e564dSmrg } 149266e564dSmrg } 150266e564dSmrg 151266e564dSmrg if ((iceConn = (IceConn) malloc (sizeof (struct _IceConn))) == NULL) 152266e564dSmrg { 153266e564dSmrg strncpy (errorStringRet, "Can't malloc", errorLength); 154266e564dSmrg return (NULL); 155266e564dSmrg } 156266e564dSmrg 157266e564dSmrg 158266e564dSmrg /* 159266e564dSmrg * Open a network connection with the peer client. 160266e564dSmrg */ 161266e564dSmrg 162266e564dSmrg if ((iceConn->trans_conn = ConnectToPeer (networkIdsList, 163266e564dSmrg &iceConn->connection_string)) == NULL) 164266e564dSmrg { 165266e564dSmrg free ((char *) iceConn); 166266e564dSmrg strncpy (errorStringRet, "Could not open network socket", errorLength); 167266e564dSmrg return (NULL); 168266e564dSmrg } 169266e564dSmrg 170266e564dSmrg /* 171266e564dSmrg * Set close-on-exec so that programs that fork() don't get confused. 172266e564dSmrg */ 173266e564dSmrg 174266e564dSmrg _IceTransSetOption (iceConn->trans_conn, TRANS_CLOSEONEXEC, 1); 175266e564dSmrg 176266e564dSmrg iceConn->listen_obj = NULL; 177266e564dSmrg 178266e564dSmrg iceConn->connection_status = IceConnectPending; 179266e564dSmrg iceConn->io_ok = True; 180266e564dSmrg iceConn->dispatch_level = 0; 181266e564dSmrg iceConn->context = context; 182266e564dSmrg iceConn->my_ice_version_index = 0; 183266e564dSmrg iceConn->send_sequence = 0; 184266e564dSmrg iceConn->receive_sequence = 0; 185266e564dSmrg 186266e564dSmrg iceConn->vendor = NULL; 187266e564dSmrg iceConn->release = NULL; 188266e564dSmrg iceConn->outbuf = NULL; 189266e564dSmrg 190266e564dSmrg iceConn->scratch = NULL; 191266e564dSmrg iceConn->scratch_size = 0; 192266e564dSmrg 193266e564dSmrg iceConn->process_msg_info = NULL; 194266e564dSmrg 195266e564dSmrg iceConn->connect_to_you = NULL; 196266e564dSmrg iceConn->protosetup_to_you = NULL; 197266e564dSmrg 198266e564dSmrg iceConn->connect_to_me = NULL; 199266e564dSmrg iceConn->protosetup_to_me = NULL; 200266e564dSmrg 201266e564dSmrg if ((iceConn->inbuf = iceConn->inbufptr = 202266e564dSmrg (char *) malloc (ICE_INBUFSIZE)) == NULL) 203266e564dSmrg { 204266e564dSmrg _IceFreeConnection (iceConn); 205266e564dSmrg strncpy (errorStringRet, "Can't malloc", errorLength); 206266e564dSmrg return (NULL); 207266e564dSmrg } 208266e564dSmrg 209266e564dSmrg iceConn->inbufmax = iceConn->inbuf + ICE_INBUFSIZE; 210266e564dSmrg 211266e564dSmrg if ((iceConn->outbuf = iceConn->outbufptr = 212266e564dSmrg (char *) calloc (1, ICE_OUTBUFSIZE)) == NULL) 213266e564dSmrg { 214266e564dSmrg _IceFreeConnection (iceConn); 215266e564dSmrg strncpy (errorStringRet, "Can't malloc", errorLength); 216266e564dSmrg return (NULL); 217266e564dSmrg } 218266e564dSmrg 219266e564dSmrg iceConn->outbufmax = iceConn->outbuf + ICE_OUTBUFSIZE; 220266e564dSmrg 221266e564dSmrg iceConn->open_ref_count = 1; 222266e564dSmrg iceConn->proto_ref_count = 0; 223266e564dSmrg 224266e564dSmrg iceConn->skip_want_to_close = False; 225266e564dSmrg iceConn->want_to_close = False; 226266e564dSmrg iceConn->free_asap = False; 227266e564dSmrg 228266e564dSmrg iceConn->saved_reply_waits = NULL; 229266e564dSmrg iceConn->ping_waits = NULL; 230266e564dSmrg 231266e564dSmrg iceConn->connect_to_you = (_IceConnectToYouInfo *) malloc ( 232266e564dSmrg sizeof (_IceConnectToYouInfo)); 233266e564dSmrg iceConn->connect_to_you->auth_active = 0; 234266e564dSmrg 235266e564dSmrg /* 236266e564dSmrg * Send our byte order. 237266e564dSmrg */ 238266e564dSmrg 239266e564dSmrg IceGetHeader (iceConn, 0, ICE_ByteOrder, 240266e564dSmrg SIZEOF (iceByteOrderMsg), iceByteOrderMsg, pByteOrderMsg); 241266e564dSmrg 242266e564dSmrg endian = 1; 243266e564dSmrg if (*(char *) &endian) 244266e564dSmrg pByteOrderMsg->byteOrder = IceLSBfirst; 245266e564dSmrg else 246266e564dSmrg pByteOrderMsg->byteOrder = IceMSBfirst; 247266e564dSmrg 248266e564dSmrg IceFlush (iceConn); 249266e564dSmrg 250266e564dSmrg 251266e564dSmrg /* 252266e564dSmrg * Now read the ByteOrder message from the other client. 253266e564dSmrg * iceConn->swap should be set to the appropriate boolean 254266e564dSmrg * value after the call to IceProcessMessages. 255266e564dSmrg */ 256266e564dSmrg 257266e564dSmrg iceConn->waiting_for_byteorder = True; 258266e564dSmrg 259266e564dSmrg ioErrorOccured = False; 260266e564dSmrg while (iceConn->waiting_for_byteorder == True && !ioErrorOccured) 261266e564dSmrg { 262266e564dSmrg ioErrorOccured = (IceProcessMessages ( 263266e564dSmrg iceConn, NULL, NULL) == IceProcessMessagesIOError); 264266e564dSmrg } 265266e564dSmrg 266266e564dSmrg if (ioErrorOccured) 267266e564dSmrg { 268266e564dSmrg _IceFreeConnection (iceConn); 269266e564dSmrg strncpy (errorStringRet, "IO error occured opening connection", 270266e564dSmrg errorLength); 271266e564dSmrg return (NULL); 272266e564dSmrg } 273266e564dSmrg 274266e564dSmrg if (iceConn->connection_status == IceConnectRejected) 275266e564dSmrg { 276266e564dSmrg /* 277266e564dSmrg * We failed to get the required ByteOrder message. 278266e564dSmrg */ 279266e564dSmrg 280266e564dSmrg _IceFreeConnection (iceConn); 281266e564dSmrg strncpy (errorStringRet, 282266e564dSmrg "Internal error - did not receive the expected ByteOrder message", 283266e564dSmrg errorLength); 284266e564dSmrg return (NULL); 285266e564dSmrg } 286266e564dSmrg 287266e564dSmrg 288266e564dSmrg /* 289266e564dSmrg * Determine which authentication methods are available for 290266e564dSmrg * the Connection Setup authentication. 291266e564dSmrg */ 292266e564dSmrg 293266e564dSmrg _IceGetPoValidAuthIndices ( 294266e564dSmrg "ICE", iceConn->connection_string, 295266e564dSmrg _IceAuthCount, _IceAuthNames, &authUsableCount, authIndices); 296266e564dSmrg 297266e564dSmrg for (i = 0; i < _IceAuthCount; i++) 298266e564dSmrg { 299266e564dSmrg authUsableFlags[i] = 0; 300266e564dSmrg for (j = 0; j < authUsableCount && !authUsableFlags[i]; j++) 301266e564dSmrg authUsableFlags[i] = (authIndices[j] == i); 302266e564dSmrg } 303266e564dSmrg 304266e564dSmrg 305266e564dSmrg /* 306266e564dSmrg * Now send a Connection Setup message. 307266e564dSmrg */ 308266e564dSmrg 309266e564dSmrg extra = STRING_BYTES (IceVendorString) + STRING_BYTES (IceReleaseString); 310266e564dSmrg 311266e564dSmrg for (i = 0; i < _IceAuthCount; i++) 312266e564dSmrg if (authUsableFlags[i]) 313266e564dSmrg { 314266e564dSmrg extra += STRING_BYTES (_IceAuthNames[i]); 315266e564dSmrg } 316266e564dSmrg 317266e564dSmrg extra += (_IceVersionCount * 4); 318266e564dSmrg 319266e564dSmrg IceGetHeaderExtra (iceConn, 0, ICE_ConnectionSetup, 320266e564dSmrg SIZEOF (iceConnectionSetupMsg), WORD64COUNT (extra), 321266e564dSmrg iceConnectionSetupMsg, pSetupMsg, pData); 322266e564dSmrg 323266e564dSmrg setup_sequence = iceConn->send_sequence; 324266e564dSmrg 325266e564dSmrg pSetupMsg->versionCount = _IceVersionCount; 326266e564dSmrg pSetupMsg->authCount = authUsableCount; 327266e564dSmrg pSetupMsg->mustAuthenticate = mustAuthenticate; 328266e564dSmrg 329266e564dSmrg STORE_STRING (pData, IceVendorString); 330266e564dSmrg STORE_STRING (pData, IceReleaseString); 331266e564dSmrg 332266e564dSmrg for (i = 0; i < _IceAuthCount; i++) 333266e564dSmrg if (authUsableFlags[i]) 334266e564dSmrg { 335266e564dSmrg STORE_STRING (pData, _IceAuthNames[i]); 336266e564dSmrg } 337266e564dSmrg 338266e564dSmrg for (i = 0; i < _IceVersionCount; i++) 339266e564dSmrg { 340266e564dSmrg STORE_CARD16 (pData, _IceVersions[i].major_version); 341266e564dSmrg STORE_CARD16 (pData, _IceVersions[i].minor_version); 342266e564dSmrg } 343266e564dSmrg 344266e564dSmrg IceFlush (iceConn); 345266e564dSmrg 346266e564dSmrg 347266e564dSmrg /* 348266e564dSmrg * Process messages until we get a Connection Reply or an Error Message. 349266e564dSmrg * Authentication will take place behind the scenes. 350266e564dSmrg */ 351266e564dSmrg 352266e564dSmrg replyWait.sequence_of_request = setup_sequence; 353266e564dSmrg replyWait.major_opcode_of_request = 0; 354266e564dSmrg replyWait.minor_opcode_of_request = ICE_ConnectionSetup; 355266e564dSmrg replyWait.reply = (IcePointer) &reply; 356266e564dSmrg 357266e564dSmrg gotReply = False; 358266e564dSmrg ioErrorOccured = False; 359266e564dSmrg 360266e564dSmrg while (!gotReply && !ioErrorOccured) 361266e564dSmrg { 362266e564dSmrg ioErrorOccured = (IceProcessMessages ( 363266e564dSmrg iceConn, &replyWait, &gotReply) == IceProcessMessagesIOError); 364266e564dSmrg 365266e564dSmrg if (ioErrorOccured) 366266e564dSmrg { 367266e564dSmrg strncpy (errorStringRet, "IO error occured opening connection", 368266e564dSmrg errorLength); 369266e564dSmrg _IceFreeConnection (iceConn); 370266e564dSmrg iceConn = NULL; 371266e564dSmrg } 372266e564dSmrg else if (gotReply) 373266e564dSmrg { 374266e564dSmrg if (reply.type == ICE_CONNECTION_REPLY) 375266e564dSmrg { 376266e564dSmrg if (reply.connection_reply.version_index >= _IceVersionCount) 377266e564dSmrg { 378266e564dSmrg strncpy (errorStringRet, 379266e564dSmrg "Got a bad version index in the Connection Reply", 380266e564dSmrg errorLength); 381266e564dSmrg 382266e564dSmrg free (reply.connection_reply.vendor); 383266e564dSmrg free (reply.connection_reply.release); 384266e564dSmrg _IceFreeConnection (iceConn); 385266e564dSmrg iceConn = NULL; 386266e564dSmrg } 387266e564dSmrg else 388266e564dSmrg { 389266e564dSmrg iceConn->my_ice_version_index = 390266e564dSmrg reply.connection_reply.version_index; 391266e564dSmrg iceConn->vendor = reply.connection_reply.vendor; 392266e564dSmrg iceConn->release = reply.connection_reply.release; 393266e564dSmrg 394266e564dSmrg _IceConnectionObjs[_IceConnectionCount] = iceConn; 395266e564dSmrg _IceConnectionStrings[_IceConnectionCount] = 396266e564dSmrg iceConn->connection_string; 397266e564dSmrg _IceConnectionCount++; 398266e564dSmrg 399266e564dSmrg free ((char *) iceConn->connect_to_you); 400266e564dSmrg iceConn->connect_to_you = NULL; 401266e564dSmrg 402266e564dSmrg iceConn->connection_status = IceConnectAccepted; 403266e564dSmrg } 404266e564dSmrg } 405266e564dSmrg else /* reply.type == ICE_CONNECTION_ERROR */ 406266e564dSmrg { 407266e564dSmrg /* Connection failed */ 408266e564dSmrg 409266e564dSmrg strncpy (errorStringRet, reply.connection_error.error_message, 410266e564dSmrg errorLength); 411266e564dSmrg 412266e564dSmrg free (reply.connection_error.error_message); 413266e564dSmrg 414266e564dSmrg _IceFreeConnection (iceConn); 415266e564dSmrg iceConn = NULL; 416266e564dSmrg } 417266e564dSmrg } 418266e564dSmrg } 419266e564dSmrg 420266e564dSmrg if (iceConn && _IceWatchProcs) 421266e564dSmrg { 422266e564dSmrg /* 423266e564dSmrg * Notify the watch procedures that an iceConn was opened. 424266e564dSmrg */ 425266e564dSmrg 426266e564dSmrg _IceConnectionOpened (iceConn); 427266e564dSmrg } 428266e564dSmrg 429266e564dSmrg return (iceConn); 430266e564dSmrg} 431266e564dSmrg 432266e564dSmrg 433266e564dSmrg 434266e564dSmrgIcePointer 435266e564dSmrgIceGetConnectionContext (iceConn) 436266e564dSmrg 437266e564dSmrgIceConn iceConn; 438266e564dSmrg 439266e564dSmrg{ 440266e564dSmrg return (iceConn->context); 441266e564dSmrg} 442266e564dSmrg 443266e564dSmrg 444266e564dSmrg 445266e564dSmrg/* ------------------------------------------------------------------------- * 446266e564dSmrg * local routines * 447266e564dSmrg * ------------------------------------------------------------------------- */ 448266e564dSmrg 449266e564dSmrg#define ICE_CONNECTION_RETRIES 5 450266e564dSmrg 451266e564dSmrg 452266e564dSmrgstatic XtransConnInfo 453266e564dSmrgConnectToPeer (char *networkIdsList, char **actualConnectionRet) 454266e564dSmrg{ 455266e564dSmrg char addrbuf[256]; 456266e564dSmrg char* address; 457266e564dSmrg char *ptr, *endptr, *delim; 458266e564dSmrg int madeConnection = 0; 459266e564dSmrg int len, retry; 460266e564dSmrg int connect_stat; 461266e564dSmrg int address_size; 462266e564dSmrg XtransConnInfo trans_conn = NULL; 463266e564dSmrg 464266e564dSmrg *actualConnectionRet = NULL; 465266e564dSmrg 466266e564dSmrg ptr = networkIdsList; 467266e564dSmrg len = strlen (networkIdsList); 468266e564dSmrg endptr = networkIdsList + len; 469266e564dSmrg 470266e564dSmrg if (len < sizeof addrbuf) 471266e564dSmrg { 472266e564dSmrg address = addrbuf; 473266e564dSmrg address_size = 256; 474266e564dSmrg } 475266e564dSmrg else 476266e564dSmrg { 477266e564dSmrg address = malloc (len + 1); 478266e564dSmrg address_size = len; 479266e564dSmrg } 480266e564dSmrg 481266e564dSmrg while (ptr < endptr && !madeConnection) 482266e564dSmrg { 483266e564dSmrg if ((delim = (char *) strchr (ptr, ',')) == NULL) 484266e564dSmrg delim = endptr; 485266e564dSmrg 486266e564dSmrg len = delim - ptr; 487266e564dSmrg if (len > address_size - 1) 488266e564dSmrg len = address_size - 1; 489266e564dSmrg strncpy (address, ptr, len); 490266e564dSmrg address[len] = '\0'; 491266e564dSmrg 492266e564dSmrg ptr = delim + 1; 493266e564dSmrg 494266e564dSmrg for (retry = ICE_CONNECTION_RETRIES; retry >= 0; retry--) 495266e564dSmrg { 496266e564dSmrg if ((trans_conn = _IceTransOpenCOTSClient (address)) == NULL) 497266e564dSmrg { 498266e564dSmrg break; 499266e564dSmrg } 500266e564dSmrg 501266e564dSmrg if ((connect_stat = _IceTransConnect (trans_conn, address)) < 0) 502266e564dSmrg { 503266e564dSmrg _IceTransClose (trans_conn); 504266e564dSmrg 505266e564dSmrg if (connect_stat == TRANS_TRY_CONNECT_AGAIN) 506266e564dSmrg { 507266e564dSmrg sleep(1); 508266e564dSmrg continue; 509266e564dSmrg } 510266e564dSmrg else 511266e564dSmrg break; 512266e564dSmrg } 513266e564dSmrg else 514266e564dSmrg { 515266e564dSmrg madeConnection = 1; 516266e564dSmrg break; 517266e564dSmrg } 518266e564dSmrg } 519266e564dSmrg } 520266e564dSmrg 521266e564dSmrg if (madeConnection) 522266e564dSmrg { 523266e564dSmrg /* 524266e564dSmrg * We need to return the actual network connection string 525266e564dSmrg */ 526266e564dSmrg 527266e564dSmrg *actualConnectionRet = strdup(address); 528266e564dSmrg 529266e564dSmrg /* 530266e564dSmrg * Return the file descriptor 531266e564dSmrg */ 532266e564dSmrg } 533266e564dSmrg else trans_conn = NULL; 534266e564dSmrg 535266e564dSmrg if (address != addrbuf) free (address); 536266e564dSmrg 537266e564dSmrg return trans_conn; 538266e564dSmrg} 539