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