etc/protocols - sync with NetBSD-8
[minix.git] / external / bsd / dhcp / dist / omapip / message.c
blob1b9ba781a0c1cc734bb85f12e7792d56e1e92b85
1 /* $NetBSD: message.c,v 1.1.1.2 2014/07/12 11:57:59 spz Exp $ */
2 /* message.c
4 Subroutines for dealing with message objects. */
6 /*
7 * Copyright (c) 2004,2007,2009,2014 by Internet Systems Consortium, Inc. ("ISC")
8 * Copyright (c) 1999-2003 by Internet Software Consortium
10 * Permission to use, copy, modify, and distribute this software for any
11 * purpose with or without fee is hereby granted, provided that the above
12 * copyright notice and this permission notice appear in all copies.
14 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
15 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
17 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
20 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 * Internet Systems Consortium, Inc.
23 * 950 Charter Street
24 * Redwood City, CA 94063
25 * <info@isc.org>
26 * https://www.isc.org/
30 #include <sys/cdefs.h>
31 __RCSID("$NetBSD: message.c,v 1.1.1.2 2014/07/12 11:57:59 spz Exp $");
33 #include "dhcpd.h"
35 #include <omapip/omapip_p.h>
37 OMAPI_OBJECT_ALLOC (omapi_message,
38 omapi_message_object_t, omapi_type_message)
40 omapi_message_object_t *omapi_registered_messages;
42 isc_result_t omapi_message_new (omapi_object_t **o, const char *file, int line)
44 omapi_message_object_t *m;
45 omapi_object_t *g;
46 isc_result_t status;
48 m = (omapi_message_object_t *)0;
49 status = omapi_message_allocate (&m, file, line);
50 if (status != ISC_R_SUCCESS)
51 return status;
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;
59 status = omapi_object_reference (&m -> inner, g, file, line);
60 if (status != ISC_R_SUCCESS) {
61 omapi_object_dereference ((omapi_object_t **)&m, file, line);
62 omapi_object_dereference (&g, file, line);
63 return status;
65 status = omapi_object_reference (&g -> outer,
66 (omapi_object_t *)m, file, line);
68 if (status != ISC_R_SUCCESS) {
69 omapi_object_dereference ((omapi_object_t **)&m, file, line);
70 omapi_object_dereference (&g, file, line);
71 return status;
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;
80 return status;
83 isc_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)
88 omapi_message_object_t *m;
89 isc_result_t status;
91 if (h -> type != omapi_type_message)
92 return DHCP_R_INVALIDARG;
93 m = (omapi_message_object_t *)h;
95 /* Can't set authlen. */
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;
105 } else if (!omapi_ds_strcmp (name, "object")) {
106 if (value -> type != omapi_datatype_object)
107 return DHCP_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;
113 } else if (!omapi_ds_strcmp (name, "notify-object")) {
114 if (value -> type != omapi_datatype_object)
115 return DHCP_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;
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 DHCP_R_INVALIDARG;
126 m -> authid = value -> u.integer;
127 return ISC_R_SUCCESS;
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 DHCP_R_INVALIDARG;
133 m -> op = value -> u.integer;
134 return ISC_R_SUCCESS;
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 DHCP_R_INVALIDARG;
140 m -> h = value -> u.integer;
141 return ISC_R_SUCCESS;
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 DHCP_R_INVALIDARG;
147 m -> id = value -> u.integer;
148 return ISC_R_SUCCESS;
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 DHCP_R_INVALIDARG;
154 m -> rid = value -> u.integer;
155 return ISC_R_SUCCESS;
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;
166 return ISC_R_NOTFOUND;
169 isc_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)
174 omapi_message_object_t *m;
175 if (h -> type != omapi_type_message)
176 return DHCP_R_INVALIDARG;
177 m = (omapi_message_object_t *)h;
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);
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;
209 isc_result_t omapi_message_destroy (omapi_object_t *h,
210 const char *file, int line)
212 omapi_message_object_t *m;
213 if (h -> type != omapi_type_message)
214 return DHCP_R_INVALIDARG;
215 m = (omapi_message_object_t *)h;
216 if (m -> authenticator) {
217 omapi_typed_data_dereference (&m -> authenticator, file, line);
219 if (!m -> prev && omapi_registered_messages != m)
220 omapi_message_unregister (h);
221 if (m -> id_object)
222 omapi_object_dereference (&m -> id_object, file, line);
223 if (m -> object)
224 omapi_object_dereference (&m -> object, file, line);
225 if (m -> notify_object)
226 omapi_object_dereference (&m -> notify_object, file, line);
227 if (m -> protocol_object)
228 omapi_protocol_dereference (&m -> protocol_object, file, line);
229 return ISC_R_SUCCESS;
232 isc_result_t omapi_message_signal_handler (omapi_object_t *h,
233 const char *name, va_list ap)
235 omapi_message_object_t *m;
236 if (h -> type != omapi_type_message)
237 return DHCP_R_INVALIDARG;
238 m = (omapi_message_object_t *)h;
240 if (!strcmp (name, "status")) {
241 if (m -> notify_object &&
242 m -> notify_object -> type -> signal_handler)
243 return ((m -> notify_object -> type -> signal_handler))
244 (m -> notify_object, name, ap);
245 else if (m -> object && m -> object -> type -> signal_handler)
246 return ((m -> object -> type -> signal_handler))
247 (m -> object, name, ap);
249 if (h -> inner && h -> inner -> type -> signal_handler)
250 return (*(h -> inner -> type -> signal_handler)) (h -> inner,
251 name, ap);
252 return ISC_R_NOTFOUND;
255 /* Write all the published values associated with the object through the
256 specified connection. */
258 isc_result_t omapi_message_stuff_values (omapi_object_t *c,
259 omapi_object_t *id,
260 omapi_object_t *m)
262 if (m -> type != omapi_type_message)
263 return DHCP_R_INVALIDARG;
265 if (m -> inner && m -> inner -> type -> stuff_values)
266 return (*(m -> inner -> type -> stuff_values)) (c, id,
267 m -> inner);
268 return ISC_R_SUCCESS;
271 isc_result_t omapi_message_register (omapi_object_t *mo)
273 omapi_message_object_t *m;
275 if (mo -> type != omapi_type_message)
276 return DHCP_R_INVALIDARG;
277 m = (omapi_message_object_t *)mo;
279 /* Already registered? */
280 if (m -> prev || m -> next || omapi_registered_messages == m)
281 return DHCP_R_INVALIDARG;
283 if (omapi_registered_messages) {
284 omapi_object_reference
285 ((omapi_object_t **)&m -> next,
286 (omapi_object_t *)omapi_registered_messages, MDL);
287 omapi_object_reference
288 ((omapi_object_t **)&omapi_registered_messages -> prev,
289 (omapi_object_t *)m, MDL);
290 omapi_object_dereference
291 ((omapi_object_t **)&omapi_registered_messages, MDL);
293 omapi_object_reference
294 ((omapi_object_t **)&omapi_registered_messages,
295 (omapi_object_t *)m, MDL);
296 return ISC_R_SUCCESS;;
299 isc_result_t omapi_message_unregister (omapi_object_t *mo)
301 omapi_message_object_t *m;
302 omapi_message_object_t *n;
304 if (mo -> type != omapi_type_message)
305 return DHCP_R_INVALIDARG;
306 m = (omapi_message_object_t *)mo;
308 /* Not registered? */
309 if (!m -> prev && omapi_registered_messages != m)
310 return DHCP_R_INVALIDARG;
312 n = (omapi_message_object_t *)0;
313 if (m -> next) {
314 omapi_object_reference ((omapi_object_t **)&n,
315 (omapi_object_t *)m -> next, MDL);
316 omapi_object_dereference ((omapi_object_t **)&m -> next, MDL);
317 omapi_object_dereference ((omapi_object_t **)&n -> prev, MDL);
319 if (m -> prev) {
320 omapi_message_object_t *tmp = (omapi_message_object_t *)0;
321 omapi_object_reference ((omapi_object_t **)&tmp,
322 (omapi_object_t *)m -> prev, MDL);
323 omapi_object_dereference ((omapi_object_t **)&m -> prev, MDL);
324 if (tmp -> next)
325 omapi_object_dereference
326 ((omapi_object_t **)&tmp -> next, MDL);
327 if (n)
328 omapi_object_reference
329 ((omapi_object_t **)&tmp -> next,
330 (omapi_object_t *)n, MDL);
331 omapi_object_dereference ((omapi_object_t **)&tmp, MDL);
332 } else {
333 omapi_object_dereference
334 ((omapi_object_t **)&omapi_registered_messages, MDL);
335 if (n)
336 omapi_object_reference
337 ((omapi_object_t **)&omapi_registered_messages,
338 (omapi_object_t *)n, MDL);
340 if (n)
341 omapi_object_dereference ((omapi_object_t **)&n, MDL);
342 return ISC_R_SUCCESS;
345 #ifdef DEBUG_PROTOCOL
346 static const char *omapi_message_op_name(int op) {
347 switch (op) {
348 case OMAPI_OP_OPEN: return "OMAPI_OP_OPEN";
349 case OMAPI_OP_REFRESH: return "OMAPI_OP_REFRESH";
350 case OMAPI_OP_UPDATE: return "OMAPI_OP_UPDATE";
351 case OMAPI_OP_STATUS: return "OMAPI_OP_STATUS";
352 case OMAPI_OP_DELETE: return "OMAPI_OP_DELETE";
353 case OMAPI_OP_NOTIFY: return "OMAPI_OP_NOTIFY";
354 default: return "(unknown op)";
357 #endif
359 static isc_result_t
360 omapi_message_process_internal (omapi_object_t *, omapi_object_t *);
362 isc_result_t omapi_message_process (omapi_object_t *mo, omapi_object_t *po)
364 isc_result_t status;
365 #if defined (DEBUG_MEMORY_LEAKAGE) && 0
366 unsigned long previous_outstanding = dmalloc_outstanding;
367 #endif
369 status = omapi_message_process_internal (mo, po);
371 #if defined (DEBUG_MEMORY_LEAKAGE) && 0
372 log_info ("generation %ld: %ld new, %ld outstanding, %ld long-term",
373 dmalloc_generation,
374 dmalloc_outstanding - previous_outstanding,
375 dmalloc_outstanding, dmalloc_longterm);
376 #endif
377 #if defined (DEBUG_MEMORY_LEAKAGE) && 0
378 dmalloc_dump_outstanding ();
379 #endif
380 #if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY) && 0
381 dump_rc_history ();
382 #endif
384 return status;
387 static isc_result_t
388 omapi_message_process_internal (omapi_object_t *mo, omapi_object_t *po)
390 omapi_message_object_t *message, *m;
391 omapi_object_t *object = (omapi_object_t *)0;
392 omapi_value_t *tv = (omapi_value_t *)0;
393 unsigned long create, update, exclusive;
394 unsigned long wsi;
395 isc_result_t status, waitstatus;
396 omapi_object_type_t *type;
398 if (mo -> type != omapi_type_message)
399 return DHCP_R_INVALIDARG;
400 message = (omapi_message_object_t *)mo;
402 #ifdef DEBUG_PROTOCOL
403 log_debug ("omapi_message_process(): "
404 "op=%s handle=%#x id=%#x rid=%#x",
405 omapi_message_op_name (message -> op),
406 message -> h, message -> id, message -> rid);
407 #endif
409 if (message -> rid) {
410 for (m = omapi_registered_messages; m; m = m -> next)
411 if (m -> id == message -> rid)
412 break;
413 /* If we don't have a real message corresponding to
414 the message ID to which this message claims it is a
415 response, something's fishy. */
416 if (!m)
417 return ISC_R_NOTFOUND;
418 /* The authenticator on responses must match the initial
419 message. */
420 if (message -> authid != m -> authid)
421 return ISC_R_NOTFOUND;
422 } else {
423 m = (omapi_message_object_t *)0;
425 /* All messages must have an authenticator, with the exception
426 of messages that are opening a new authenticator. */
427 if (omapi_protocol_authenticated(po) &&
428 !message->id_object &&
429 message->op != OMAPI_OP_OPEN) {
430 return omapi_protocol_send_status
431 (po, message->id_object, DHCP_R_NOKEYS,
432 message->id, "No authenticator on message");
436 switch (message -> op) {
437 case OMAPI_OP_OPEN:
438 if (m) {
439 return omapi_protocol_send_status
440 (po, message->id_object, DHCP_R_INVALIDARG,
441 message->id, "OPEN can't be a response");
444 /* Get the type of the requested object, if one was
445 specified. */
446 status = omapi_get_value_str (mo, message -> id_object,
447 "type", &tv);
448 if (status == ISC_R_SUCCESS &&
449 (tv -> value -> type == omapi_datatype_data ||
450 tv -> value -> type == omapi_datatype_string)) {
451 for (type = omapi_object_types;
452 type; type = type -> next)
453 if (!omapi_td_strcmp (tv -> value,
454 type -> name))
455 break;
456 } else
457 type = (omapi_object_type_t *)0;
458 if (tv)
459 omapi_value_dereference (&tv, MDL);
461 /* If this object had no authenticator, the requested object
462 must be an authenticator object. */
463 if (omapi_protocol_authenticated(po) &&
464 !message->id_object &&
465 type != omapi_type_auth_key) {
466 return omapi_protocol_send_status
467 (po, message->id_object, DHCP_R_NOKEYS,
468 message->id, "No authenticator on message");
471 /* Get the create flag. */
472 status = omapi_get_value_str (mo, message -> id_object,
473 "create", &tv);
474 if (status == ISC_R_SUCCESS) {
475 status = omapi_get_int_value (&create, tv -> value);
476 omapi_value_dereference (&tv, MDL);
477 if (status != ISC_R_SUCCESS) {
478 return omapi_protocol_send_status
479 (po, message -> id_object,
480 status, message -> id,
481 "invalid create flag value");
483 } else
484 create = 0;
486 /* Get the update flag. */
487 status = omapi_get_value_str (mo, message -> id_object,
488 "update", &tv);
489 if (status == ISC_R_SUCCESS) {
490 status = omapi_get_int_value (&update, tv -> value);
491 omapi_value_dereference (&tv, MDL);
492 if (status != ISC_R_SUCCESS) {
493 return omapi_protocol_send_status
494 (po, message -> id_object,
495 status, message -> id,
496 "invalid update flag value");
498 } else
499 update = 0;
501 /* Get the exclusive flag. */
502 status = omapi_get_value_str (mo, message -> id_object,
503 "exclusive", &tv);
504 if (status == ISC_R_SUCCESS) {
505 status = omapi_get_int_value (&exclusive, tv -> value);
506 omapi_value_dereference (&tv, MDL);
507 if (status != ISC_R_SUCCESS) {
508 return omapi_protocol_send_status
509 (po, message -> id_object,
510 status, message -> id,
511 "invalid exclusive flag value");
513 } else
514 exclusive = 0;
516 /* If we weren't given a type, look the object up with
517 the handle. */
518 if (!type) {
519 if (create) {
520 return omapi_protocol_send_status
521 (po, message->id_object,
522 DHCP_R_INVALIDARG,
523 message->id,
524 "type required on create");
526 goto refresh;
529 /* If the type doesn't provide a lookup method, we can't
530 look up the object. */
531 if (!type -> lookup) {
532 return omapi_protocol_send_status
533 (po, message -> id_object,
534 ISC_R_NOTIMPLEMENTED, message -> id,
535 "unsearchable object type");
538 status = (*(type -> lookup)) (&object, message -> id_object,
539 message -> object);
541 if (status != ISC_R_SUCCESS &&
542 status != ISC_R_NOTFOUND &&
543 status != DHCP_R_NOKEYS) {
544 return omapi_protocol_send_status
545 (po, message -> id_object,
546 status, message -> id,
547 "object lookup failed");
550 /* If we didn't find the object and we aren't supposed to
551 create it, return an error. */
552 if (status == ISC_R_NOTFOUND && !create) {
553 return omapi_protocol_send_status
554 (po, message -> id_object,
555 ISC_R_NOTFOUND, message -> id,
556 "no object matches specification");
559 /* If we found an object, we're supposed to be creating an
560 object, and we're not supposed to have found an object,
561 return an error. */
562 if (status == ISC_R_SUCCESS && create && exclusive) {
563 omapi_object_dereference (&object, MDL);
564 return omapi_protocol_send_status
565 (po, message -> id_object,
566 ISC_R_EXISTS, message -> id,
567 "specified object already exists");
570 /* If we're creating the object, do it now. */
571 if (!object) {
572 status = omapi_object_create (&object,
573 message -> id_object,
574 type);
575 if (status != ISC_R_SUCCESS) {
576 return omapi_protocol_send_status
577 (po, message -> id_object,
578 status, message -> id,
579 "can't create new object");
583 /* If we're updating it, do so now. */
584 if (create || update) {
585 /* This check does not belong here. */
586 if (object -> type == omapi_type_auth_key) {
587 omapi_object_dereference (&object, MDL);
588 return omapi_protocol_send_status
589 (po, message -> id_object,
590 status, message -> id,
591 "can't update object");
594 status = omapi_object_update (object,
595 message -> id_object,
596 message -> object,
597 message -> h);
598 if (status != ISC_R_SUCCESS) {
599 omapi_object_dereference (&object, MDL);
600 return omapi_protocol_send_status
601 (po, message -> id_object,
602 status, message -> id,
603 "can't update object");
607 /* If this is an authenticator object, add it to the active
608 set for the connection. */
609 if (object -> type == omapi_type_auth_key) {
610 omapi_handle_t handle;
611 status = omapi_object_handle (&handle, object);
612 if (status != ISC_R_SUCCESS) {
613 omapi_object_dereference (&object, MDL);
614 return omapi_protocol_send_status
615 (po, message -> id_object,
616 status, message -> id,
617 "can't select authenticator");
620 status = omapi_protocol_add_auth (po, object, handle);
621 if (status != ISC_R_SUCCESS) {
622 omapi_object_dereference (&object, MDL);
623 return omapi_protocol_send_status
624 (po, message -> id_object,
625 status, message -> id,
626 "can't select authenticator");
630 /* Now send the new contents of the object back in
631 response. */
632 goto send;
634 case OMAPI_OP_REFRESH:
635 refresh:
636 status = omapi_handle_lookup (&object, message -> h);
637 if (status != ISC_R_SUCCESS) {
638 return omapi_protocol_send_status
639 (po, message -> id_object,
640 status, message -> id,
641 "no matching handle");
643 send:
644 status = omapi_protocol_send_update (po, message -> id_object,
645 message -> id, object);
646 omapi_object_dereference (&object, MDL);
647 return status;
649 case OMAPI_OP_UPDATE:
650 if (m && m -> object) {
651 status = omapi_object_reference (&object, m -> object,
652 MDL);
653 } else {
654 status = omapi_handle_lookup (&object, message -> h);
655 if (status != ISC_R_SUCCESS) {
656 return omapi_protocol_send_status
657 (po, message -> id_object,
658 status, message -> id,
659 "no matching handle");
663 if (object -> type == omapi_type_auth_key ||
664 (object -> inner &&
665 object -> inner -> type == omapi_type_auth_key)) {
666 if (!m) {
667 omapi_object_dereference (&object, MDL);
668 return omapi_protocol_send_status
669 (po, message -> id_object,
670 status, message -> id,
671 "cannot update authenticator");
674 status = omapi_protocol_add_auth (po, object,
675 message -> h);
676 } else {
677 status = omapi_object_update (object,
678 message -> id_object,
679 message -> object,
680 message -> h);
682 if (status != ISC_R_SUCCESS) {
683 omapi_object_dereference (&object, MDL);
684 if (!message -> rid)
685 return omapi_protocol_send_status
686 (po, message -> id_object,
687 status, message -> id,
688 "can't update object");
689 if (m)
690 omapi_signal ((omapi_object_t *)m,
691 "status", status,
692 (omapi_typed_data_t *)0);
693 return ISC_R_SUCCESS;
695 if (!message -> rid)
696 status = omapi_protocol_send_status
697 (po, message -> id_object, ISC_R_SUCCESS,
698 message -> id, (char *)0);
699 if (m) {
700 omapi_signal ((omapi_object_t *)m,
701 "status", ISC_R_SUCCESS,
702 (omapi_typed_data_t *)0);
703 omapi_message_unregister ((omapi_object_t *)m);
706 omapi_object_dereference (&object, MDL);
708 return status;
710 case OMAPI_OP_NOTIFY:
711 return omapi_protocol_send_status
712 (po, message -> id_object, ISC_R_NOTIMPLEMENTED,
713 message -> id, "notify not implemented yet");
715 case OMAPI_OP_STATUS:
716 /* The return status of a request. */
717 if (!m)
718 return ISC_R_UNEXPECTED;
720 /* Get the wait status. */
721 status = omapi_get_value_str (mo, message -> id_object,
722 "result", &tv);
723 if (status == ISC_R_SUCCESS) {
724 status = omapi_get_int_value (&wsi, tv -> value);
725 waitstatus = wsi;
726 omapi_value_dereference (&tv, MDL);
727 if (status != ISC_R_SUCCESS)
728 waitstatus = ISC_R_UNEXPECTED;
729 } else
730 waitstatus = ISC_R_UNEXPECTED;
732 status = omapi_get_value_str (mo, message -> id_object,
733 "message", &tv);
734 omapi_signal ((omapi_object_t *)m, "status", waitstatus, tv);
735 if (status == ISC_R_SUCCESS)
736 omapi_value_dereference (&tv, MDL);
738 omapi_message_unregister((omapi_object_t *)m);
740 return ISC_R_SUCCESS;
742 case OMAPI_OP_DELETE:
743 status = omapi_handle_lookup (&object, message -> h);
744 if (status != ISC_R_SUCCESS) {
745 return omapi_protocol_send_status
746 (po, message -> id_object,
747 status, message -> id,
748 "no matching handle");
751 if (!object -> type -> remove)
752 return omapi_protocol_send_status
753 (po, message -> id_object,
754 ISC_R_NOTIMPLEMENTED, message -> id,
755 "no remove method for object");
757 status = (*(object -> type -> remove)) (object,
758 message -> id_object);
759 omapi_object_dereference (&object, MDL);
761 return omapi_protocol_send_status (po, message -> id_object,
762 status, message -> id,
763 (char *)0);
765 return ISC_R_NOTIMPLEMENTED;