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