1/* message.c 2 3 Subroutines for dealing with message objects. */ 4 5/* 6 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 7 * Copyright (c) 1999-2003 by Internet Software Consortium 8 * 9 * Permission to use, copy, modify, and distribute this software for any 10 * purpose with or without fee is hereby granted, provided that the above 11 * copyright notice and this permission notice appear in all copies. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 19 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20 * 21 * Internet Systems Consortium, Inc. 22 * 950 Charter Street 23 * Redwood City, CA 94063 24 * <info@isc.org> 25 * http://www.isc.org/ 26 * 27 * This software has been written for Internet Systems Consortium 28 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc. 29 * To learn more about Internet Systems Consortium, see 30 * ``http://www.isc.org/''. To learn more about Vixie Enterprises, 31 * see ``http://www.vix.com''. To learn more about Nominum, Inc., see 32 * ``http://www.nominum.com''. 33 */ 34 35#include <omapip/omapip_p.h> 36 37OMAPI_OBJECT_ALLOC (omapi_message, 38 omapi_message_object_t, omapi_type_message) 39 40omapi_message_object_t *omapi_registered_messages; 41 42isc_result_t omapi_message_new (omapi_object_t **o, const char *file, int line) 43{ 44 omapi_message_object_t *m; 45 omapi_object_t *g; 46 isc_result_t status; 47 48 m = (omapi_message_object_t *)0; 49 status = omapi_message_allocate (&m, file, line); 50 if (status != ISC_R_SUCCESS) 51 return status; 52 53 g = (omapi_object_t *)0; 54 status = omapi_generic_new (&g, file, line); 55 if (status != ISC_R_SUCCESS) { 56 dfree (m, file, line); 57 return status; 58 } 59 status = omapi_object_reference (&m -> inner, g, file, line); 60 if (status != ISC_R_SUCCESS) { 61 omapi_object_dereference ((void *)&m, file, line); 62 omapi_object_dereference (&g, file, line); 63 return status; 64 } 65 status = omapi_object_reference (&g -> outer, 66 (omapi_object_t *)m, file, line); 67 68 if (status != ISC_R_SUCCESS) { 69 omapi_object_dereference ((void *)&m, file, line); 70 omapi_object_dereference (&g, file, line); 71 return status; 72 } 73 74 status = omapi_object_reference (o, (omapi_object_t *)m, file, line); 75 omapi_message_dereference (&m, file, line); 76 omapi_object_dereference (&g, file, line); 77 if (status != ISC_R_SUCCESS) 78 return status; 79 80 return status; 81} 82 83isc_result_t omapi_message_set_value (omapi_object_t *h, 84 omapi_object_t *id, 85 omapi_data_string_t *name, 86 omapi_typed_data_t *value) 87{ 88 omapi_message_object_t *m; 89 isc_result_t status; 90 91 if (h -> type != omapi_type_message) 92 return ISC_R_INVALIDARG; 93 m = (omapi_message_object_t *)h; 94 95 /* Can't set authlen. */ 96 97 /* Can set authenticator, but the value must be typed data. */ 98 if (!omapi_ds_strcmp (name, "authenticator")) { 99 if (m -> authenticator) 100 omapi_typed_data_dereference (&m -> authenticator, 101 MDL); 102 omapi_typed_data_reference (&m -> authenticator, value, MDL); 103 return ISC_R_SUCCESS; 104 105 } else if (!omapi_ds_strcmp (name, "object")) { 106 if (value -> type != omapi_datatype_object) 107 return ISC_R_INVALIDARG; 108 if (m -> object) 109 omapi_object_dereference (&m -> object, MDL); 110 omapi_object_reference (&m -> object, value -> u.object, MDL); 111 return ISC_R_SUCCESS; 112 113 } else if (!omapi_ds_strcmp (name, "notify-object")) { 114 if (value -> type != omapi_datatype_object) 115 return ISC_R_INVALIDARG; 116 if (m -> notify_object) 117 omapi_object_dereference (&m -> notify_object, MDL); 118 omapi_object_reference (&m -> notify_object, 119 value -> u.object, MDL); 120 return ISC_R_SUCCESS; 121 122 /* Can set authid, but it has to be an integer. */ 123 } else if (!omapi_ds_strcmp (name, "authid")) { 124 if (value -> type != omapi_datatype_int) 125 return ISC_R_INVALIDARG; 126 m -> authid = value -> u.integer; 127 return ISC_R_SUCCESS; 128 129 /* Can set op, but it has to be an integer. */ 130 } else if (!omapi_ds_strcmp (name, "op")) { 131 if (value -> type != omapi_datatype_int) 132 return ISC_R_INVALIDARG; 133 m -> op = value -> u.integer; 134 return ISC_R_SUCCESS; 135 136 /* Handle also has to be an integer. */ 137 } else if (!omapi_ds_strcmp (name, "handle")) { 138 if (value -> type != omapi_datatype_int) 139 return ISC_R_INVALIDARG; 140 m -> h = value -> u.integer; 141 return ISC_R_SUCCESS; 142 143 /* Transaction ID has to be an integer. */ 144 } else if (!omapi_ds_strcmp (name, "id")) { 145 if (value -> type != omapi_datatype_int) 146 return ISC_R_INVALIDARG; 147 m -> id = value -> u.integer; 148 return ISC_R_SUCCESS; 149 150 /* Remote transaction ID has to be an integer. */ 151 } else if (!omapi_ds_strcmp (name, "rid")) { 152 if (value -> type != omapi_datatype_int) 153 return ISC_R_INVALIDARG; 154 m -> rid = value -> u.integer; 155 return ISC_R_SUCCESS; 156 } 157 158 /* Try to find some inner object that can take the value. */ 159 if (h -> inner && h -> inner -> type -> set_value) { 160 status = ((*(h -> inner -> type -> set_value)) 161 (h -> inner, id, name, value)); 162 if (status == ISC_R_SUCCESS) 163 return status; 164 } 165 166 return ISC_R_NOTFOUND; 167} 168 169isc_result_t omapi_message_get_value (omapi_object_t *h, 170 omapi_object_t *id, 171 omapi_data_string_t *name, 172 omapi_value_t **value) 173{ 174 omapi_message_object_t *m; 175 if (h -> type != omapi_type_message) 176 return ISC_R_INVALIDARG; 177 m = (omapi_message_object_t *)h; 178 179 /* Look for values that are in the message data structure. */ 180 if (!omapi_ds_strcmp (name, "authlen")) 181 return omapi_make_int_value (value, name, (int)m -> authlen, 182 MDL); 183 else if (!omapi_ds_strcmp (name, "authenticator")) { 184 if (m -> authenticator) 185 return omapi_make_value (value, name, 186 m -> authenticator, MDL); 187 else 188 return ISC_R_NOTFOUND; 189 } else if (!omapi_ds_strcmp (name, "authid")) { 190 return omapi_make_int_value (value, 191 name, (int)m -> authid, MDL); 192 } else if (!omapi_ds_strcmp (name, "op")) { 193 return omapi_make_int_value (value, name, (int)m -> op, MDL); 194 } else if (!omapi_ds_strcmp (name, "handle")) { 195 return omapi_make_int_value (value, name, (int)m -> h, MDL); 196 } else if (!omapi_ds_strcmp (name, "id")) { 197 return omapi_make_int_value (value, name, (int)m -> id, MDL); 198 } else if (!omapi_ds_strcmp (name, "rid")) { 199 return omapi_make_int_value (value, name, (int)m -> rid, MDL); 200 } 201 202 /* See if there's an inner object that has the value. */ 203 if (h -> inner && h -> inner -> type -> get_value) 204 return (*(h -> inner -> type -> get_value)) 205 (h -> inner, id, name, value); 206 return ISC_R_NOTFOUND; 207} 208 209isc_result_t omapi_message_destroy (omapi_object_t *h, 210 const char *file, int line) 211{ 212 213 omapi_message_object_t *m; 214 if (h -> type != omapi_type_message) 215 return ISC_R_INVALIDARG; 216 m = (omapi_message_object_t *)h; 217 if (m -> authenticator) { 218 omapi_typed_data_dereference (&m -> authenticator, file, line); 219 } 220 if (!m -> prev && omapi_registered_messages != m) 221 omapi_message_unregister (h); 222 if (m -> id_object) 223 omapi_object_dereference (&m -> id_object, file, line); 224 if (m -> object) 225 omapi_object_dereference (&m -> object, file, line); 226 if (m -> notify_object) 227 omapi_object_dereference (&m -> notify_object, file, line); 228 if (m -> protocol_object) 229 omapi_protocol_dereference (&m -> protocol_object, file, line); 230 return ISC_R_SUCCESS; 231} 232 233isc_result_t omapi_message_signal_handler (omapi_object_t *h, 234 const char *name, va_list ap) 235{ 236 omapi_message_object_t *m; 237 if (h -> type != omapi_type_message) 238 return ISC_R_INVALIDARG; 239 m = (omapi_message_object_t *)h; 240 241 if (!strcmp (name, "status")) { 242 if (m -> notify_object && 243 m -> notify_object -> type -> signal_handler) 244 return ((m -> notify_object -> type -> signal_handler)) 245 (m -> notify_object, name, ap); 246 else if (m -> object && m -> object -> type -> signal_handler) 247 return ((m -> object -> type -> signal_handler)) 248 (m -> object, name, ap); 249 } 250 if (h -> inner && h -> inner -> type -> signal_handler) 251 return (*(h -> inner -> type -> signal_handler)) (h -> inner, 252 name, ap); 253 return ISC_R_NOTFOUND; 254} 255 256/* Write all the published values associated with the object through the 257 specified connection. */ 258 259isc_result_t omapi_message_stuff_values (omapi_object_t *c, 260 omapi_object_t *id, 261 omapi_object_t *m) 262{ 263 264 if (m -> type != omapi_type_message) 265 return ISC_R_INVALIDARG; 266 267 if (m -> inner && m -> inner -> type -> stuff_values) 268 return (*(m -> inner -> type -> stuff_values)) (c, id, 269 m -> inner); 270 return ISC_R_SUCCESS; 271} 272 273isc_result_t omapi_message_register (omapi_object_t *mo) 274{ 275 omapi_message_object_t *m; 276 277 if (mo -> type != omapi_type_message) 278 return ISC_R_INVALIDARG; 279 m = (omapi_message_object_t *)mo; 280 281 /* Already registered? */ 282 if (m -> prev || m -> next || omapi_registered_messages == m) 283 return ISC_R_INVALIDARG; 284 285 if (omapi_registered_messages) { 286 omapi_object_reference 287 ((omapi_object_t **)&m -> next, 288 (omapi_object_t *)omapi_registered_messages, MDL); 289 omapi_object_reference 290 ((omapi_object_t **)&omapi_registered_messages -> prev, 291 (omapi_object_t *)m, MDL); 292 omapi_object_dereference 293 ((void *)&omapi_registered_messages, MDL); 294 } 295 omapi_object_reference 296 ((void *)&omapi_registered_messages, 297 (omapi_object_t *)m, MDL); 298 return ISC_R_SUCCESS;; 299} 300 301isc_result_t omapi_message_unregister (omapi_object_t *mo) 302{ 303 omapi_message_object_t *m; 304 omapi_message_object_t *n; 305 306 if (mo -> type != omapi_type_message) 307 return ISC_R_INVALIDARG; 308 m = (omapi_message_object_t *)mo; 309 310 /* Not registered? */ 311 if (!m -> prev && omapi_registered_messages != m) 312 return ISC_R_INVALIDARG; 313 314 n = (omapi_message_object_t *)0; 315 if (m -> next) { 316 omapi_object_reference ((void *)&n, 317 (omapi_object_t *)m -> next, MDL); 318 omapi_object_dereference ((omapi_object_t **)&m -> next, MDL); 319 omapi_object_dereference ((omapi_object_t **)&n -> prev, MDL); 320 } 321 if (m -> prev) { 322 omapi_message_object_t *tmp = (omapi_message_object_t *)0; 323 omapi_object_reference ((void *)&tmp, 324 (omapi_object_t *)m -> prev, MDL); 325 omapi_object_dereference ((omapi_object_t **)&m -> prev, MDL); 326 if (tmp -> next) 327 omapi_object_dereference 328 ((omapi_object_t **)&tmp -> next, MDL); 329 if (n) 330 omapi_object_reference 331 ((omapi_object_t **)&tmp -> next, 332 (omapi_object_t *)n, MDL); 333 omapi_object_dereference ((void *)&tmp, MDL); 334 } else { 335 omapi_object_dereference 336 ((void *)&omapi_registered_messages, MDL); 337 if (n) 338 omapi_object_reference 339 ((void *)&omapi_registered_messages, 340 (omapi_object_t *)n, MDL); 341 } 342 if (n) 343 omapi_object_dereference ((void *)&n, MDL); 344 return ISC_R_SUCCESS; 345} 346 347#ifdef DEBUG_PROTOCOL 348static const char *omapi_message_op_name(int op) { 349 switch (op) { 350 case OMAPI_OP_OPEN: return "OMAPI_OP_OPEN"; 351 case OMAPI_OP_REFRESH: return "OMAPI_OP_REFRESH"; 352 case OMAPI_OP_UPDATE: return "OMAPI_OP_UPDATE"; 353 case OMAPI_OP_STATUS: return "OMAPI_OP_STATUS"; 354 case OMAPI_OP_DELETE: return "OMAPI_OP_DELETE"; 355 case OMAPI_OP_NOTIFY: return "OMAPI_OP_NOTIFY"; 356 default: return "(unknown op)"; 357 } 358} 359#endif 360 361static isc_result_t 362omapi_message_process_internal (omapi_object_t *, omapi_object_t *); 363 364isc_result_t omapi_message_process (omapi_object_t *mo, omapi_object_t *po) 365{ 366 isc_result_t status; 367#if defined (DEBUG_MEMORY_LEAKAGE) 368 unsigned long previous_outstanding = dmalloc_outstanding; 369#endif 370 371 status = omapi_message_process_internal (mo, po); 372 373#if defined (DEBUG_MEMORY_LEAKAGE) && 0 374 log_info ("generation %ld: %ld new, %ld outstanding, %ld long-term", 375 dmalloc_generation, 376 dmalloc_outstanding - previous_outstanding, 377 dmalloc_outstanding, dmalloc_longterm); 378#endif 379#if defined (DEBUG_MEMORY_LEAKAGE) && 0 380 dmalloc_dump_outstanding (); 381#endif 382#if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY) && 0 383 dump_rc_history (); 384#endif 385 386 return status; 387} 388 389static isc_result_t 390omapi_message_process_internal (omapi_object_t *mo, omapi_object_t *po) 391{ 392 omapi_message_object_t *message, *m; 393 omapi_object_t *object = (omapi_object_t *)0; 394 omapi_value_t *tv = (omapi_value_t *)0; 395 unsigned long create, update, exclusive; 396 unsigned long wsi; 397 isc_result_t status, waitstatus; 398 omapi_object_type_t *type; 399 400 if (mo -> type != omapi_type_message) 401 return ISC_R_INVALIDARG; 402 message = (omapi_message_object_t *)mo; 403 404#ifdef DEBUG_PROTOCOL 405 log_debug ("omapi_message_process(): " 406 "op=%s handle=%#x id=%#x rid=%#x", 407 omapi_message_op_name (message -> op), 408 message -> h, message -> id, message -> rid); 409#endif 410 411 if (message -> rid) { 412 for (m = omapi_registered_messages; m; m = m -> next) 413 if (m -> id == message -> rid) 414 break; 415 /* If we don't have a real message corresponding to 416 the message ID to which this message claims it is a 417 response, something's fishy. */ 418 if (!m) 419 return ISC_R_NOTFOUND; 420 /* The authenticator on responses must match the initial 421 message. */ 422 if (message -> authid != m -> authid) 423 return ISC_R_NOTFOUND; 424 } else { 425 m = (omapi_message_object_t *)0; 426 427 /* All messages must have an authenticator, with the exception 428 of messages that are opening a new authenticator. */ 429 if (omapi_protocol_authenticated (po) && 430 !message -> id_object && 431 message -> op != OMAPI_OP_OPEN) { 432 return omapi_protocol_send_status 433 (po, message -> id_object, ISC_R_NOKEYS, 434 message -> id, "No authenticator on message"); 435 } 436 } 437 438 switch (message -> op) { 439 case OMAPI_OP_OPEN: 440 if (m) { 441 return omapi_protocol_send_status 442 (po, message -> id_object, ISC_R_INVALIDARG, 443 message -> id, "OPEN can't be a response"); 444 } 445 446 /* Get the type of the requested object, if one was 447 specified. */ 448 status = omapi_get_value_str (mo, message -> id_object, 449 "type", &tv); 450 if (status == ISC_R_SUCCESS && 451 (tv -> value -> type == omapi_datatype_data || 452 tv -> value -> type == omapi_datatype_string)) { 453 for (type = omapi_object_types; 454 type; type = type -> next) 455 if (!omapi_td_strcmp (tv -> value, 456 type -> name)) 457 break; 458 } else 459 type = (omapi_object_type_t *)0; 460 if (tv) 461 omapi_value_dereference (&tv, MDL); 462 463 /* If this object had no authenticator, the requested object 464 must be an authenticator object. */ 465 if (omapi_protocol_authenticated (po) && 466 !message -> id_object && 467 type != omapi_type_auth_key) { 468 return omapi_protocol_send_status 469 (po, message -> id_object, ISC_R_NOKEYS, 470 message -> id, "No authenticator on message"); 471 } 472 473 /* Get the create flag. */ 474 status = omapi_get_value_str (mo, message -> id_object, 475 "create", &tv); 476 if (status == ISC_R_SUCCESS) { 477 status = omapi_get_int_value (&create, tv -> value); 478 omapi_value_dereference (&tv, MDL); 479 if (status != ISC_R_SUCCESS) { 480 return omapi_protocol_send_status 481 (po, message -> id_object, 482 status, message -> id, 483 "invalid create flag value"); 484 } 485 } else 486 create = 0; 487 488 /* Get the update flag. */ 489 status = omapi_get_value_str (mo, message -> id_object, 490 "update", &tv); 491 if (status == ISC_R_SUCCESS) { 492 status = omapi_get_int_value (&update, tv -> value); 493 omapi_value_dereference (&tv, MDL); 494 if (status != ISC_R_SUCCESS) { 495 return omapi_protocol_send_status 496 (po, message -> id_object, 497 status, message -> id, 498 "invalid update flag value"); 499 } 500 } else 501 update = 0; 502 503 /* Get the exclusive flag. */ 504 status = omapi_get_value_str (mo, message -> id_object, 505 "exclusive", &tv); 506 if (status == ISC_R_SUCCESS) { 507 status = omapi_get_int_value (&exclusive, tv -> value); 508 omapi_value_dereference (&tv, MDL); 509 if (status != ISC_R_SUCCESS) { 510 return omapi_protocol_send_status 511 (po, message -> id_object, 512 status, message -> id, 513 "invalid exclusive flag value"); 514 } 515 } else 516 exclusive = 0; 517 518 /* If we weren't given a type, look the object up with 519 the handle. */ 520 if (!type) { 521 if (create) { 522 return omapi_protocol_send_status 523 (po, message -> id_object, 524 ISC_R_INVALIDARG, 525 message -> id, 526 "type required on create"); 527 } 528 goto refresh; 529 } 530 531 /* If the type doesn't provide a lookup method, we can't 532 look up the object. */ 533 if (!type -> lookup) { 534 return omapi_protocol_send_status 535 (po, message -> id_object, 536 ISC_R_NOTIMPLEMENTED, message -> id, 537 "unsearchable object type"); 538 } 539 540 status = (*(type -> lookup)) (&object, message -> id_object, 541 message -> object); 542 543 if (status != ISC_R_SUCCESS && 544 status != ISC_R_NOTFOUND && 545 status != ISC_R_NOKEYS) { 546 return omapi_protocol_send_status 547 (po, message -> id_object, 548 status, message -> id, 549 "object lookup failed"); 550 } 551 552 /* If we didn't find the object and we aren't supposed to 553 create it, return an error. */ 554 if (status == ISC_R_NOTFOUND && !create) { 555 return omapi_protocol_send_status 556 (po, message -> id_object, 557 ISC_R_NOTFOUND, message -> id, 558 "no object matches specification"); 559 } 560 561 /* If we found an object, we're supposed to be creating an 562 object, and we're not supposed to have found an object, 563 return an error. */ 564 if (status == ISC_R_SUCCESS && create && exclusive) { 565 omapi_object_dereference (&object, MDL); 566 return omapi_protocol_send_status 567 (po, message -> id_object, 568 ISC_R_EXISTS, message -> id, 569 "specified object already exists"); 570 } 571 572 /* If we're creating the object, do it now. */ 573 if (!object) { 574 status = omapi_object_create (&object, 575 message -> id_object, 576 type); 577 if (status != ISC_R_SUCCESS) { 578 return omapi_protocol_send_status 579 (po, message -> id_object, 580 status, message -> id, 581 "can't create new object"); 582 } 583 } 584 585 /* If we're updating it, do so now. */ 586 if (create || update) { 587 /* This check does not belong here. */ 588 if (object -> type == omapi_type_auth_key) { 589 omapi_object_dereference (&object, MDL); 590 return omapi_protocol_send_status 591 (po, message -> id_object, 592 status, message -> id, 593 "can't update object"); 594 } 595 596 status = omapi_object_update (object, 597 message -> id_object, 598 message -> object, 599 message -> h); 600 if (status != ISC_R_SUCCESS) { 601 omapi_object_dereference (&object, MDL); 602 return omapi_protocol_send_status 603 (po, message -> id_object, 604 status, message -> id, 605 "can't update object"); 606 } 607 } 608 609 /* If this is an authenticator object, add it to the active 610 set for the connection. */ 611 if (object -> type == omapi_type_auth_key) { 612 omapi_handle_t handle; 613 status = omapi_object_handle (&handle, object); 614 if (status != ISC_R_SUCCESS) { 615 omapi_object_dereference (&object, MDL); 616 return omapi_protocol_send_status 617 (po, message -> id_object, 618 status, message -> id, 619 "can't select authenticator"); 620 } 621 622 status = omapi_protocol_add_auth (po, object, handle); 623 if (status != ISC_R_SUCCESS) { 624 omapi_object_dereference (&object, MDL); 625 return omapi_protocol_send_status 626 (po, message -> id_object, 627 status, message -> id, 628 "can't select authenticator"); 629 } 630 } 631 632 /* Now send the new contents of the object back in 633 response. */ 634 goto send; 635 636 case OMAPI_OP_REFRESH: 637 refresh: 638 status = omapi_handle_lookup (&object, message -> h); 639 if (status != ISC_R_SUCCESS) { 640 return omapi_protocol_send_status 641 (po, message -> id_object, 642 status, message -> id, 643 "no matching handle"); 644 } 645 send: 646 status = omapi_protocol_send_update (po, message -> id_object, 647 message -> id, object); 648 omapi_object_dereference (&object, MDL); 649 return status; 650 651 case OMAPI_OP_UPDATE: 652 if (m && m -> object) { 653 status = omapi_object_reference (&object, m -> object, 654 MDL); 655 } else { 656 status = omapi_handle_lookup (&object, message -> h); 657 if (status != ISC_R_SUCCESS) { 658 return omapi_protocol_send_status 659 (po, message -> id_object, 660 status, message -> id, 661 "no matching handle"); 662 } 663 } 664 665 if (object -> type == omapi_type_auth_key || 666 (object -> inner && 667 object -> inner -> type == omapi_type_auth_key)) { 668 if (!m) { 669 omapi_object_dereference (&object, MDL); 670 return omapi_protocol_send_status 671 (po, message -> id_object, 672 status, message -> id, 673 "cannot update authenticator"); 674 } 675 676 status = omapi_protocol_add_auth (po, object, 677 message -> h); 678 } else { 679 status = omapi_object_update (object, 680 message -> id_object, 681 message -> object, 682 message -> h); 683 } 684 if (status != ISC_R_SUCCESS) { 685 omapi_object_dereference (&object, MDL); 686 if (!message -> rid) 687 return omapi_protocol_send_status 688 (po, message -> id_object, 689 status, message -> id, 690 "can't update object"); 691 if (m) 692 omapi_signal ((omapi_object_t *)m, 693 "status", status, 694 (omapi_typed_data_t *)0); 695 return ISC_R_SUCCESS; 696 } 697 if (!message -> rid) 698 status = omapi_protocol_send_status 699 (po, message -> id_object, ISC_R_SUCCESS, 700 message -> id, (char *)0); 701 if (m) { 702 omapi_signal ((omapi_object_t *)m, 703 "status", ISC_R_SUCCESS, 704 (omapi_typed_data_t *)0); 705 omapi_message_unregister ((omapi_object_t *)m); 706 } 707 708 omapi_object_dereference (&object, MDL); 709 710 return status; 711 712 case OMAPI_OP_NOTIFY: 713 return omapi_protocol_send_status 714 (po, message -> id_object, ISC_R_NOTIMPLEMENTED, 715 message -> id, "notify not implemented yet"); 716 717 case OMAPI_OP_STATUS: 718 /* The return status of a request. */ 719 if (!m) 720 return ISC_R_UNEXPECTED; 721 722 /* Get the wait status. */ 723 status = omapi_get_value_str (mo, message -> id_object, 724 "result", &tv); 725 if (status == ISC_R_SUCCESS) { 726 status = omapi_get_int_value (&wsi, tv -> value); 727 waitstatus = wsi; 728 omapi_value_dereference (&tv, MDL); 729 if (status != ISC_R_SUCCESS) 730 waitstatus = ISC_R_UNEXPECTED; 731 } else 732 waitstatus = ISC_R_UNEXPECTED; 733 734 status = omapi_get_value_str (mo, message -> id_object, 735 "message", &tv); 736 omapi_signal ((omapi_object_t *)m, "status", waitstatus, tv); 737 if (status == ISC_R_SUCCESS) 738 omapi_value_dereference (&tv, MDL); 739 740 omapi_message_unregister((omapi_object_t *)m); 741 742 return ISC_R_SUCCESS; 743 744 case OMAPI_OP_DELETE: 745 status = omapi_handle_lookup (&object, message -> h); 746 if (status != ISC_R_SUCCESS) { 747 return omapi_protocol_send_status 748 (po, message -> id_object, 749 status, message -> id, 750 "no matching handle"); 751 } 752 753 if (!object -> type -> remove) 754 return omapi_protocol_send_status 755 (po, message -> id_object, 756 ISC_R_NOTIMPLEMENTED, message -> id, 757 "no remove method for object"); 758 759 status = (*(object -> type -> remove)) (object, 760 message -> id_object); 761 omapi_object_dereference (&object, MDL); 762 763 return omapi_protocol_send_status (po, message -> id_object, 764 status, message -> id, 765 (char *)0); 766 } 767 return ISC_R_NOTIMPLEMENTED; 768} 769