misc.c revision fb5e8d76
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 44266e564dSmrg 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 { 57266e564dSmrg if (iceConn->scratch) 58266e564dSmrg free (iceConn->scratch); 59266e564dSmrg 60fb5e8d76Smrg iceConn->scratch = malloc (size); 61266e564dSmrg iceConn->scratch_size = size; 62266e564dSmrg } 63266e564dSmrg 64266e564dSmrg return (iceConn->scratch); 65266e564dSmrg} 66266e564dSmrg 67266e564dSmrg 68266e564dSmrg 69266e564dSmrg/* 70266e564dSmrg * Output/Input buffer functions 71266e564dSmrg */ 72266e564dSmrg 73266e564dSmrgint 74c5629e66SmrgIceFlush ( 75c5629e66Smrg IceConn iceConn 76c5629e66Smrg) 77266e564dSmrg{ 78266e564dSmrg _IceWrite (iceConn, 79266e564dSmrg (unsigned long) (iceConn->outbufptr - iceConn->outbuf), 80266e564dSmrg iceConn->outbuf); 81266e564dSmrg 82266e564dSmrg iceConn->outbufptr = iceConn->outbuf; 83266e564dSmrg return 1; 84266e564dSmrg} 85266e564dSmrg 86266e564dSmrg 87266e564dSmrgint 88c5629e66SmrgIceGetOutBufSize ( 89c5629e66Smrg IceConn iceConn 90c5629e66Smrg) 91266e564dSmrg{ 92266e564dSmrg return (iceConn->outbufmax - iceConn->outbuf); 93266e564dSmrg} 94266e564dSmrg 95266e564dSmrg 96266e564dSmrgint 97c5629e66SmrgIceGetInBufSize ( 98c5629e66Smrg IceConn iceConn 99c5629e66Smrg) 100266e564dSmrg{ 101266e564dSmrg return (iceConn->inbufmax - iceConn->inbuf); 102266e564dSmrg} 103266e564dSmrg 104266e564dSmrg 105266e564dSmrg 106266e564dSmrg/* 107266e564dSmrg * informational functions 108266e564dSmrg */ 109266e564dSmrg 110266e564dSmrgIceConnectStatus 111c5629e66SmrgIceConnectionStatus ( 112c5629e66Smrg IceConn iceConn 113c5629e66Smrg) 114266e564dSmrg{ 115266e564dSmrg return (iceConn->connection_status); 116266e564dSmrg} 117266e564dSmrg 118266e564dSmrg 119266e564dSmrgchar * 120c5629e66SmrgIceVendor ( 121c5629e66Smrg IceConn iceConn 122c5629e66Smrg) 123266e564dSmrg{ 124266e564dSmrg return strdup(iceConn->vendor); 125266e564dSmrg} 126266e564dSmrg 127266e564dSmrg 128266e564dSmrgchar * 129c5629e66SmrgIceRelease ( 130c5629e66Smrg IceConn iceConn 131c5629e66Smrg) 132266e564dSmrg{ 133266e564dSmrg return strdup(iceConn->release); 134266e564dSmrg} 135266e564dSmrg 136266e564dSmrg 137266e564dSmrgint 138c5629e66SmrgIceProtocolVersion ( 139c5629e66Smrg IceConn iceConn 140c5629e66Smrg) 141266e564dSmrg{ 142266e564dSmrg return (_IceVersions[iceConn->my_ice_version_index].major_version); 143266e564dSmrg} 144266e564dSmrg 145266e564dSmrg 146266e564dSmrgint 147c5629e66SmrgIceProtocolRevision ( 148c5629e66Smrg IceConn iceConn 149c5629e66Smrg) 150266e564dSmrg{ 151266e564dSmrg return (_IceVersions[iceConn->my_ice_version_index].minor_version); 152266e564dSmrg} 153266e564dSmrg 154266e564dSmrg 155266e564dSmrgint 156c5629e66SmrgIceConnectionNumber ( 157c5629e66Smrg IceConn iceConn 158c5629e66Smrg) 159266e564dSmrg{ 160266e564dSmrg return (_IceTransGetConnectionNumber (iceConn->trans_conn)); 161266e564dSmrg} 162266e564dSmrg 163266e564dSmrg 164266e564dSmrgchar * 165c5629e66SmrgIceConnectionString ( 166c5629e66Smrg IceConn iceConn 167c5629e66Smrg) 168266e564dSmrg{ 169266e564dSmrg if (iceConn->connection_string) 170266e564dSmrg { 171266e564dSmrg return strdup(iceConn->connection_string); 172266e564dSmrg } 173266e564dSmrg else 174266e564dSmrg return (NULL); 175266e564dSmrg} 176266e564dSmrg 177266e564dSmrg 178266e564dSmrgunsigned long 179c5629e66SmrgIceLastSentSequenceNumber ( 180c5629e66Smrg IceConn iceConn 181c5629e66Smrg) 182266e564dSmrg{ 183266e564dSmrg return (iceConn->send_sequence); 184266e564dSmrg} 185266e564dSmrg 186266e564dSmrg 187266e564dSmrgunsigned long 188c5629e66SmrgIceLastReceivedSequenceNumber ( 189c5629e66Smrg IceConn iceConn 190c5629e66Smrg) 191266e564dSmrg{ 192266e564dSmrg return (iceConn->receive_sequence); 193266e564dSmrg} 194266e564dSmrg 195266e564dSmrg 196266e564dSmrgBool 197c5629e66SmrgIceSwapping ( 198c5629e66Smrg IceConn iceConn 199c5629e66Smrg) 200266e564dSmrg{ 201266e564dSmrg return (iceConn->swap); 202266e564dSmrg} 203266e564dSmrg 204266e564dSmrg 205266e564dSmrg 206266e564dSmrg/* 207266e564dSmrg * Read "n" bytes from a connection. 208266e564dSmrg * 209266e564dSmrg * Return Status 0 if we detected an EXPECTED closed connection. 210266e564dSmrg * 211266e564dSmrg */ 212266e564dSmrg 213266e564dSmrgStatus 214c5629e66Smrg_IceRead ( 215c5629e66Smrg register IceConn iceConn, 216c5629e66Smrg unsigned long nbytes, 217c5629e66Smrg register char *ptr 218c5629e66Smrg) 219266e564dSmrg{ 220266e564dSmrg register unsigned long nleft; 221266e564dSmrg 222266e564dSmrg nleft = nbytes; 223266e564dSmrg while (nleft > 0) 224266e564dSmrg { 225266e564dSmrg int nread; 226266e564dSmrg 227266e564dSmrg if (iceConn->io_ok) 228266e564dSmrg nread = _IceTransRead (iceConn->trans_conn, ptr, (int) nleft); 229266e564dSmrg else 230266e564dSmrg return (1); 231266e564dSmrg 232266e564dSmrg if (nread <= 0) 233266e564dSmrg { 234266e564dSmrg#ifdef WIN32 235266e564dSmrg errno = WSAGetLastError(); 236266e564dSmrg#endif 237266e564dSmrg if (iceConn->want_to_close) 238266e564dSmrg { 239266e564dSmrg /* 240266e564dSmrg * We sent a WantToClose message and now we detected that 241266e564dSmrg * the other side closed the connection. 242266e564dSmrg */ 243266e564dSmrg 244266e564dSmrg _IceConnectionClosed (iceConn); /* invoke watch procs */ 245266e564dSmrg _IceFreeConnection (iceConn); 246266e564dSmrg 247266e564dSmrg return (0); 248266e564dSmrg } 2499ef0b394Smrg else 250266e564dSmrg { 251266e564dSmrg /* 252266e564dSmrg * Fatal IO error. First notify each protocol's IceIOErrorProc 253266e564dSmrg * callback, then invoke the application IO error handler. 254266e564dSmrg */ 255266e564dSmrg 256266e564dSmrg iceConn->io_ok = False; 257266e564dSmrg 258266e564dSmrg if (iceConn->connection_status == IceConnectPending) 259266e564dSmrg { 260266e564dSmrg /* 261266e564dSmrg * Don't invoke IO error handler if we are in the 262266e564dSmrg * middle of a connection setup. 263266e564dSmrg */ 264266e564dSmrg 265266e564dSmrg return (1); 266266e564dSmrg } 267266e564dSmrg 268266e564dSmrg if (iceConn->process_msg_info) 269266e564dSmrg { 270266e564dSmrg int i; 271266e564dSmrg 272266e564dSmrg for (i = iceConn->his_min_opcode; 273266e564dSmrg i <= iceConn->his_max_opcode; i++) 274266e564dSmrg { 275266e564dSmrg _IceProcessMsgInfo *process; 276266e564dSmrg 277266e564dSmrg process = &iceConn->process_msg_info[ 278266e564dSmrg i - iceConn->his_min_opcode]; 279266e564dSmrg 280266e564dSmrg if ((process != NULL) && process->in_use) 281266e564dSmrg { 282266e564dSmrg IceIOErrorProc IOErrProc = process->accept_flag ? 283266e564dSmrg process->protocol->accept_client->io_error_proc : 284266e564dSmrg process->protocol->orig_client->io_error_proc; 285266e564dSmrg 286266e564dSmrg if (IOErrProc) 287266e564dSmrg (*IOErrProc) (iceConn); 288266e564dSmrg } 289266e564dSmrg } 290266e564dSmrg } 291266e564dSmrg 292266e564dSmrg (*_IceIOErrorHandler) (iceConn); 293266e564dSmrg return (1); 294266e564dSmrg } 295266e564dSmrg } 296266e564dSmrg 297266e564dSmrg nleft -= nread; 298266e564dSmrg ptr += nread; 299266e564dSmrg } 300266e564dSmrg 301266e564dSmrg return (1); 302266e564dSmrg} 303266e564dSmrg 304266e564dSmrg 305266e564dSmrg 306266e564dSmrg/* 307266e564dSmrg * If we read a message header with a bad major or minor opcode, 308266e564dSmrg * we need to advance to the end of the message. This way, the next 309266e564dSmrg * message can be processed correctly. 310266e564dSmrg */ 311266e564dSmrg 312266e564dSmrgvoid 313c5629e66Smrg_IceReadSkip ( 314c5629e66Smrg register IceConn iceConn, 315c5629e66Smrg register unsigned long nbytes 316c5629e66Smrg) 317266e564dSmrg{ 318266e564dSmrg char temp[512]; 319266e564dSmrg 320266e564dSmrg while (nbytes > 0) 321266e564dSmrg { 322266e564dSmrg unsigned long rbytes = nbytes > 512 ? 512 : nbytes; 323266e564dSmrg 324266e564dSmrg _IceRead (iceConn, rbytes, temp); 325266e564dSmrg nbytes -= rbytes; 326266e564dSmrg } 327266e564dSmrg} 328266e564dSmrg 329266e564dSmrg 330266e564dSmrg 331266e564dSmrg/* 332266e564dSmrg * Write "n" bytes to a connection. 333266e564dSmrg */ 334266e564dSmrg 335266e564dSmrgvoid 336c5629e66Smrg_IceWrite ( 337c5629e66Smrg register IceConn iceConn, 338c5629e66Smrg unsigned long nbytes, 339c5629e66Smrg register char *ptr 340c5629e66Smrg) 341266e564dSmrg{ 342266e564dSmrg register unsigned long nleft; 343266e564dSmrg 344266e564dSmrg nleft = nbytes; 345266e564dSmrg while (nleft > 0) 346266e564dSmrg { 347266e564dSmrg int nwritten; 348266e564dSmrg 349266e564dSmrg if (iceConn->io_ok) 350266e564dSmrg nwritten = _IceTransWrite (iceConn->trans_conn, ptr, (int) nleft); 351266e564dSmrg else 352266e564dSmrg return; 353266e564dSmrg 354266e564dSmrg if (nwritten <= 0) 355266e564dSmrg { 356266e564dSmrg#ifdef WIN32 357266e564dSmrg errno = WSAGetLastError(); 358266e564dSmrg#endif 359266e564dSmrg /* 360266e564dSmrg * Fatal IO error. First notify each protocol's IceIOErrorProc 361266e564dSmrg * callback, then invoke the application IO error handler. 362266e564dSmrg */ 363266e564dSmrg 364266e564dSmrg iceConn->io_ok = False; 365266e564dSmrg 366266e564dSmrg if (iceConn->connection_status == IceConnectPending) 367266e564dSmrg { 368266e564dSmrg /* 369266e564dSmrg * Don't invoke IO error handler if we are in the 370266e564dSmrg * middle of a connection setup. 371266e564dSmrg */ 372266e564dSmrg 373266e564dSmrg return; 374266e564dSmrg } 375266e564dSmrg 376266e564dSmrg if (iceConn->process_msg_info) 377266e564dSmrg { 378266e564dSmrg int i; 379266e564dSmrg 380266e564dSmrg for (i = iceConn->his_min_opcode; 381266e564dSmrg i <= iceConn->his_max_opcode; i++) 382266e564dSmrg { 383266e564dSmrg _IceProcessMsgInfo *process; 384266e564dSmrg 385266e564dSmrg process = &iceConn->process_msg_info[ 386266e564dSmrg i - iceConn->his_min_opcode]; 387266e564dSmrg 388266e564dSmrg if (process->in_use) 389266e564dSmrg { 390266e564dSmrg IceIOErrorProc IOErrProc = process->accept_flag ? 391266e564dSmrg process->protocol->accept_client->io_error_proc : 392266e564dSmrg process->protocol->orig_client->io_error_proc; 393266e564dSmrg 394266e564dSmrg if (IOErrProc) 395266e564dSmrg (*IOErrProc) (iceConn); 396266e564dSmrg } 397266e564dSmrg } 398266e564dSmrg } 399266e564dSmrg 400266e564dSmrg (*_IceIOErrorHandler) (iceConn); 401266e564dSmrg return; 402266e564dSmrg } 403266e564dSmrg 404266e564dSmrg nleft -= nwritten; 405266e564dSmrg ptr += nwritten; 406266e564dSmrg } 407266e564dSmrg} 408266e564dSmrg 409266e564dSmrg 410266e564dSmrg 411266e564dSmrgvoid 412c5629e66Smrg_IceAddOpcodeMapping ( 413c5629e66Smrg IceConn iceConn, 414c5629e66Smrg int hisOpcode, 415c5629e66Smrg int myOpcode 416c5629e66Smrg) 417266e564dSmrg{ 418266e564dSmrg if (hisOpcode <= 0 || hisOpcode > 255) 419266e564dSmrg { 420266e564dSmrg return; 421266e564dSmrg } 422266e564dSmrg else if (iceConn->process_msg_info == NULL) 423266e564dSmrg { 424fb5e8d76Smrg iceConn->process_msg_info = malloc (sizeof (_IceProcessMsgInfo)); 425266e564dSmrg iceConn->his_min_opcode = iceConn->his_max_opcode = hisOpcode; 426266e564dSmrg } 427266e564dSmrg else if (hisOpcode < iceConn->his_min_opcode) 428266e564dSmrg { 429266e564dSmrg _IceProcessMsgInfo *oldVec = iceConn->process_msg_info; 430266e564dSmrg int oldsize = iceConn->his_max_opcode - iceConn->his_min_opcode + 1; 431266e564dSmrg int newsize = iceConn->his_max_opcode - hisOpcode + 1; 432266e564dSmrg int i; 433266e564dSmrg 434fb5e8d76Smrg iceConn->process_msg_info = malloc ( 435266e564dSmrg newsize * sizeof (_IceProcessMsgInfo)); 436266e564dSmrg 437266e564dSmrg memcpy (&iceConn->process_msg_info[ 438266e564dSmrg iceConn->his_min_opcode - hisOpcode], oldVec, 439266e564dSmrg oldsize * sizeof (_IceProcessMsgInfo)); 440266e564dSmrg 441fb5e8d76Smrg free (oldVec); 442266e564dSmrg 443266e564dSmrg for (i = hisOpcode + 1; i < iceConn->his_min_opcode; i++) 444266e564dSmrg { 445266e564dSmrg iceConn->process_msg_info[i - 446266e564dSmrg iceConn->his_min_opcode].in_use = False; 447266e564dSmrg 448266e564dSmrg iceConn->process_msg_info[i - 449266e564dSmrg iceConn->his_min_opcode].protocol = NULL; 450266e564dSmrg } 451266e564dSmrg 452266e564dSmrg iceConn->his_min_opcode = hisOpcode; 453266e564dSmrg } 454266e564dSmrg else if (hisOpcode > iceConn->his_max_opcode) 455266e564dSmrg { 456266e564dSmrg _IceProcessMsgInfo *oldVec = iceConn->process_msg_info; 457266e564dSmrg int oldsize = iceConn->his_max_opcode - iceConn->his_min_opcode + 1; 458266e564dSmrg int newsize = hisOpcode - iceConn->his_min_opcode + 1; 459266e564dSmrg int i; 460266e564dSmrg 461fb5e8d76Smrg iceConn->process_msg_info = malloc ( 462266e564dSmrg newsize * sizeof (_IceProcessMsgInfo)); 463266e564dSmrg 464266e564dSmrg memcpy (iceConn->process_msg_info, oldVec, 465266e564dSmrg oldsize * sizeof (_IceProcessMsgInfo)); 466266e564dSmrg 467fb5e8d76Smrg free (oldVec); 468266e564dSmrg 469266e564dSmrg for (i = iceConn->his_max_opcode + 1; i < hisOpcode; i++) 470266e564dSmrg { 471266e564dSmrg iceConn->process_msg_info[i - 472266e564dSmrg iceConn->his_min_opcode].in_use = False; 473266e564dSmrg 474266e564dSmrg iceConn->process_msg_info[i - 475266e564dSmrg iceConn->his_min_opcode].protocol = NULL; 476266e564dSmrg } 477266e564dSmrg 478266e564dSmrg iceConn->his_max_opcode = hisOpcode; 479266e564dSmrg } 480266e564dSmrg 481266e564dSmrg iceConn->process_msg_info[hisOpcode - 482266e564dSmrg iceConn->his_min_opcode].in_use = True; 483266e564dSmrg 484266e564dSmrg iceConn->process_msg_info[hisOpcode - 485266e564dSmrg iceConn->his_min_opcode].my_opcode = myOpcode; 486266e564dSmrg 487266e564dSmrg iceConn->process_msg_info[hisOpcode - 488266e564dSmrg iceConn->his_min_opcode].protocol = &_IceProtocols[myOpcode - 1]; 489266e564dSmrg} 490266e564dSmrg 491266e564dSmrg 492266e564dSmrg 493266e564dSmrgchar * 494266e564dSmrgIceGetPeerName (IceConn iceConn) 495266e564dSmrg{ 496266e564dSmrg return (_IceTransGetPeerNetworkId (iceConn->trans_conn)); 497266e564dSmrg} 498266e564dSmrg 499266e564dSmrg 500266e564dSmrgchar * 501266e564dSmrg_IceGetPeerName (IceConn iceConn) 502266e564dSmrg{ 503266e564dSmrg return (IceGetPeerName(iceConn)); 504266e564dSmrg} 505