sm_process.c revision 0a6b08f8
1/* 2 3Copyright 1993, 1998 The Open Group 4 5Permission to use, copy, modify, distribute, and sell this software and its 6documentation for any purpose is hereby granted without fee, provided that 7the above copyright notice appear in all copies and that both that 8copyright notice and this permission notice appear in supporting 9documentation. 10 11The above copyright notice and this permission notice shall be included in 12all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 21Except as contained in this notice, the name of The Open Group shall not be 22used in advertising or otherwise to promote the sale, use or other dealings 23in this Software without prior written authorization from The Open Group. 24 25*/ 26 27/* 28 * Author: Ralph Mor, X Consortium 29 */ 30 31#ifdef HAVE_CONFIG_H 32#include <config.h> 33#endif 34#include <X11/SM/SMlib.h> 35#include "SMlibint.h" 36 37 38/* 39 * Check for bad length 40 */ 41 42#define CHECK_SIZE_MATCH(_iceConn, _majorOp, _minorOp, _expected_len, _actual_len, _severity) \ 43 if ((((_actual_len) - SIZEOF (iceMsg)) >> 3) != _expected_len) \ 44 { \ 45 _IceErrorBadLength (_iceConn, _majorOp, _minorOp, _severity); \ 46 return; \ 47 } 48 49#define CHECK_AT_LEAST_SIZE(_iceConn, _majorOp, _minorOp, _expected_len, _actual_len, _severity) \ 50 if ((((_actual_len) - SIZEOF (iceMsg)) >> 3) > _expected_len) \ 51 { \ 52 _IceErrorBadLength (_iceConn, _majorOp, _minorOp, _severity); \ 53 return; \ 54 } 55 56#define CHECK_COMPLETE_SIZE(_iceConn, _majorOp, _minorOp, _expected_len, _actual_len, _pStart, _severity) \ 57 if (((unsigned long)(PADDED_BYTES64((_actual_len)) - SIZEOF (iceMsg)) >> 3) \ 58 != _expected_len) \ 59 { \ 60 _IceErrorBadLength (_iceConn, _majorOp, _minorOp, _severity); \ 61 IceDisposeCompleteMessage (iceConn, _pStart); \ 62 return; \ 63 } 64 65 66 67void 68_SmcProcessMessage(IceConn iceConn, IcePointer clientData, int opcode, 69 unsigned long length, Bool swap, 70 IceReplyWaitInfo *replyWait, Bool *replyReadyRet) 71{ 72 SmcConn smcConn = (SmcConn) clientData; 73 74 if (replyWait) 75 *replyReadyRet = False; 76 77 if (!smcConn->client_id && 78 opcode != SM_RegisterClientReply && opcode != SM_Error) 79 { 80 _IceReadSkip (iceConn, length << 3); 81 82 _IceErrorBadState (iceConn, _SmcOpcode, opcode, IceFatalToProtocol); 83 return; 84 } 85 86 switch (opcode) 87 { 88 case SM_Error: 89 { 90 iceErrorMsg *pMsg; 91 char *pData; 92 93 CHECK_AT_LEAST_SIZE (iceConn, _SmcOpcode, opcode, 94 length, SIZEOF (iceErrorMsg), IceFatalToProtocol); 95 96 IceReadCompleteMessage (iceConn, SIZEOF (iceErrorMsg), 97 iceErrorMsg, pMsg, pData); 98 99 if (!IceValidIO (iceConn)) 100 { 101 IceDisposeCompleteMessage (iceConn, pData); 102 return; 103 } 104 105 if (swap) 106 { 107 pMsg->errorClass = lswaps (pMsg->errorClass); 108 pMsg->offendingSequenceNum = lswapl (pMsg->offendingSequenceNum); 109 } 110 111 if (replyWait && 112 replyWait->minor_opcode_of_request == SM_RegisterClient && 113 pMsg->errorClass == IceBadValue && 114 pMsg->offendingMinorOpcode == SM_RegisterClient && 115 pMsg->offendingSequenceNum == replyWait->sequence_of_request) 116 { 117 /* 118 * For Register Client, the previous ID was bad. 119 */ 120 121 _SmcRegisterClientReply *reply = 122 (_SmcRegisterClientReply *) (replyWait->reply); 123 124 reply->status = 0; 125 126 *replyReadyRet = True; 127 } 128 else 129 { 130 (*_SmcErrorHandler) (smcConn, swap, 131 pMsg->offendingMinorOpcode, 132 pMsg->offendingSequenceNum, 133 pMsg->errorClass, pMsg->severity, 134 (SmPointer) pData); 135 } 136 137 IceDisposeCompleteMessage (iceConn, pData); 138 break; 139 } 140 141 case SM_RegisterClientReply: 142 143 if (!replyWait || 144 replyWait->minor_opcode_of_request != SM_RegisterClient) 145 { 146 _IceReadSkip (iceConn, length << 3); 147 148 _IceErrorBadState (iceConn, _SmcOpcode, 149 SM_RegisterClientReply, IceFatalToProtocol); 150 } 151 else 152 { 153 smRegisterClientReplyMsg *pMsg; 154 char *pData, *pStart; 155 _SmcRegisterClientReply *reply = 156 (_SmcRegisterClientReply *) (replyWait->reply); 157 158#if 0 /* No-op */ 159 CHECK_AT_LEAST_SIZE (iceConn, _SmcOpcode, opcode, 160 length, SIZEOF (smRegisterClientReplyMsg), IceFatalToProtocol); 161#endif 162 163 IceReadCompleteMessage (iceConn, SIZEOF (smRegisterClientReplyMsg), 164 smRegisterClientReplyMsg, pMsg, pStart); 165 166 if (!IceValidIO (iceConn)) 167 { 168 IceDisposeCompleteMessage (iceConn, pStart); 169 return; 170 } 171 172 pData = pStart; 173 174 SKIP_ARRAY8 (pData, swap); /* client id */ 175 176 CHECK_COMPLETE_SIZE (iceConn, _SmcOpcode, opcode, 177 length, pData - pStart + SIZEOF (smRegisterClientReplyMsg), 178 pStart, IceFatalToProtocol); 179 180 pData = pStart; 181 182 EXTRACT_ARRAY8_AS_STRING (pData, swap, reply->client_id); 183 184 reply->status = 1; 185 *replyReadyRet = True; 186 187 IceDisposeCompleteMessage (iceConn, pStart); 188 } 189 break; 190 191 case SM_SaveYourself: 192 { 193 smSaveYourselfMsg *pMsg; 194 unsigned char errVal; 195 int errOffset = -1; 196 197 CHECK_SIZE_MATCH (iceConn, _SmcOpcode, opcode, 198 length, SIZEOF (smSaveYourselfMsg), 199 IceFatalToProtocol); 200 201 IceReadMessageHeader (iceConn, SIZEOF (smSaveYourselfMsg), 202 smSaveYourselfMsg, pMsg); 203 204 if (!IceValidIO (iceConn)) 205 { 206 return; 207 } 208 209 if (pMsg->saveType != SmSaveGlobal && 210 pMsg->saveType != SmSaveLocal && 211 pMsg->saveType != SmSaveBoth) 212 { 213 errVal = pMsg->saveType; 214 errOffset = 8; 215 } 216 else if (pMsg->shutdown != 1 && pMsg->shutdown != 0) 217 { 218 errVal = pMsg->shutdown; 219 errOffset = 9; 220 } 221 else if (pMsg->interactStyle != SmInteractStyleNone && 222 pMsg->interactStyle != SmInteractStyleErrors && 223 pMsg->interactStyle != SmInteractStyleAny) 224 { 225 errVal = pMsg->interactStyle; 226 errOffset = 10; 227 } 228 else if (pMsg->fast != 1 && pMsg->fast != 0) 229 { 230 errVal = pMsg->fast; 231 errOffset = 11; 232 } 233 234 if (errOffset >= 0) 235 { 236 _IceErrorBadValue (iceConn, _SmcOpcode, 237 SM_SaveYourself, errOffset, 1, (IcePointer) &errVal); 238 } 239 else 240 { 241 (*smcConn->callbacks.save_yourself.callback) (smcConn, 242 smcConn->callbacks.save_yourself.client_data, 243 pMsg->saveType, pMsg->shutdown, 244 pMsg->interactStyle, pMsg->fast); 245 246 smcConn->save_yourself_in_progress = True; 247 248 if (pMsg->shutdown) 249 smcConn->shutdown_in_progress = True; 250 } 251 break; 252 } 253 254 case SM_SaveYourselfPhase2: 255 256 if (!smcConn->phase2_wait) 257 { 258 _IceErrorBadState (iceConn, _SmcOpcode, 259 SM_SaveYourselfPhase2, IceCanContinue); 260 } 261 else 262 { 263 CHECK_SIZE_MATCH (iceConn, _SmcOpcode, opcode, 264 length, SIZEOF (smSaveYourselfPhase2Msg), 265 IceFatalToProtocol); 266 267 (*smcConn->phase2_wait->phase2_proc) (smcConn, 268 smcConn->phase2_wait->client_data); 269 270 free (smcConn->phase2_wait); 271 smcConn->phase2_wait = NULL; 272 } 273 break; 274 275 case SM_Interact: 276 277 if (!smcConn->interact_waits) 278 { 279 _IceErrorBadState (iceConn, _SmcOpcode, 280 SM_Interact, IceCanContinue); 281 } 282 else 283 { 284 _SmcInteractWait *next = smcConn->interact_waits->next; 285 286 CHECK_SIZE_MATCH (iceConn, _SmcOpcode, opcode, 287 length, SIZEOF (smInteractMsg), 288 IceFatalToProtocol); 289 290 (*smcConn->interact_waits->interact_proc) (smcConn, 291 smcConn->interact_waits->client_data); 292 293 free (smcConn->interact_waits); 294 smcConn->interact_waits = next; 295 } 296 break; 297 298 case SM_SaveComplete: 299 300 if (!smcConn->save_yourself_in_progress) 301 { 302 _IceErrorBadState (iceConn, _SmcOpcode, 303 SM_SaveComplete, IceCanContinue); 304 } 305 else 306 { 307 CHECK_SIZE_MATCH (iceConn, _SmcOpcode, opcode, 308 length, SIZEOF (smSaveCompleteMsg), 309 IceFatalToProtocol); 310 311 smcConn->save_yourself_in_progress = False; 312 313 (*smcConn->callbacks.save_complete.callback) (smcConn, 314 smcConn->callbacks.save_complete.client_data); 315 } 316 break; 317 318 case SM_Die: 319 320 CHECK_SIZE_MATCH (iceConn, _SmcOpcode, opcode, 321 length, SIZEOF (smDieMsg), 322 IceFatalToProtocol); 323 324 (*smcConn->callbacks.die.callback) (smcConn, 325 smcConn->callbacks.die.client_data); 326 break; 327 328 case SM_ShutdownCancelled: 329 330 if (!smcConn->shutdown_in_progress) 331 { 332 _IceErrorBadState (iceConn, _SmcOpcode, 333 SM_ShutdownCancelled, IceCanContinue); 334 } 335 else 336 { 337 CHECK_SIZE_MATCH (iceConn, _SmcOpcode, opcode, 338 length, SIZEOF (smShutdownCancelledMsg), 339 IceFatalToProtocol); 340 341 smcConn->shutdown_in_progress = False; 342 343 (*smcConn->callbacks.shutdown_cancelled.callback) (smcConn, 344 smcConn->callbacks.shutdown_cancelled.client_data); 345 } 346 break; 347 348 case SM_PropertiesReply: 349 350 if (!smcConn->prop_reply_waits) 351 { 352 _IceReadSkip (iceConn, length << 3); 353 354 _IceErrorBadState (iceConn, _SmcOpcode, 355 SM_PropertiesReply, IceCanContinue); 356 } 357 else 358 { 359 smPropertiesReplyMsg *pMsg; 360 char *pData, *pStart; 361 int numProps; 362 SmProp **props = NULL; 363 _SmcPropReplyWait *next; 364 365#if 0 /* No-op */ 366 CHECK_AT_LEAST_SIZE (iceConn, _SmcOpcode, opcode, 367 length, SIZEOF (smPropertiesReplyMsg), IceFatalToProtocol); 368#endif 369 370 IceReadCompleteMessage (iceConn, SIZEOF (smPropertiesReplyMsg), 371 smPropertiesReplyMsg, pMsg, pStart); 372 373 if (!IceValidIO (iceConn)) 374 { 375 IceDisposeCompleteMessage (iceConn, pStart); 376 return; 377 } 378 379 pData = pStart; 380 381 SKIP_LISTOF_PROPERTY (pData, swap); 382 383 CHECK_COMPLETE_SIZE (iceConn, _SmcOpcode, opcode, 384 length, pData - pStart + SIZEOF (smPropertiesReplyMsg), 385 pStart, IceFatalToProtocol); 386 387 pData = pStart; 388 389 EXTRACT_LISTOF_PROPERTY (pData, swap, numProps, props); 390 391 next = smcConn->prop_reply_waits->next; 392 393 (*smcConn->prop_reply_waits->prop_reply_proc) (smcConn, 394 smcConn->prop_reply_waits->client_data, numProps, props); 395 396 free (smcConn->prop_reply_waits); 397 smcConn->prop_reply_waits = next; 398 399 IceDisposeCompleteMessage (iceConn, pStart); 400 } 401 break; 402 403 default: 404 { 405 _IceErrorBadMinor (iceConn, _SmcOpcode, opcode, IceCanContinue); 406 _IceReadSkip (iceConn, length << 3); 407 break; 408 } 409 } 410} 411 412 413 414void 415_SmsProcessMessage(IceConn iceConn, IcePointer clientData, int opcode, 416 unsigned long length, Bool swap) 417{ 418 SmsConn smsConn = (SmsConn) clientData; 419 420 if (!smsConn->client_id && 421 opcode != SM_RegisterClient && opcode != SM_Error) 422 { 423 _IceReadSkip (iceConn, length << 3); 424 425 _IceErrorBadState (iceConn, _SmsOpcode, opcode, IceFatalToProtocol); 426 427 return; 428 } 429 430 switch (opcode) 431 { 432 case SM_Error: 433 { 434 iceErrorMsg *pMsg; 435 char *pData; 436 437 CHECK_AT_LEAST_SIZE (iceConn, _SmsOpcode, opcode, 438 length, SIZEOF (iceErrorMsg), IceFatalToProtocol); 439 440 IceReadCompleteMessage (iceConn, SIZEOF (iceErrorMsg), 441 iceErrorMsg, pMsg, pData); 442 443 if (!IceValidIO (iceConn)) 444 { 445 IceDisposeCompleteMessage (iceConn, pData); 446 return; 447 } 448 449 if (swap) 450 { 451 pMsg->errorClass = lswaps (pMsg->errorClass); 452 pMsg->offendingSequenceNum = lswapl (pMsg->offendingSequenceNum); 453 } 454 455 (*_SmsErrorHandler) (smsConn, swap, 456 pMsg->offendingMinorOpcode, 457 pMsg->offendingSequenceNum, 458 pMsg->errorClass, pMsg->severity, 459 (SmPointer) pData); 460 461 IceDisposeCompleteMessage (iceConn, pData); 462 break; 463 } 464 465 case SM_RegisterClient: 466 { 467 smRegisterClientMsg *pMsg; 468 char *pData, *pStart; 469 char *previousId; 470 int idLen; 471 472#if 0 /* No-op */ 473 CHECK_AT_LEAST_SIZE (iceConn, _SmsOpcode, opcode, 474 length, SIZEOF (smRegisterClientMsg), IceFatalToProtocol); 475#endif 476 477 IceReadCompleteMessage (iceConn, SIZEOF (smRegisterClientMsg), 478 smRegisterClientMsg, pMsg, pStart); 479 480 if (!IceValidIO (iceConn)) 481 { 482 IceDisposeCompleteMessage (iceConn, pStart); 483 return; 484 } 485 486 pData = pStart; 487 488 SKIP_ARRAY8 (pData, swap); /* previous id */ 489 490 CHECK_COMPLETE_SIZE (iceConn, _SmsOpcode, opcode, 491 length, pData - pStart + SIZEOF (smRegisterClientMsg), 492 pStart, IceFatalToProtocol); 493 494 pData = pStart; 495 496 EXTRACT_ARRAY8 (pData, swap, idLen, previousId); 497 498 if (*previousId == '\0') 499 { 500 free (previousId); 501 previousId = NULL; 502 } 503 504 if (!(*smsConn->callbacks.register_client.callback) (smsConn, 505 smsConn->callbacks.register_client.manager_data, previousId)) 506 { 507 /* 508 * The previoudId was bad. Generate BadValue error. 509 */ 510 511 _IceErrorBadValue (smsConn->iceConn, _SmsOpcode, SM_RegisterClient, 512 8, ARRAY8_BYTES (idLen), (IcePointer) pStart); 513 } 514 515 IceDisposeCompleteMessage (iceConn, pStart); 516 break; 517 } 518 519 case SM_InteractRequest: 520 521 if (!smsConn->save_yourself_in_progress || 522 smsConn->interaction_allowed == SmInteractStyleNone) 523 { 524 _IceErrorBadState (iceConn, _SmsOpcode, 525 SM_InteractRequest, IceCanContinue); 526 } 527 else 528 { 529 smInteractRequestMsg *pMsg; 530 531 CHECK_SIZE_MATCH (iceConn, _SmsOpcode, opcode, 532 length, SIZEOF (smInteractRequestMsg), 533 IceFatalToProtocol); 534 535 IceReadSimpleMessage (iceConn, smInteractRequestMsg, pMsg); 536 537 if (pMsg->dialogType != SmDialogNormal && 538 pMsg->dialogType != SmDialogError) 539 { 540 unsigned char errVal = pMsg->dialogType; 541 542 _IceErrorBadValue (iceConn, _SmsOpcode, 543 SM_InteractRequest, 2, 1, (IcePointer) &errVal); 544 } 545 else if (pMsg->dialogType == SmDialogNormal && 546 smsConn->interaction_allowed != SmInteractStyleAny) 547 { 548 _IceErrorBadState (iceConn, _SmsOpcode, 549 SM_InteractRequest, IceCanContinue); 550 } 551 else 552 { 553 (*smsConn->callbacks.interact_request.callback) (smsConn, 554 smsConn->callbacks.interact_request.manager_data, 555 pMsg->dialogType); 556 } 557 } 558 break; 559 560 case SM_InteractDone: 561 562 if (!smsConn->interact_in_progress) 563 { 564 _IceErrorBadState (iceConn, _SmsOpcode, 565 SM_InteractDone, IceCanContinue); 566 } 567 else 568 { 569 smInteractDoneMsg *pMsg; 570 571 CHECK_SIZE_MATCH (iceConn, _SmsOpcode, opcode, 572 length, SIZEOF (smInteractDoneMsg), 573 IceFatalToProtocol); 574 575 IceReadSimpleMessage (iceConn, smInteractDoneMsg, pMsg); 576 577 if (pMsg->cancelShutdown != 1 && 578 pMsg->cancelShutdown != 0) 579 { 580 unsigned char errVal = pMsg->cancelShutdown; 581 582 _IceErrorBadValue (iceConn, _SmsOpcode, 583 SM_InteractDone, 2, 1, (IcePointer) &errVal); 584 } 585 else if (pMsg->cancelShutdown && !smsConn->can_cancel_shutdown) 586 { 587 _IceErrorBadState (iceConn, _SmsOpcode, 588 SM_InteractDone, IceCanContinue); 589 } 590 else 591 { 592 smsConn->interact_in_progress = False; 593 594 (*smsConn->callbacks.interact_done.callback) (smsConn, 595 smsConn->callbacks.interact_done.manager_data, 596 pMsg->cancelShutdown); 597 } 598 } 599 break; 600 601 case SM_SaveYourselfRequest: 602 { 603 smSaveYourselfRequestMsg *pMsg; 604 unsigned char errVal; 605 int errOffset = -1; 606 607 CHECK_SIZE_MATCH (iceConn, _SmsOpcode, opcode, 608 length, SIZEOF (smSaveYourselfRequestMsg), 609 IceFatalToProtocol); 610 611 IceReadMessageHeader (iceConn, SIZEOF (smSaveYourselfRequestMsg), 612 smSaveYourselfRequestMsg, pMsg); 613 614 if (!IceValidIO (iceConn)) 615 { 616 IceDisposeCompleteMessage (iceConn, pMsg); 617 return; 618 } 619 620 if (pMsg->saveType != SmSaveGlobal && 621 pMsg->saveType != SmSaveLocal && 622 pMsg->saveType != SmSaveBoth) 623 { 624 errVal = pMsg->saveType; 625 errOffset = 8; 626 } 627 else if (pMsg->shutdown != 1 && pMsg->shutdown != 0) 628 { 629 errVal = pMsg->shutdown; 630 errOffset = 9; 631 } 632 else if (pMsg->interactStyle != SmInteractStyleNone && 633 pMsg->interactStyle != SmInteractStyleErrors && 634 pMsg->interactStyle != SmInteractStyleAny) 635 { 636 errVal = pMsg->interactStyle; 637 errOffset = 10; 638 } 639 else if (pMsg->fast != 1 && pMsg->fast != 0) 640 { 641 errVal = pMsg->fast; 642 errOffset = 11; 643 } 644 else if (pMsg->global != 1 && pMsg->global != 0) 645 { 646 errVal = pMsg->fast; 647 errOffset = 11; 648 } 649 650 if (errOffset >= 0) 651 { 652 _IceErrorBadValue (iceConn, _SmsOpcode, 653 SM_SaveYourselfRequest, errOffset, 1, (IcePointer) &errVal); 654 } 655 else 656 { 657 (*smsConn->callbacks.save_yourself_request.callback) (smsConn, 658 smsConn->callbacks.save_yourself_request.manager_data, 659 pMsg->saveType, pMsg->shutdown, pMsg->interactStyle, 660 pMsg->fast, pMsg->global); 661 } 662 break; 663 } 664 665 case SM_SaveYourselfPhase2Request: 666 667 if (!smsConn->save_yourself_in_progress) 668 { 669 _IceErrorBadState (iceConn, _SmsOpcode, 670 SM_SaveYourselfPhase2Request, IceCanContinue); 671 } 672 else 673 { 674 CHECK_SIZE_MATCH (iceConn, _SmsOpcode, opcode, 675 length, SIZEOF (smSaveYourselfPhase2RequestMsg), 676 IceFatalToProtocol); 677 678 (*smsConn->callbacks.save_yourself_phase2_request.callback) ( 679 smsConn, smsConn->callbacks. 680 save_yourself_phase2_request.manager_data); 681 } 682 break; 683 684 case SM_SaveYourselfDone: 685 686 if (!smsConn->save_yourself_in_progress) 687 { 688 _IceErrorBadState (iceConn, _SmsOpcode, 689 SM_SaveYourselfDone, IceCanContinue); 690 } 691 else 692 { 693 smSaveYourselfDoneMsg *pMsg; 694 695 CHECK_SIZE_MATCH (iceConn, _SmsOpcode, opcode, 696 length, SIZEOF (smSaveYourselfDoneMsg), 697 IceFatalToProtocol); 698 699 IceReadSimpleMessage (iceConn, smSaveYourselfDoneMsg, pMsg); 700 701 if (pMsg->success != 1 && pMsg->success != 0) 702 { 703 unsigned char errVal = pMsg->success; 704 705 _IceErrorBadValue (iceConn, _SmsOpcode, 706 SM_SaveYourselfDone, 2, 1, (IcePointer) &errVal); 707 } 708 else 709 { 710 smsConn->save_yourself_in_progress = False; 711 smsConn->interaction_allowed = SmInteractStyleNone; 712 713 (*smsConn->callbacks.save_yourself_done.callback) (smsConn, 714 smsConn->callbacks.save_yourself_done.manager_data, 715 pMsg->success); 716 } 717 } 718 break; 719 720 case SM_CloseConnection: 721 { 722 smCloseConnectionMsg *pMsg; 723 char *pData, *pStart; 724 int count, i; 725 char **reasonMsgs = NULL; 726 727#if 0 /* No-op */ 728 CHECK_AT_LEAST_SIZE (iceConn, _SmsOpcode, opcode, 729 length, SIZEOF (smCloseConnectionMsg), IceFatalToProtocol); 730#endif 731 732 IceReadCompleteMessage (iceConn, SIZEOF (smCloseConnectionMsg), 733 smCloseConnectionMsg, pMsg, pStart); 734 735 if (!IceValidIO (iceConn)) 736 { 737 IceDisposeCompleteMessage (iceConn, pStart); 738 return; 739 } 740 741 pData = pStart; 742 743 EXTRACT_CARD32 (pData, swap, count); 744 pData += 4; 745 746 for (i = 0; i < count; i++) 747 SKIP_ARRAY8 (pData, swap); 748 749 CHECK_COMPLETE_SIZE (iceConn, _SmsOpcode, opcode, 750 length, pData - pStart + SIZEOF (smCloseConnectionMsg), 751 pStart, IceFatalToProtocol); 752 753 pData = pStart + 8; 754 755 reasonMsgs = malloc (count * sizeof (char *)); 756 for (i = 0; i < count; i++) 757 EXTRACT_ARRAY8_AS_STRING (pData, swap, reasonMsgs[i]); 758 759 IceDisposeCompleteMessage (iceConn, pStart); 760 761 (*smsConn->callbacks.close_connection.callback) (smsConn, 762 smsConn->callbacks.close_connection.manager_data, 763 count, reasonMsgs); 764 break; 765 } 766 767 case SM_SetProperties: 768 { 769 smSetPropertiesMsg *pMsg; 770 char *pData, *pStart; 771 SmProp **props = NULL; 772 int numProps; 773 774#if 0 /* No-op */ 775 CHECK_AT_LEAST_SIZE (iceConn, _SmsOpcode, opcode, 776 length, SIZEOF (smSetPropertiesMsg), IceFatalToProtocol); 777#endif 778 779 IceReadCompleteMessage (iceConn, SIZEOF (smSetPropertiesMsg), 780 smSetPropertiesMsg, pMsg, pStart); 781 782 if (!IceValidIO (iceConn)) 783 { 784 IceDisposeCompleteMessage (iceConn, pStart); 785 return; 786 } 787 788 pData = pStart; 789 790 SKIP_LISTOF_PROPERTY (pData, swap); 791 792 CHECK_COMPLETE_SIZE (iceConn, _SmsOpcode, opcode, 793 length, pData - pStart + SIZEOF (smSetPropertiesMsg), 794 pStart, IceFatalToProtocol); 795 796 pData = pStart; 797 798 EXTRACT_LISTOF_PROPERTY (pData, swap, numProps, props); 799 800 (*smsConn->callbacks.set_properties.callback) (smsConn, 801 smsConn->callbacks.set_properties.manager_data, numProps, props); 802 803 IceDisposeCompleteMessage (iceConn, pStart); 804 break; 805 } 806 807 case SM_DeleteProperties: 808 { 809 smDeletePropertiesMsg *pMsg; 810 char *pData, *pStart; 811 int count, i; 812 char **propNames = NULL; 813 814#if 0 /* No-op */ 815 CHECK_AT_LEAST_SIZE (iceConn, _SmsOpcode, opcode, 816 length, SIZEOF (smDeletePropertiesMsg), IceFatalToProtocol); 817#endif 818 819 IceReadCompleteMessage (iceConn, SIZEOF (smDeletePropertiesMsg), 820 smDeletePropertiesMsg, pMsg, pStart); 821 822 if (!IceValidIO (iceConn)) 823 { 824 IceDisposeCompleteMessage (iceConn, pStart); 825 return; 826 } 827 828 pData = pStart; 829 830 EXTRACT_CARD32 (pData, swap, count); 831 pData += 4; 832 833 for (i = 0; i < count; i++) 834 SKIP_ARRAY8 (pData, swap); /* prop names */ 835 836 CHECK_COMPLETE_SIZE (iceConn, _SmsOpcode, opcode, 837 length, pData - pStart + SIZEOF (smDeletePropertiesMsg), 838 pStart, IceFatalToProtocol); 839 840 pData = pStart + 8; 841 842 propNames = malloc (count * sizeof (char *)); 843 for (i = 0; i < count; i++) 844 EXTRACT_ARRAY8_AS_STRING (pData, swap, propNames[i]); 845 846 IceDisposeCompleteMessage (iceConn, pStart); 847 848 (*smsConn->callbacks.delete_properties.callback) (smsConn, 849 smsConn->callbacks.delete_properties.manager_data, 850 count, propNames); 851 852 break; 853 } 854 855 case SM_GetProperties: 856 857 CHECK_SIZE_MATCH (iceConn, _SmsOpcode, opcode, 858 length, SIZEOF (smGetPropertiesMsg), 859 IceFatalToProtocol); 860 861 (*smsConn->callbacks.get_properties.callback) (smsConn, 862 smsConn->callbacks.get_properties.manager_data); 863 break; 864 865 default: 866 { 867 _IceErrorBadMinor (iceConn, _SmsOpcode, opcode, IceCanContinue); 868 _IceReadSkip (iceConn, length << 3); 869 break; 870 } 871 } 872} 873