misc.c revision a3129944
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 WIN32 30266e564dSmrg#define _WILLWINSOCK_ 31266e564dSmrg#endif 32266e564dSmrg#ifdef HAVE_CONFIG_H 33266e564dSmrg#include <config.h> 34266e564dSmrg#endif 35266e564dSmrg#include <X11/ICE/ICElib.h> 36266e564dSmrg#include "ICElibint.h" 37266e564dSmrg#include <X11/Xtrans/Xtrans.h> 38266e564dSmrg#include <stdio.h> 39266e564dSmrg#ifdef WIN32 40266e564dSmrg#include <X11/Xwinsock.h> 41266e564dSmrg#include <X11/Xw32defs.h> 42266e564dSmrg#endif 43266e564dSmrg 44a3129944Smrg 45266e564dSmrg/* 46266e564dSmrg * scratch buffer 47266e564dSmrg */ 48266e564dSmrg 49266e564dSmrgchar * 50c5629e66SmrgIceAllocScratch ( 51c5629e66Smrg IceConn iceConn, 52c5629e66Smrg unsigned long size 53c5629e66Smrg) 54266e564dSmrg{ 55266e564dSmrg if (!iceConn->scratch || size > iceConn->scratch_size) 56266e564dSmrg { 57a3129944Smrg free (iceConn->scratch); 58266e564dSmrg 59fb5e8d76Smrg iceConn->scratch = malloc (size); 60266e564dSmrg iceConn->scratch_size = size; 61266e564dSmrg } 62266e564dSmrg 63266e564dSmrg return (iceConn->scratch); 64266e564dSmrg} 65266e564dSmrg 66266e564dSmrg 67a3129944Smrg 68266e564dSmrg/* 69266e564dSmrg * Output/Input buffer functions 70266e564dSmrg */ 71266e564dSmrg 72266e564dSmrgint 73c5629e66SmrgIceFlush ( 74c5629e66Smrg IceConn iceConn 75c5629e66Smrg) 76266e564dSmrg{ 77266e564dSmrg _IceWrite (iceConn, 78266e564dSmrg (unsigned long) (iceConn->outbufptr - iceConn->outbuf), 79266e564dSmrg iceConn->outbuf); 80266e564dSmrg 81266e564dSmrg iceConn->outbufptr = iceConn->outbuf; 82266e564dSmrg return 1; 83266e564dSmrg} 84266e564dSmrg 85266e564dSmrg 86266e564dSmrgint 87c5629e66SmrgIceGetOutBufSize ( 88c5629e66Smrg IceConn iceConn 89c5629e66Smrg) 90266e564dSmrg{ 91266e564dSmrg return (iceConn->outbufmax - iceConn->outbuf); 92266e564dSmrg} 93266e564dSmrg 94266e564dSmrg 95266e564dSmrgint 96c5629e66SmrgIceGetInBufSize ( 97c5629e66Smrg IceConn iceConn 98c5629e66Smrg) 99266e564dSmrg{ 100266e564dSmrg return (iceConn->inbufmax - iceConn->inbuf); 101266e564dSmrg} 102266e564dSmrg 103266e564dSmrg 104a3129944Smrg 105266e564dSmrg/* 106266e564dSmrg * informational functions 107266e564dSmrg */ 108266e564dSmrg 109266e564dSmrgIceConnectStatus 110c5629e66SmrgIceConnectionStatus ( 111c5629e66Smrg IceConn iceConn 112c5629e66Smrg) 113266e564dSmrg{ 114266e564dSmrg return (iceConn->connection_status); 115266e564dSmrg} 116266e564dSmrg 117266e564dSmrg 118266e564dSmrgchar * 119c5629e66SmrgIceVendor ( 120c5629e66Smrg IceConn iceConn 121c5629e66Smrg) 122266e564dSmrg{ 123266e564dSmrg return strdup(iceConn->vendor); 124266e564dSmrg} 125266e564dSmrg 126266e564dSmrg 127266e564dSmrgchar * 128c5629e66SmrgIceRelease ( 129c5629e66Smrg IceConn iceConn 130c5629e66Smrg) 131266e564dSmrg{ 132266e564dSmrg return strdup(iceConn->release); 133266e564dSmrg} 134266e564dSmrg 135266e564dSmrg 136266e564dSmrgint 137c5629e66SmrgIceProtocolVersion ( 138c5629e66Smrg IceConn iceConn 139c5629e66Smrg) 140266e564dSmrg{ 141266e564dSmrg return (_IceVersions[iceConn->my_ice_version_index].major_version); 142266e564dSmrg} 143266e564dSmrg 144266e564dSmrg 145266e564dSmrgint 146c5629e66SmrgIceProtocolRevision ( 147c5629e66Smrg IceConn iceConn 148c5629e66Smrg) 149266e564dSmrg{ 150266e564dSmrg return (_IceVersions[iceConn->my_ice_version_index].minor_version); 151266e564dSmrg} 152266e564dSmrg 153266e564dSmrg 154266e564dSmrgint 155c5629e66SmrgIceConnectionNumber ( 156c5629e66Smrg IceConn iceConn 157c5629e66Smrg) 158266e564dSmrg{ 159266e564dSmrg return (_IceTransGetConnectionNumber (iceConn->trans_conn)); 160266e564dSmrg} 161266e564dSmrg 162266e564dSmrg 163266e564dSmrgchar * 164c5629e66SmrgIceConnectionString ( 165c5629e66Smrg IceConn iceConn 166c5629e66Smrg) 167266e564dSmrg{ 168266e564dSmrg if (iceConn->connection_string) 169266e564dSmrg { 170266e564dSmrg return strdup(iceConn->connection_string); 171266e564dSmrg } 172266e564dSmrg else 173266e564dSmrg return (NULL); 174266e564dSmrg} 175266e564dSmrg 176266e564dSmrg 177266e564dSmrgunsigned long 178c5629e66SmrgIceLastSentSequenceNumber ( 179c5629e66Smrg IceConn iceConn 180c5629e66Smrg) 181266e564dSmrg{ 182266e564dSmrg return (iceConn->send_sequence); 183266e564dSmrg} 184266e564dSmrg 185266e564dSmrg 186266e564dSmrgunsigned long 187c5629e66SmrgIceLastReceivedSequenceNumber ( 188c5629e66Smrg IceConn iceConn 189c5629e66Smrg) 190266e564dSmrg{ 191266e564dSmrg return (iceConn->receive_sequence); 192266e564dSmrg} 193266e564dSmrg 194266e564dSmrg 195266e564dSmrgBool 196c5629e66SmrgIceSwapping ( 197c5629e66Smrg IceConn iceConn 198c5629e66Smrg) 199266e564dSmrg{ 200266e564dSmrg return (iceConn->swap); 201266e564dSmrg} 202266e564dSmrg 203266e564dSmrg 204a3129944Smrg 205266e564dSmrg/* 206266e564dSmrg * Read "n" bytes from a connection. 207266e564dSmrg * 208266e564dSmrg * Return Status 0 if we detected an EXPECTED closed connection. 209266e564dSmrg * 210266e564dSmrg */ 211266e564dSmrg 212266e564dSmrgStatus 213c5629e66Smrg_IceRead ( 214c5629e66Smrg register IceConn iceConn, 215c5629e66Smrg unsigned long nbytes, 216c5629e66Smrg register char *ptr 217c5629e66Smrg) 218266e564dSmrg{ 219266e564dSmrg register unsigned long nleft; 220266e564dSmrg 221266e564dSmrg nleft = nbytes; 222266e564dSmrg while (nleft > 0) 223266e564dSmrg { 224266e564dSmrg int nread; 225266e564dSmrg 226266e564dSmrg if (iceConn->io_ok) 227266e564dSmrg nread = _IceTransRead (iceConn->trans_conn, ptr, (int) nleft); 228266e564dSmrg else 229266e564dSmrg return (1); 230266e564dSmrg 231266e564dSmrg if (nread <= 0) 232266e564dSmrg { 233266e564dSmrg#ifdef WIN32 234266e564dSmrg errno = WSAGetLastError(); 235266e564dSmrg#endif 236266e564dSmrg if (iceConn->want_to_close) 237266e564dSmrg { 238266e564dSmrg /* 239266e564dSmrg * We sent a WantToClose message and now we detected that 240266e564dSmrg * the other side closed the connection. 241266e564dSmrg */ 242266e564dSmrg 243266e564dSmrg _IceConnectionClosed (iceConn); /* invoke watch procs */ 244266e564dSmrg 245266e564dSmrg return (0); 246266e564dSmrg } 2479ef0b394Smrg else 248266e564dSmrg { 249266e564dSmrg /* 250266e564dSmrg * Fatal IO error. First notify each protocol's IceIOErrorProc 251266e564dSmrg * callback, then invoke the application IO error handler. 252266e564dSmrg */ 253266e564dSmrg 254266e564dSmrg iceConn->io_ok = False; 255266e564dSmrg 256266e564dSmrg if (iceConn->connection_status == IceConnectPending) 257266e564dSmrg { 258266e564dSmrg /* 259266e564dSmrg * Don't invoke IO error handler if we are in the 260266e564dSmrg * middle of a connection setup. 261266e564dSmrg */ 262266e564dSmrg 263266e564dSmrg return (1); 264266e564dSmrg } 265266e564dSmrg 266266e564dSmrg if (iceConn->process_msg_info) 267266e564dSmrg { 268266e564dSmrg int i; 269266e564dSmrg 270266e564dSmrg for (i = iceConn->his_min_opcode; 271266e564dSmrg i <= iceConn->his_max_opcode; i++) 272266e564dSmrg { 273266e564dSmrg _IceProcessMsgInfo *process; 274266e564dSmrg 275266e564dSmrg process = &iceConn->process_msg_info[ 276266e564dSmrg i - iceConn->his_min_opcode]; 277266e564dSmrg 278266e564dSmrg if ((process != NULL) && process->in_use) 279266e564dSmrg { 280266e564dSmrg IceIOErrorProc IOErrProc = process->accept_flag ? 281266e564dSmrg process->protocol->accept_client->io_error_proc : 282266e564dSmrg process->protocol->orig_client->io_error_proc; 283266e564dSmrg 284266e564dSmrg if (IOErrProc) 285266e564dSmrg (*IOErrProc) (iceConn); 286266e564dSmrg } 287266e564dSmrg } 288266e564dSmrg } 289266e564dSmrg 290266e564dSmrg (*_IceIOErrorHandler) (iceConn); 291266e564dSmrg return (1); 292266e564dSmrg } 293266e564dSmrg } 294266e564dSmrg 295266e564dSmrg nleft -= nread; 296266e564dSmrg ptr += nread; 297266e564dSmrg } 298266e564dSmrg 299266e564dSmrg return (1); 300266e564dSmrg} 301266e564dSmrg 302266e564dSmrg 303a3129944Smrg 304266e564dSmrg/* 305266e564dSmrg * If we read a message header with a bad major or minor opcode, 306266e564dSmrg * we need to advance to the end of the message. This way, the next 307266e564dSmrg * message can be processed correctly. 308266e564dSmrg */ 309266e564dSmrg 310266e564dSmrgvoid 311c5629e66Smrg_IceReadSkip ( 312c5629e66Smrg register IceConn iceConn, 313c5629e66Smrg register unsigned long nbytes 314c5629e66Smrg) 315266e564dSmrg{ 316266e564dSmrg char temp[512]; 317266e564dSmrg 318266e564dSmrg while (nbytes > 0) 319266e564dSmrg { 320266e564dSmrg unsigned long rbytes = nbytes > 512 ? 512 : nbytes; 321266e564dSmrg 322266e564dSmrg _IceRead (iceConn, rbytes, temp); 323266e564dSmrg nbytes -= rbytes; 324266e564dSmrg } 325266e564dSmrg} 326266e564dSmrg 327266e564dSmrg 328a3129944Smrg 329266e564dSmrg/* 330266e564dSmrg * Write "n" bytes to a connection. 331266e564dSmrg */ 332266e564dSmrg 333266e564dSmrgvoid 334c5629e66Smrg_IceWrite ( 335c5629e66Smrg register IceConn iceConn, 336c5629e66Smrg unsigned long nbytes, 337c5629e66Smrg register char *ptr 338c5629e66Smrg) 339266e564dSmrg{ 340266e564dSmrg register unsigned long nleft; 341266e564dSmrg 342266e564dSmrg nleft = nbytes; 343266e564dSmrg while (nleft > 0) 344266e564dSmrg { 345266e564dSmrg int nwritten; 346266e564dSmrg 347266e564dSmrg if (iceConn->io_ok) 348266e564dSmrg nwritten = _IceTransWrite (iceConn->trans_conn, ptr, (int) nleft); 349266e564dSmrg else 350266e564dSmrg return; 351266e564dSmrg 352266e564dSmrg if (nwritten <= 0) 353266e564dSmrg { 354266e564dSmrg#ifdef WIN32 355266e564dSmrg errno = WSAGetLastError(); 356266e564dSmrg#endif 357266e564dSmrg /* 358266e564dSmrg * Fatal IO error. First notify each protocol's IceIOErrorProc 359266e564dSmrg * callback, then invoke the application IO error handler. 360266e564dSmrg */ 361266e564dSmrg 362266e564dSmrg iceConn->io_ok = False; 363266e564dSmrg 364266e564dSmrg if (iceConn->connection_status == IceConnectPending) 365266e564dSmrg { 366266e564dSmrg /* 367266e564dSmrg * Don't invoke IO error handler if we are in the 368266e564dSmrg * middle of a connection setup. 369266e564dSmrg */ 370266e564dSmrg 371266e564dSmrg return; 372266e564dSmrg } 373266e564dSmrg 374266e564dSmrg if (iceConn->process_msg_info) 375266e564dSmrg { 376266e564dSmrg int i; 377266e564dSmrg 378266e564dSmrg for (i = iceConn->his_min_opcode; 379266e564dSmrg i <= iceConn->his_max_opcode; i++) 380266e564dSmrg { 381266e564dSmrg _IceProcessMsgInfo *process; 382266e564dSmrg 383266e564dSmrg process = &iceConn->process_msg_info[ 384266e564dSmrg i - iceConn->his_min_opcode]; 385266e564dSmrg 386266e564dSmrg if (process->in_use) 387266e564dSmrg { 388266e564dSmrg IceIOErrorProc IOErrProc = process->accept_flag ? 389266e564dSmrg process->protocol->accept_client->io_error_proc : 390266e564dSmrg process->protocol->orig_client->io_error_proc; 391266e564dSmrg 392266e564dSmrg if (IOErrProc) 393266e564dSmrg (*IOErrProc) (iceConn); 394266e564dSmrg } 395266e564dSmrg } 396266e564dSmrg } 397266e564dSmrg 398266e564dSmrg (*_IceIOErrorHandler) (iceConn); 399266e564dSmrg return; 400266e564dSmrg } 401266e564dSmrg 402266e564dSmrg nleft -= nwritten; 403266e564dSmrg ptr += nwritten; 404266e564dSmrg } 405266e564dSmrg} 406266e564dSmrg 407266e564dSmrg 408a3129944Smrg 409266e564dSmrgvoid 410c5629e66Smrg_IceAddOpcodeMapping ( 411c5629e66Smrg IceConn iceConn, 412c5629e66Smrg int hisOpcode, 413c5629e66Smrg int myOpcode 414c5629e66Smrg) 415266e564dSmrg{ 416266e564dSmrg if (hisOpcode <= 0 || hisOpcode > 255) 417266e564dSmrg { 418266e564dSmrg return; 419266e564dSmrg } 420266e564dSmrg else if (iceConn->process_msg_info == NULL) 421266e564dSmrg { 422fb5e8d76Smrg iceConn->process_msg_info = malloc (sizeof (_IceProcessMsgInfo)); 423266e564dSmrg iceConn->his_min_opcode = iceConn->his_max_opcode = hisOpcode; 424266e564dSmrg } 425266e564dSmrg else if (hisOpcode < iceConn->his_min_opcode) 426266e564dSmrg { 427266e564dSmrg _IceProcessMsgInfo *oldVec = iceConn->process_msg_info; 428266e564dSmrg int oldsize = iceConn->his_max_opcode - iceConn->his_min_opcode + 1; 429266e564dSmrg int newsize = iceConn->his_max_opcode - hisOpcode + 1; 430266e564dSmrg int i; 431266e564dSmrg 432fb5e8d76Smrg iceConn->process_msg_info = malloc ( 433266e564dSmrg newsize * sizeof (_IceProcessMsgInfo)); 434266e564dSmrg 435266e564dSmrg memcpy (&iceConn->process_msg_info[ 436266e564dSmrg iceConn->his_min_opcode - hisOpcode], oldVec, 437266e564dSmrg oldsize * sizeof (_IceProcessMsgInfo)); 438266e564dSmrg 439fb5e8d76Smrg free (oldVec); 440266e564dSmrg 441266e564dSmrg for (i = hisOpcode + 1; i < iceConn->his_min_opcode; i++) 442266e564dSmrg { 443266e564dSmrg iceConn->process_msg_info[i - 444266e564dSmrg iceConn->his_min_opcode].in_use = False; 445266e564dSmrg 446266e564dSmrg iceConn->process_msg_info[i - 447266e564dSmrg iceConn->his_min_opcode].protocol = NULL; 448266e564dSmrg } 449266e564dSmrg 450266e564dSmrg iceConn->his_min_opcode = hisOpcode; 451266e564dSmrg } 452266e564dSmrg else if (hisOpcode > iceConn->his_max_opcode) 453266e564dSmrg { 454266e564dSmrg _IceProcessMsgInfo *oldVec = iceConn->process_msg_info; 455266e564dSmrg int oldsize = iceConn->his_max_opcode - iceConn->his_min_opcode + 1; 456266e564dSmrg int newsize = hisOpcode - iceConn->his_min_opcode + 1; 457266e564dSmrg int i; 458266e564dSmrg 459fb5e8d76Smrg iceConn->process_msg_info = malloc ( 460266e564dSmrg newsize * sizeof (_IceProcessMsgInfo)); 461266e564dSmrg 462266e564dSmrg memcpy (iceConn->process_msg_info, oldVec, 463266e564dSmrg oldsize * sizeof (_IceProcessMsgInfo)); 464266e564dSmrg 465fb5e8d76Smrg free (oldVec); 466266e564dSmrg 467266e564dSmrg for (i = iceConn->his_max_opcode + 1; i < hisOpcode; i++) 468266e564dSmrg { 469266e564dSmrg iceConn->process_msg_info[i - 470266e564dSmrg iceConn->his_min_opcode].in_use = False; 471266e564dSmrg 472266e564dSmrg iceConn->process_msg_info[i - 473266e564dSmrg iceConn->his_min_opcode].protocol = NULL; 474266e564dSmrg } 475266e564dSmrg 476266e564dSmrg iceConn->his_max_opcode = hisOpcode; 477266e564dSmrg } 478266e564dSmrg 479266e564dSmrg iceConn->process_msg_info[hisOpcode - 480266e564dSmrg iceConn->his_min_opcode].in_use = True; 481266e564dSmrg 482266e564dSmrg iceConn->process_msg_info[hisOpcode - 483266e564dSmrg iceConn->his_min_opcode].my_opcode = myOpcode; 484266e564dSmrg 485266e564dSmrg iceConn->process_msg_info[hisOpcode - 486266e564dSmrg iceConn->his_min_opcode].protocol = &_IceProtocols[myOpcode - 1]; 487266e564dSmrg} 488266e564dSmrg 489266e564dSmrg 490a3129944Smrg 491266e564dSmrgchar * 492266e564dSmrgIceGetPeerName (IceConn iceConn) 493266e564dSmrg{ 494266e564dSmrg return (_IceTransGetPeerNetworkId (iceConn->trans_conn)); 495266e564dSmrg} 496266e564dSmrg 497a3129944Smrg 498266e564dSmrgchar * 499266e564dSmrg_IceGetPeerName (IceConn iceConn) 500266e564dSmrg{ 501266e564dSmrg return (IceGetPeerName(iceConn)); 502266e564dSmrg} 503