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