diff options
Diffstat (limited to 'contrib/isc-dhcp/omapip/message.c')
-rw-r--r-- | contrib/isc-dhcp/omapip/message.c | 769 |
1 files changed, 769 insertions, 0 deletions
diff --git a/contrib/isc-dhcp/omapip/message.c b/contrib/isc-dhcp/omapip/message.c new file mode 100644 index 0000000..ffdae85 --- /dev/null +++ b/contrib/isc-dhcp/omapip/message.c @@ -0,0 +1,769 @@ +/* message.c + + Subroutines for dealing with message objects. */ + +/* + * Copyright (c) 1999-2000 Internet Software Consortium. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of The Internet Software Consortium nor the names + * of its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND + * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This software has been written for the Internet Software Consortium + * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc. + * To learn more about the Internet Software Consortium, see + * ``http://www.isc.org/''. To learn more about Vixie Enterprises, + * see ``http://www.vix.com''. To learn more about Nominum, Inc., see + * ``http://www.nominum.com''. + */ + +#include <omapip/omapip_p.h> + +OMAPI_OBJECT_ALLOC (omapi_message, + omapi_message_object_t, omapi_type_message) + +omapi_message_object_t *omapi_registered_messages; + +isc_result_t omapi_message_new (omapi_object_t **o, const char *file, int line) +{ + omapi_message_object_t *m; + omapi_object_t *g; + isc_result_t status; + + m = (omapi_message_object_t *)0; + status = omapi_message_allocate (&m, file, line); + if (status != ISC_R_SUCCESS) + return status; + + g = (omapi_object_t *)0; + status = omapi_generic_new (&g, file, line); + if (status != ISC_R_SUCCESS) { + dfree (m, file, line); + return status; + } + status = omapi_object_reference (&m -> inner, g, file, line); + if (status != ISC_R_SUCCESS) { + omapi_object_dereference ((omapi_object_t **)&m, file, line); + omapi_object_dereference (&g, file, line); + return status; + } + status = omapi_object_reference (&g -> outer, + (omapi_object_t *)m, file, line); + + if (status != ISC_R_SUCCESS) { + omapi_object_dereference ((omapi_object_t **)&m, file, line); + omapi_object_dereference (&g, file, line); + return status; + } + + status = omapi_object_reference (o, (omapi_object_t *)m, file, line); + omapi_message_dereference (&m, file, line); + omapi_object_dereference (&g, file, line); + if (status != ISC_R_SUCCESS) + return status; + + return status; +} + +isc_result_t omapi_message_set_value (omapi_object_t *h, + omapi_object_t *id, + omapi_data_string_t *name, + omapi_typed_data_t *value) +{ + omapi_message_object_t *m; + isc_result_t status; + + if (h -> type != omapi_type_message) + return ISC_R_INVALIDARG; + m = (omapi_message_object_t *)h; + + /* Can't set authlen. */ + + /* Can set authenticator, but the value must be typed data. */ + if (!omapi_ds_strcmp (name, "authenticator")) { + if (m -> authenticator) + omapi_typed_data_dereference (&m -> authenticator, + MDL); + omapi_typed_data_reference (&m -> authenticator, value, MDL); + return ISC_R_SUCCESS; + + } else if (!omapi_ds_strcmp (name, "object")) { + if (value -> type != omapi_datatype_object) + return ISC_R_INVALIDARG; + if (m -> object) + omapi_object_dereference (&m -> object, MDL); + omapi_object_reference (&m -> object, value -> u.object, MDL); + return ISC_R_SUCCESS; + + } else if (!omapi_ds_strcmp (name, "notify-object")) { + if (value -> type != omapi_datatype_object) + return ISC_R_INVALIDARG; + if (m -> notify_object) + omapi_object_dereference (&m -> notify_object, MDL); + omapi_object_reference (&m -> notify_object, + value -> u.object, MDL); + return ISC_R_SUCCESS; + + /* Can set authid, but it has to be an integer. */ + } else if (!omapi_ds_strcmp (name, "authid")) { + if (value -> type != omapi_datatype_int) + return ISC_R_INVALIDARG; + m -> authid = value -> u.integer; + return ISC_R_SUCCESS; + + /* Can set op, but it has to be an integer. */ + } else if (!omapi_ds_strcmp (name, "op")) { + if (value -> type != omapi_datatype_int) + return ISC_R_INVALIDARG; + m -> op = value -> u.integer; + return ISC_R_SUCCESS; + + /* Handle also has to be an integer. */ + } else if (!omapi_ds_strcmp (name, "handle")) { + if (value -> type != omapi_datatype_int) + return ISC_R_INVALIDARG; + m -> h = value -> u.integer; + return ISC_R_SUCCESS; + + /* Transaction ID has to be an integer. */ + } else if (!omapi_ds_strcmp (name, "id")) { + if (value -> type != omapi_datatype_int) + return ISC_R_INVALIDARG; + m -> id = value -> u.integer; + return ISC_R_SUCCESS; + + /* Remote transaction ID has to be an integer. */ + } else if (!omapi_ds_strcmp (name, "rid")) { + if (value -> type != omapi_datatype_int) + return ISC_R_INVALIDARG; + m -> rid = value -> u.integer; + return ISC_R_SUCCESS; + } + + /* Try to find some inner object that can take the value. */ + if (h -> inner && h -> inner -> type -> set_value) { + status = ((*(h -> inner -> type -> set_value)) + (h -> inner, id, name, value)); + if (status == ISC_R_SUCCESS) + return status; + } + + return ISC_R_NOTFOUND; +} + +isc_result_t omapi_message_get_value (omapi_object_t *h, + omapi_object_t *id, + omapi_data_string_t *name, + omapi_value_t **value) +{ + omapi_message_object_t *m; + if (h -> type != omapi_type_message) + return ISC_R_INVALIDARG; + m = (omapi_message_object_t *)h; + + /* Look for values that are in the message data structure. */ + if (!omapi_ds_strcmp (name, "authlen")) + return omapi_make_int_value (value, name, (int)m -> authlen, + MDL); + else if (!omapi_ds_strcmp (name, "authenticator")) { + if (m -> authenticator) + return omapi_make_value (value, name, + m -> authenticator, MDL); + else + return ISC_R_NOTFOUND; + } else if (!omapi_ds_strcmp (name, "authid")) { + return omapi_make_int_value (value, + name, (int)m -> authid, MDL); + } else if (!omapi_ds_strcmp (name, "op")) { + return omapi_make_int_value (value, name, (int)m -> op, MDL); + } else if (!omapi_ds_strcmp (name, "handle")) { + return omapi_make_int_value (value, name, (int)m -> h, MDL); + } else if (!omapi_ds_strcmp (name, "id")) { + return omapi_make_int_value (value, name, (int)m -> id, MDL); + } else if (!omapi_ds_strcmp (name, "rid")) { + return omapi_make_int_value (value, name, (int)m -> rid, MDL); + } + + /* See if there's an inner object that has the value. */ + if (h -> inner && h -> inner -> type -> get_value) + return (*(h -> inner -> type -> get_value)) + (h -> inner, id, name, value); + return ISC_R_NOTFOUND; +} + +isc_result_t omapi_message_destroy (omapi_object_t *h, + const char *file, int line) +{ + int i; + + omapi_message_object_t *m; + if (h -> type != omapi_type_message) + return ISC_R_INVALIDARG; + m = (omapi_message_object_t *)h; + if (m -> authenticator) { + omapi_typed_data_dereference (&m -> authenticator, file, line); + } + if (!m -> prev && omapi_registered_messages != m) + omapi_message_unregister (h); + if (m -> id_object) + omapi_object_dereference (&m -> id_object, file, line); + if (m -> object) + omapi_object_dereference (&m -> object, file, line); + if (m -> notify_object) + omapi_object_dereference (&m -> notify_object, file, line); + if (m -> protocol_object) + omapi_protocol_dereference (&m -> protocol_object, file, line); + return ISC_R_SUCCESS; +} + +isc_result_t omapi_message_signal_handler (omapi_object_t *h, + const char *name, va_list ap) +{ + omapi_message_object_t *m; + if (h -> type != omapi_type_message) + return ISC_R_INVALIDARG; + m = (omapi_message_object_t *)h; + + if (!strcmp (name, "status")) { + if (m -> notify_object && + m -> notify_object -> type -> signal_handler) + return ((m -> notify_object -> type -> signal_handler)) + (m -> notify_object, name, ap); + else if (m -> object && m -> object -> type -> signal_handler) + return ((m -> object -> type -> signal_handler)) + (m -> object, name, ap); + } + if (h -> inner && h -> inner -> type -> signal_handler) + return (*(h -> inner -> type -> signal_handler)) (h -> inner, + name, ap); + return ISC_R_NOTFOUND; +} + +/* Write all the published values associated with the object through the + specified connection. */ + +isc_result_t omapi_message_stuff_values (omapi_object_t *c, + omapi_object_t *id, + omapi_object_t *m) +{ + int i; + + if (m -> type != omapi_type_message) + return ISC_R_INVALIDARG; + + if (m -> inner && m -> inner -> type -> stuff_values) + return (*(m -> inner -> type -> stuff_values)) (c, id, + m -> inner); + return ISC_R_SUCCESS; +} + +isc_result_t omapi_message_register (omapi_object_t *mo) +{ + omapi_message_object_t *m; + + if (mo -> type != omapi_type_message) + return ISC_R_INVALIDARG; + m = (omapi_message_object_t *)mo; + + /* Already registered? */ + if (m -> prev || m -> next || omapi_registered_messages == m) + return ISC_R_INVALIDARG; + + if (omapi_registered_messages) { + omapi_object_reference + ((omapi_object_t **)&m -> next, + (omapi_object_t *)omapi_registered_messages, MDL); + omapi_object_reference + ((omapi_object_t **)&omapi_registered_messages -> prev, + (omapi_object_t *)m, MDL); + omapi_object_dereference + ((omapi_object_t **)&omapi_registered_messages, MDL); + } + omapi_object_reference + ((omapi_object_t **)&omapi_registered_messages, + (omapi_object_t *)m, MDL); + return ISC_R_SUCCESS;; +} + +isc_result_t omapi_message_unregister (omapi_object_t *mo) +{ + omapi_message_object_t *m; + omapi_message_object_t *n; + + if (mo -> type != omapi_type_message) + return ISC_R_INVALIDARG; + m = (omapi_message_object_t *)mo; + + /* Not registered? */ + if (!m -> prev && omapi_registered_messages != m) + return ISC_R_INVALIDARG; + + n = (omapi_message_object_t *)0; + if (m -> next) { + omapi_object_reference ((omapi_object_t **)&n, + (omapi_object_t *)m -> next, MDL); + omapi_object_dereference ((omapi_object_t **)&m -> next, MDL); + } + if (m -> prev) { + omapi_message_object_t *tmp = (omapi_message_object_t *)0; + omapi_object_reference ((omapi_object_t **)&tmp, + (omapi_object_t *)m -> prev, MDL); + omapi_object_dereference ((omapi_object_t **)&m -> prev, MDL); + if (tmp -> next) + omapi_object_dereference + ((omapi_object_t **)&tmp -> next, MDL); + if (n) + omapi_object_reference + ((omapi_object_t **)&tmp -> next, + (omapi_object_t *)n, MDL); + omapi_object_dereference ((omapi_object_t **)&tmp, MDL); + } else { + omapi_object_dereference + ((omapi_object_t **)&omapi_registered_messages, MDL); + if (n) + omapi_object_reference + ((omapi_object_t **)&omapi_registered_messages, + (omapi_object_t *)n, MDL); + } + if (n) + omapi_object_dereference ((omapi_object_t **)&n, MDL); + return ISC_R_SUCCESS; +} + +#ifdef DEBUG_PROTOCOL +static const char *omapi_message_op_name(int op) { + switch (op) { + case OMAPI_OP_OPEN: return "OMAPI_OP_OPEN"; + case OMAPI_OP_REFRESH: return "OMAPI_OP_REFRESH"; + case OMAPI_OP_UPDATE: return "OMAPI_OP_UPDATE"; + case OMAPI_OP_STATUS: return "OMAPI_OP_STATUS"; + case OMAPI_OP_DELETE: return "OMAPI_OP_DELETE"; + case OMAPI_OP_NOTIFY: return "OMAPI_OP_NOTIFY"; + default: return "(unknown op)"; + } +} +#endif + +static isc_result_t +omapi_message_process_internal (omapi_object_t *, omapi_object_t *); + +isc_result_t omapi_message_process (omapi_object_t *mo, omapi_object_t *po) +{ + isc_result_t status; +#if defined (DEBUG_MEMORY_LEAKAGE) + unsigned long previous_outstanding = dmalloc_outstanding; +#endif + + status = omapi_message_process_internal (mo, po); + +#if defined (DEBUG_MEMORY_LEAKAGE) && 0 + log_info ("generation %ld: %ld new, %ld outstanding, %ld long-term", + dmalloc_generation, + dmalloc_outstanding - previous_outstanding, + dmalloc_outstanding, dmalloc_longterm); +#endif +#if defined (DEBUG_MEMORY_LEAKAGE) && 0 + dmalloc_dump_outstanding (); +#endif +#if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY) && 0 + dump_rc_history (); +#endif + + return status; +} + +static isc_result_t +omapi_message_process_internal (omapi_object_t *mo, omapi_object_t *po) +{ + omapi_message_object_t *message, *m; + omapi_object_t *object = (omapi_object_t *)0; + omapi_value_t *tv = (omapi_value_t *)0; + unsigned long create, update, exclusive; + unsigned long wsi; + isc_result_t status, waitstatus; + omapi_object_type_t *type; + + if (mo -> type != omapi_type_message) + return ISC_R_INVALIDARG; + message = (omapi_message_object_t *)mo; + +#ifdef DEBUG_PROTOCOL + log_debug ("omapi_message_process(): " + "op=%s handle=%#x id=%#x rid=%#x", + omapi_message_op_name (message -> op), + message -> h, message -> id, message -> rid); +#endif + + if (message -> rid) { + for (m = omapi_registered_messages; m; m = m -> next) + if (m -> id == message -> rid) + break; + /* If we don't have a real message corresponding to + the message ID to which this message claims it is a + response, something's fishy. */ + if (!m) + return ISC_R_NOTFOUND; + /* The authenticator on responses must match the initial + message. */ + if (message -> authid != m -> authid) + return ISC_R_NOTFOUND; + } else { + m = (omapi_message_object_t *)0; + + /* All messages must have an authenticator, with the exception + of messages that are opening a new authenticator. */ + if (omapi_protocol_authenticated (po) && + !message -> id_object && + message -> op != OMAPI_OP_OPEN) { + return omapi_protocol_send_status + (po, message -> id_object, ISC_R_NOKEYS, + message -> id, "No authenticator on message"); + } + } + + switch (message -> op) { + case OMAPI_OP_OPEN: + if (m) { + return omapi_protocol_send_status + (po, message -> id_object, ISC_R_INVALIDARG, + message -> id, "OPEN can't be a response"); + } + + /* Get the type of the requested object, if one was + specified. */ + status = omapi_get_value_str (mo, message -> id_object, + "type", &tv); + if (status == ISC_R_SUCCESS && + (tv -> value -> type == omapi_datatype_data || + tv -> value -> type == omapi_datatype_string)) { + for (type = omapi_object_types; + type; type = type -> next) + if (!omapi_td_strcmp (tv -> value, + type -> name)) + break; + } else + type = (omapi_object_type_t *)0; + if (tv) + omapi_value_dereference (&tv, MDL); + + /* If this object had no authenticator, the requested object + must be an authenticator object. */ + if (omapi_protocol_authenticated (po) && + !message -> id_object && + type != omapi_type_auth_key) { + return omapi_protocol_send_status + (po, message -> id_object, ISC_R_NOKEYS, + message -> id, "No authenticator on message"); + } + + /* Get the create flag. */ + status = omapi_get_value_str (mo, message -> id_object, + "create", &tv); + if (status == ISC_R_SUCCESS) { + status = omapi_get_int_value (&create, tv -> value); + omapi_value_dereference (&tv, MDL); + if (status != ISC_R_SUCCESS) { + return omapi_protocol_send_status + (po, message -> id_object, + status, message -> id, + "invalid create flag value"); + } + } else + create = 0; + + /* Get the update flag. */ + status = omapi_get_value_str (mo, message -> id_object, + "update", &tv); + if (status == ISC_R_SUCCESS) { + status = omapi_get_int_value (&update, tv -> value); + omapi_value_dereference (&tv, MDL); + if (status != ISC_R_SUCCESS) { + return omapi_protocol_send_status + (po, message -> id_object, + status, message -> id, + "invalid update flag value"); + } + } else + update = 0; + + /* Get the exclusive flag. */ + status = omapi_get_value_str (mo, message -> id_object, + "exclusive", &tv); + if (status == ISC_R_SUCCESS) { + status = omapi_get_int_value (&exclusive, tv -> value); + omapi_value_dereference (&tv, MDL); + if (status != ISC_R_SUCCESS) { + return omapi_protocol_send_status + (po, message -> id_object, + status, message -> id, + "invalid exclusive flag value"); + } + } else + exclusive = 0; + + /* If we weren't given a type, look the object up with + the handle. */ + if (!type) { + if (create) { + return omapi_protocol_send_status + (po, message -> id_object, + ISC_R_INVALIDARG, + message -> id, + "type required on create"); + } + goto refresh; + } + + /* If the type doesn't provide a lookup method, we can't + look up the object. */ + if (!type -> lookup) { + return omapi_protocol_send_status + (po, message -> id_object, + ISC_R_NOTIMPLEMENTED, message -> id, + "unsearchable object type"); + } + + status = (*(type -> lookup)) (&object, message -> id_object, + message -> object); + + if (status != ISC_R_SUCCESS && + status != ISC_R_NOTFOUND && + status != ISC_R_NOKEYS) { + return omapi_protocol_send_status + (po, message -> id_object, + status, message -> id, + "object lookup failed"); + } + + /* If we didn't find the object and we aren't supposed to + create it, return an error. */ + if (status == ISC_R_NOTFOUND && !create) { + return omapi_protocol_send_status + (po, message -> id_object, + ISC_R_NOTFOUND, message -> id, + "no object matches specification"); + } + + /* If we found an object, we're supposed to be creating an + object, and we're not supposed to have found an object, + return an error. */ + if (status == ISC_R_SUCCESS && create && exclusive) { + omapi_object_dereference (&object, MDL); + return omapi_protocol_send_status + (po, message -> id_object, + ISC_R_EXISTS, message -> id, + "specified object already exists"); + } + + /* If we're creating the object, do it now. */ + if (!object) { + status = omapi_object_create (&object, + message -> id_object, + type); + if (status != ISC_R_SUCCESS) { + return omapi_protocol_send_status + (po, message -> id_object, + status, message -> id, + "can't create new object"); + } + } + + /* If we're updating it, do so now. */ + if (create || update) { + /* This check does not belong here. */ + if (object -> type == omapi_type_auth_key) { + omapi_object_dereference (&object, MDL); + return omapi_protocol_send_status + (po, message -> id_object, + status, message -> id, + "can't update object"); + } + + status = omapi_object_update (object, + message -> id_object, + message -> object, + message -> h); + if (status != ISC_R_SUCCESS) { + omapi_object_dereference (&object, MDL); + return omapi_protocol_send_status + (po, message -> id_object, + status, message -> id, + "can't update object"); + } + } + + /* If this is an authenticator object, add it to the active + set for the connection. */ + if (object -> type == omapi_type_auth_key) { + omapi_handle_t handle; + status = omapi_object_handle (&handle, object); + if (status != ISC_R_SUCCESS) { + omapi_object_dereference (&object, MDL); + return omapi_protocol_send_status + (po, message -> id_object, + status, message -> id, + "can't select authenticator"); + } + + status = omapi_protocol_add_auth (po, object, handle); + if (status != ISC_R_SUCCESS) { + omapi_object_dereference (&object, MDL); + return omapi_protocol_send_status + (po, message -> id_object, + status, message -> id, + "can't select authenticator"); + } + } + + /* Now send the new contents of the object back in + response. */ + goto send; + + case OMAPI_OP_REFRESH: + refresh: + status = omapi_handle_lookup (&object, message -> h); + if (status != ISC_R_SUCCESS) { + return omapi_protocol_send_status + (po, message -> id_object, + status, message -> id, + "no matching handle"); + } + send: + status = omapi_protocol_send_update (po, message -> id_object, + message -> id, object); + omapi_object_dereference (&object, MDL); + return status; + + case OMAPI_OP_UPDATE: + if (m && m -> object) { + omapi_object_reference (&object, m -> object, MDL); + } else { + status = omapi_handle_lookup (&object, message -> h); + if (status != ISC_R_SUCCESS) { + return omapi_protocol_send_status + (po, message -> id_object, + status, message -> id, + "no matching handle"); + } + } + + if (object -> type == omapi_type_auth_key || + (object -> inner && + object -> inner -> type == omapi_type_auth_key)) { + if (!m) { + omapi_object_dereference (&object, MDL); + return omapi_protocol_send_status + (po, message -> id_object, + status, message -> id, + "cannot update authenticator"); + } + + status = omapi_protocol_add_auth (po, object, + message -> h); + } else { + status = omapi_object_update (object, + message -> id_object, + message -> object, + message -> h); + } + if (status != ISC_R_SUCCESS) { + omapi_object_dereference (&object, MDL); + if (!message -> rid) + return omapi_protocol_send_status + (po, message -> id_object, + status, message -> id, + "can't update object"); + if (m) + omapi_signal ((omapi_object_t *)m, + "status", status, + (omapi_typed_data_t *)0); + return ISC_R_SUCCESS; + } + if (!message -> rid) + status = omapi_protocol_send_status + (po, message -> id_object, ISC_R_SUCCESS, + message -> id, (char *)0); + if (m) + omapi_signal ((omapi_object_t *)m, + "status", ISC_R_SUCCESS, + (omapi_typed_data_t *)0); + return status; + + case OMAPI_OP_NOTIFY: + return omapi_protocol_send_status + (po, message -> id_object, ISC_R_NOTIMPLEMENTED, + message -> id, "notify not implemented yet"); + + case OMAPI_OP_STATUS: + /* The return status of a request. */ + if (!m) + return ISC_R_UNEXPECTED; + + /* Get the wait status. */ + status = omapi_get_value_str (mo, message -> id_object, + "result", &tv); + if (status == ISC_R_SUCCESS) { + status = omapi_get_int_value (&wsi, tv -> value); + waitstatus = wsi; + omapi_value_dereference (&tv, MDL); + if (status != ISC_R_SUCCESS) + waitstatus = ISC_R_UNEXPECTED; + } else + waitstatus = ISC_R_UNEXPECTED; + + status = omapi_get_value_str (mo, message -> id_object, + "message", &tv); + omapi_signal ((omapi_object_t *)m, "status", waitstatus, tv); + if (status == ISC_R_SUCCESS) + omapi_value_dereference (&tv, MDL); + return ISC_R_SUCCESS; + + case OMAPI_OP_DELETE: + status = omapi_handle_lookup (&object, message -> h); + if (status != ISC_R_SUCCESS) { + return omapi_protocol_send_status + (po, message -> id_object, + status, message -> id, + "no matching handle"); + } + + if (!object -> type -> remove) + return omapi_protocol_send_status + (po, message -> id_object, + ISC_R_NOTIMPLEMENTED, message -> id, + "no remove method for object"); + + status = (*(object -> type -> remove)) (object, + message -> id_object); + omapi_object_dereference (&object, MDL); + + return omapi_protocol_send_status (po, message -> id_object, + status, message -> id, + (char *)0); + } + return ISC_R_NOTIMPLEMENTED; +} |