misc.c revision c5629e66
1/* $Xorg: misc.c,v 1.4 2001/02/09 02:03:26 xorgcvs Exp $ */ 2/****************************************************************************** 3 4 5Copyright 1993, 1998 The Open Group 6 7Permission to use, copy, modify, distribute, and sell this software and its 8documentation for any purpose is hereby granted without fee, provided that 9the above copyright notice appear in all copies and that both that 10copyright notice and this permission notice appear in supporting 11documentation. 12 13The above copyright notice and this permission notice shall be included in 14all copies or substantial portions of the Software. 15 16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 20AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 23Except as contained in this notice, the name of The Open Group shall not be 24used in advertising or otherwise to promote the sale, use or other dealings 25in this Software without prior written authorization from The Open Group. 26 27Author: Ralph Mor, X Consortium 28******************************************************************************/ 29/* $XFree86: xc/lib/ICE/misc.c,v 1.3 2001/01/17 19:41:29 dawes Exp $ */ 30 31#ifdef WIN32 32#define _WILLWINSOCK_ 33#endif 34#ifdef HAVE_CONFIG_H 35#include <config.h> 36#endif 37#include <X11/ICE/ICElib.h> 38#include "ICElibint.h" 39#include <X11/Xtrans/Xtrans.h> 40#include <stdio.h> 41#ifdef WIN32 42#include <X11/Xwinsock.h> 43#include <X11/Xw32defs.h> 44#endif 45 46 47/* 48 * scratch buffer 49 */ 50 51char * 52IceAllocScratch ( 53 IceConn iceConn, 54 unsigned long size 55) 56{ 57 if (!iceConn->scratch || size > iceConn->scratch_size) 58 { 59 if (iceConn->scratch) 60 free (iceConn->scratch); 61 62 iceConn->scratch = (char *) malloc ((unsigned) size); 63 iceConn->scratch_size = size; 64 } 65 66 return (iceConn->scratch); 67} 68 69 70 71/* 72 * Output/Input buffer functions 73 */ 74 75int 76IceFlush ( 77 IceConn iceConn 78) 79{ 80 _IceWrite (iceConn, 81 (unsigned long) (iceConn->outbufptr - iceConn->outbuf), 82 iceConn->outbuf); 83 84 iceConn->outbufptr = iceConn->outbuf; 85 return 1; 86} 87 88 89int 90IceGetOutBufSize ( 91 IceConn iceConn 92) 93{ 94 return (iceConn->outbufmax - iceConn->outbuf); 95} 96 97 98int 99IceGetInBufSize ( 100 IceConn iceConn 101) 102{ 103 return (iceConn->inbufmax - iceConn->inbuf); 104} 105 106 107 108/* 109 * informational functions 110 */ 111 112IceConnectStatus 113IceConnectionStatus ( 114 IceConn iceConn 115) 116{ 117 return (iceConn->connection_status); 118} 119 120 121char * 122IceVendor ( 123 IceConn iceConn 124) 125{ 126 return strdup(iceConn->vendor); 127} 128 129 130char * 131IceRelease ( 132 IceConn iceConn 133) 134{ 135 return strdup(iceConn->release); 136} 137 138 139int 140IceProtocolVersion ( 141 IceConn iceConn 142) 143{ 144 return (_IceVersions[iceConn->my_ice_version_index].major_version); 145} 146 147 148int 149IceProtocolRevision ( 150 IceConn iceConn 151) 152{ 153 return (_IceVersions[iceConn->my_ice_version_index].minor_version); 154} 155 156 157int 158IceConnectionNumber ( 159 IceConn iceConn 160) 161{ 162 return (_IceTransGetConnectionNumber (iceConn->trans_conn)); 163} 164 165 166char * 167IceConnectionString ( 168 IceConn iceConn 169) 170{ 171 if (iceConn->connection_string) 172 { 173 return strdup(iceConn->connection_string); 174 } 175 else 176 return (NULL); 177} 178 179 180unsigned long 181IceLastSentSequenceNumber ( 182 IceConn iceConn 183) 184{ 185 return (iceConn->send_sequence); 186} 187 188 189unsigned long 190IceLastReceivedSequenceNumber ( 191 IceConn iceConn 192) 193{ 194 return (iceConn->receive_sequence); 195} 196 197 198Bool 199IceSwapping ( 200 IceConn iceConn 201) 202{ 203 return (iceConn->swap); 204} 205 206 207 208/* 209 * Read "n" bytes from a connection. 210 * 211 * Return Status 0 if we detected an EXPECTED closed connection. 212 * 213 */ 214 215Status 216_IceRead ( 217 register IceConn iceConn, 218 unsigned long nbytes, 219 register char *ptr 220) 221{ 222 register unsigned long nleft; 223 224 nleft = nbytes; 225 while (nleft > 0) 226 { 227 int nread; 228 229 if (iceConn->io_ok) 230 nread = _IceTransRead (iceConn->trans_conn, ptr, (int) nleft); 231 else 232 return (1); 233 234 if (nread <= 0) 235 { 236#ifdef WIN32 237 errno = WSAGetLastError(); 238#endif 239 if (iceConn->want_to_close) 240 { 241 /* 242 * We sent a WantToClose message and now we detected that 243 * the other side closed the connection. 244 */ 245 246 _IceConnectionClosed (iceConn); /* invoke watch procs */ 247 _IceFreeConnection (iceConn); 248 249 return (0); 250 } 251 else 252 { 253 /* 254 * Fatal IO error. First notify each protocol's IceIOErrorProc 255 * callback, then invoke the application IO error handler. 256 */ 257 258 iceConn->io_ok = False; 259 260 if (iceConn->connection_status == IceConnectPending) 261 { 262 /* 263 * Don't invoke IO error handler if we are in the 264 * middle of a connection setup. 265 */ 266 267 return (1); 268 } 269 270 if (iceConn->process_msg_info) 271 { 272 int i; 273 274 for (i = iceConn->his_min_opcode; 275 i <= iceConn->his_max_opcode; i++) 276 { 277 _IceProcessMsgInfo *process; 278 279 process = &iceConn->process_msg_info[ 280 i - iceConn->his_min_opcode]; 281 282 if ((process != NULL) && process->in_use) 283 { 284 IceIOErrorProc IOErrProc = process->accept_flag ? 285 process->protocol->accept_client->io_error_proc : 286 process->protocol->orig_client->io_error_proc; 287 288 if (IOErrProc) 289 (*IOErrProc) (iceConn); 290 } 291 } 292 } 293 294 (*_IceIOErrorHandler) (iceConn); 295 return (1); 296 } 297 } 298 299 nleft -= nread; 300 ptr += nread; 301 } 302 303 return (1); 304} 305 306 307 308/* 309 * If we read a message header with a bad major or minor opcode, 310 * we need to advance to the end of the message. This way, the next 311 * message can be processed correctly. 312 */ 313 314void 315_IceReadSkip ( 316 register IceConn iceConn, 317 register unsigned long nbytes 318) 319{ 320 char temp[512]; 321 322 while (nbytes > 0) 323 { 324 unsigned long rbytes = nbytes > 512 ? 512 : nbytes; 325 326 _IceRead (iceConn, rbytes, temp); 327 nbytes -= rbytes; 328 } 329} 330 331 332 333/* 334 * Write "n" bytes to a connection. 335 */ 336 337void 338_IceWrite ( 339 register IceConn iceConn, 340 unsigned long nbytes, 341 register char *ptr 342) 343{ 344 register unsigned long nleft; 345 346 nleft = nbytes; 347 while (nleft > 0) 348 { 349 int nwritten; 350 351 if (iceConn->io_ok) 352 nwritten = _IceTransWrite (iceConn->trans_conn, ptr, (int) nleft); 353 else 354 return; 355 356 if (nwritten <= 0) 357 { 358#ifdef WIN32 359 errno = WSAGetLastError(); 360#endif 361 /* 362 * Fatal IO error. First notify each protocol's IceIOErrorProc 363 * callback, then invoke the application IO error handler. 364 */ 365 366 iceConn->io_ok = False; 367 368 if (iceConn->connection_status == IceConnectPending) 369 { 370 /* 371 * Don't invoke IO error handler if we are in the 372 * middle of a connection setup. 373 */ 374 375 return; 376 } 377 378 if (iceConn->process_msg_info) 379 { 380 int i; 381 382 for (i = iceConn->his_min_opcode; 383 i <= iceConn->his_max_opcode; i++) 384 { 385 _IceProcessMsgInfo *process; 386 387 process = &iceConn->process_msg_info[ 388 i - iceConn->his_min_opcode]; 389 390 if (process->in_use) 391 { 392 IceIOErrorProc IOErrProc = process->accept_flag ? 393 process->protocol->accept_client->io_error_proc : 394 process->protocol->orig_client->io_error_proc; 395 396 if (IOErrProc) 397 (*IOErrProc) (iceConn); 398 } 399 } 400 } 401 402 (*_IceIOErrorHandler) (iceConn); 403 return; 404 } 405 406 nleft -= nwritten; 407 ptr += nwritten; 408 } 409} 410 411#ifdef WORD64 412 413IceWriteData16 ( 414 IceConn iceConn, 415 unsigned long nbytes, 416 short *data 417) 418{ 419 int numShorts = nbytes / 2; 420 int index = 0; 421 422 while (index < numShorts) 423 { 424 int spaceLeft, count, i; 425 int shortsLeft = numShorts - index; 426 427 spaceLeft = iceConn->outbufmax - iceConn->outbufptr - 1; 428 429 if (spaceLeft < 2) 430 { 431 IceFlush (iceConn); 432 spaceLeft = iceConn->outbufmax - iceConn->outbufptr - 1; 433 } 434 435 count = (shortsLeft < spaceLeft / 2) ? shortsLeft : spaceLeft / 2; 436 437 for (i = 0; i < count; i++) 438 STORE_CARD16 (iceConn->outbufptr, data[index++]); 439 } 440} 441 442 443IceWriteData32 ( 444 IceConn iceConn, 445 unsigned long nbytes, 446 int *data 447) 448{ 449 int numLongs = nbytes / 4; 450 int index = 0; 451 452 while (index < numLongs) 453 { 454 int spaceLeft, count, i; 455 int longsLeft = numLongs - index; 456 457 spaceLeft = iceConn->outbufmax - iceConn->outbufptr - 1; 458 459 if (spaceLeft < 4) 460 { 461 IceFlush (iceConn); 462 spaceLeft = iceConn->outbufmax - iceConn->outbufptr - 1; 463 } 464 465 count = (longsLeft < spaceLeft / 4) ? longsLeft : spaceLeft / 4; 466 467 for (i = 0; i < count; i++) 468 STORE_CARD32 (iceConn->outbufptr, data[index++]); 469 } 470} 471 472 473IceReadData16 ( 474 IceConn iceConn, 475 Bool swap, 476 unsigned long nbytes, 477 short *data 478) 479{ 480 /* NOT IMPLEMENTED YET */ 481} 482 483 484IceReadData32 ( 485 IceConn iceConn, 486 Bool swap, 487 unsigned long nbytes, 488 int *data 489) 490{ 491 /* NOT IMPLEMENTED YET */ 492} 493 494#endif /* WORD64 */ 495 496 497 498void 499_IceAddOpcodeMapping ( 500 IceConn iceConn, 501 int hisOpcode, 502 int myOpcode 503) 504{ 505 if (hisOpcode <= 0 || hisOpcode > 255) 506 { 507 return; 508 } 509 else if (iceConn->process_msg_info == NULL) 510 { 511 iceConn->process_msg_info = (_IceProcessMsgInfo *) malloc ( 512 sizeof (_IceProcessMsgInfo)); 513 iceConn->his_min_opcode = iceConn->his_max_opcode = hisOpcode; 514 } 515 else if (hisOpcode < iceConn->his_min_opcode) 516 { 517 _IceProcessMsgInfo *oldVec = iceConn->process_msg_info; 518 int oldsize = iceConn->his_max_opcode - iceConn->his_min_opcode + 1; 519 int newsize = iceConn->his_max_opcode - hisOpcode + 1; 520 int i; 521 522 iceConn->process_msg_info = (_IceProcessMsgInfo *) malloc ( 523 newsize * sizeof (_IceProcessMsgInfo)); 524 525 memcpy (&iceConn->process_msg_info[ 526 iceConn->his_min_opcode - hisOpcode], oldVec, 527 oldsize * sizeof (_IceProcessMsgInfo)); 528 529 free ((char *) oldVec); 530 531 for (i = hisOpcode + 1; i < iceConn->his_min_opcode; i++) 532 { 533 iceConn->process_msg_info[i - 534 iceConn->his_min_opcode].in_use = False; 535 536 iceConn->process_msg_info[i - 537 iceConn->his_min_opcode].protocol = NULL; 538 } 539 540 iceConn->his_min_opcode = hisOpcode; 541 } 542 else if (hisOpcode > iceConn->his_max_opcode) 543 { 544 _IceProcessMsgInfo *oldVec = iceConn->process_msg_info; 545 int oldsize = iceConn->his_max_opcode - iceConn->his_min_opcode + 1; 546 int newsize = hisOpcode - iceConn->his_min_opcode + 1; 547 int i; 548 549 iceConn->process_msg_info = (_IceProcessMsgInfo *) malloc ( 550 newsize * sizeof (_IceProcessMsgInfo)); 551 552 memcpy (iceConn->process_msg_info, oldVec, 553 oldsize * sizeof (_IceProcessMsgInfo)); 554 555 free ((char *) oldVec); 556 557 for (i = iceConn->his_max_opcode + 1; i < hisOpcode; i++) 558 { 559 iceConn->process_msg_info[i - 560 iceConn->his_min_opcode].in_use = False; 561 562 iceConn->process_msg_info[i - 563 iceConn->his_min_opcode].protocol = NULL; 564 } 565 566 iceConn->his_max_opcode = hisOpcode; 567 } 568 569 iceConn->process_msg_info[hisOpcode - 570 iceConn->his_min_opcode].in_use = True; 571 572 iceConn->process_msg_info[hisOpcode - 573 iceConn->his_min_opcode].my_opcode = myOpcode; 574 575 iceConn->process_msg_info[hisOpcode - 576 iceConn->his_min_opcode].protocol = &_IceProtocols[myOpcode - 1]; 577} 578 579 580 581char * 582IceGetPeerName (IceConn iceConn) 583{ 584 return (_IceTransGetPeerNetworkId (iceConn->trans_conn)); 585} 586 587 588char * 589_IceGetPeerName (IceConn iceConn) 590{ 591 return (IceGetPeerName(iceConn)); 592} 593