]> git.ipfire.org Git - thirdparty/dhcp.git/blame - omapip/protocol.c
Fix up one mistake from last night's fixes.
[thirdparty/dhcp.git] / omapip / protocol.c
CommitLineData
61b844bf
TL
1/* protocol.c
2
3 Functions supporting the object management protocol... */
4
5/*
6 * Copyright (c) 1996-1999 Internet Software Consortium.
7 * Use is subject to license terms which appear in the file named
8 * ISC-LICENSE that should have accompanied this file when you
9 * received it. If a file named ISC-LICENSE did not accompany this
10 * file, or you are not sure the one you have is correct, you may
11 * obtain an applicable copy of the license at:
12 *
13 * http://www.isc.org/isc-license-1.0.html.
14 *
15 * This file is part of the ISC DHCP distribution. The documentation
16 * associated with this file is listed in the file DOCUMENTATION,
17 * included in the top-level directory of this release.
18 *
19 * Support and other services are available for ISC products - see
20 * http://www.isc.org for more information.
21 */
22
23#include <omapip/omapip.h>
24
25isc_result_t omapi_protocol_connect (omapi_object_t *h,
b1b7b521 26 const char *server_name,
61b844bf
TL
27 int port,
28 omapi_object_t *authinfo)
29{
30 isc_result_t status;
31 omapi_protocol_object_t *obj;
32
33 obj = (omapi_protocol_object_t *)malloc (sizeof *obj);
34 if (!obj)
35 return ISC_R_NOMEMORY;
36 memset (obj, 0, sizeof *obj);
37 obj -> refcnt = 1;
38 obj -> type = omapi_type_protocol;
39
40 status = omapi_connect ((omapi_object_t *)obj, server_name, port);
41 if (status != ISC_R_SUCCESS) {
42 omapi_object_dereference ((omapi_object_t **)&obj,
43 "omapi_protocol_connect");
44 return status;
45 }
46 status = omapi_object_reference (&h -> outer, (omapi_object_t *)obj,
47 "omapi_protocol_connect");
48 if (status != ISC_R_SUCCESS) {
49 omapi_object_dereference ((omapi_object_t **)&obj,
50 "omapi_protocol_connect");
51 return status;
52 }
53 status = omapi_object_reference (&obj -> inner, h,
54 "omapi_protocol_connect");
55 if (status != ISC_R_SUCCESS) {
56 omapi_object_dereference ((omapi_object_t **)&obj,
57 "omapi_protocol_connect");
58 return status;
59 }
60
61 /* Send the introductory message. */
62 status = omapi_protocol_send_intro ((omapi_object_t *)obj,
63 OMAPI_PROTOCOL_VERSION,
64 sizeof (omapi_protocol_header_t));
65 if (status != ISC_R_SUCCESS) {
66 omapi_object_dereference ((omapi_object_t **)&obj,
67 "omapi_protocol_connect");
68 return status;
69 }
70
71 if (authinfo)
72 omapi_object_reference (&obj -> authinfo, authinfo,
73 "omapi_protocol_connect");
74 omapi_object_dereference ((omapi_object_t **)&obj,
75 "omapi_protocol_accept");
76 return ISC_R_SUCCESS;
77}
78
79/* Send the protocol introduction message. */
80isc_result_t omapi_protocol_send_intro (omapi_object_t *h,
b1b7b521
TL
81 unsigned ver,
82 unsigned hsize)
61b844bf
TL
83{
84 isc_result_t status;
85 omapi_protocol_object_t *p;
86
87 if (h -> type != omapi_type_protocol)
88 return ISC_R_INVALIDARG;
89 p = (omapi_protocol_object_t *)h;
90
91 if (!h -> outer || h -> outer -> type != omapi_type_connection)
92 return ISC_R_NOTCONNECTED;
93
94 status = omapi_connection_put_uint32 (h -> outer, ver);
95 if (status != ISC_R_SUCCESS)
96 return status;
97
98 status = omapi_connection_put_uint32 (h -> outer, hsize);
99
100 if (status != ISC_R_SUCCESS)
101 return status;
102
103 /* Require the other end to send an intro - this kicks off the
104 protocol input state machine. */
105 p -> state = omapi_protocol_intro_wait;
106 status = omapi_connection_require (h -> outer, 8);
107 if (status != ISC_R_SUCCESS && status != ISC_R_NOTYET)
108 return status;
109
110 /* Make up an initial transaction ID for this connection. */
111 p -> next_xid = random ();
112 return ISC_R_SUCCESS;
113}
114
115isc_result_t omapi_protocol_send_message (omapi_object_t *po,
116 omapi_object_t *id,
117 omapi_object_t *mo,
118 omapi_object_t *omo)
119{
120 omapi_protocol_object_t *p;
121 omapi_object_t *c;
122 omapi_message_object_t *m;
123 omapi_message_object_t *om;
124 isc_result_t status;
125 u_int32_t foo;
126
127 if (po -> type != omapi_type_protocol ||
128 !po -> outer || po -> outer -> type != omapi_type_connection ||
129 mo -> type != omapi_type_message)
130 return ISC_R_INVALIDARG;
131 if (omo && omo -> type != omapi_type_message)
132 return ISC_R_INVALIDARG;
133 p = (omapi_protocol_object_t *)po;
134 c = (omapi_object_t *)(po -> outer);
135 m = (omapi_message_object_t *)mo;
136 om = (omapi_message_object_t *)omo;
137
138 /* XXX Write the authenticator length */
139 status = omapi_connection_put_uint32 (c, 0);
140 if (status != ISC_R_SUCCESS)
141 return status;
142 /* XXX Write the ID of the authentication key we're using. */
143 status = omapi_connection_put_uint32 (c, 0);
144 if (status != ISC_R_SUCCESS) {
145 omapi_disconnect (c, 1);
146 return status;
147 }
148
149 /* Write the opcode. */
150 status = omapi_connection_put_uint32 (c, m -> op);
151 if (status != ISC_R_SUCCESS) {
152 omapi_disconnect (c, 1);
153 return status;
154 }
155
156 /* Write the handle. If we've been given an explicit handle, use
157 that. Otherwise, use the handle of the object we're sending.
158 The caller is responsible for arranging for one of these handles
159 to be set (or not). */
160 status = omapi_connection_put_uint32 (c, (m -> h
161 ? m -> h
5a8e13c6
TL
162 : (m -> object
163 ? m -> object -> handle
164 : 0)));
61b844bf
TL
165 if (status != ISC_R_SUCCESS) {
166 omapi_disconnect (c, 1);
167 return status;
168 }
169
170 /* Set and write the transaction ID. */
171 m -> id = p -> next_xid++;
172 status = omapi_connection_put_uint32 (c, m -> id);
173 if (status != ISC_R_SUCCESS) {
174 omapi_disconnect (c, 1);
175 return status;
176 }
177
178 /* Write the transaction ID of the message to which this is a
179 response, if there is such a message. */
5a8e13c6 180 status = omapi_connection_put_uint32 (c, om ? om -> id : m -> rid);
61b844bf
TL
181 if (status != ISC_R_SUCCESS) {
182 omapi_disconnect (c, 1);
183 return status;
184 }
185
581e37e4 186 /* Stuff out the name/value pairs specific to this message. */
5a8e13c6
TL
187 status = omapi_stuff_values (c, id, (omapi_object_t *)m);
188 if (status != ISC_R_SUCCESS) {
189 omapi_disconnect (c, 1);
190 return status;
581e37e4
TL
191 }
192
193 /* Write the zero-length name that terminates the list of name/value
194 pairs specific to the message. */
195 status = omapi_connection_put_uint16 (c, 0);
61b844bf
TL
196 if (status != ISC_R_SUCCESS) {
197 omapi_disconnect (c, 1);
198 return status;
199 }
200
581e37e4
TL
201 /* Stuff out all the published name/value pairs in the object that's
202 being sent in the message, if there is one. */
203 if (m -> object) {
204 status = omapi_stuff_values (c, id, m -> object);
205 if (status != ISC_R_SUCCESS) {
206 omapi_disconnect (c, 1);
207 return status;
208 }
209 }
210
61b844bf 211 /* Write the zero-length name that terminates the list of name/value
581e37e4 212 pairs for the associated object. */
61b844bf
TL
213 status = omapi_connection_put_uint16 (c, 0);
214 if (status != ISC_R_SUCCESS) {
215 omapi_disconnect (c, 1);
216 return status;
217 }
218
219 /* XXX Write the authenticator... */
220
221 return ISC_R_SUCCESS;
222}
223
224
225isc_result_t omapi_protocol_signal_handler (omapi_object_t *h,
b1b7b521 226 const char *name, va_list ap)
61b844bf
TL
227{
228 isc_result_t status;
229 omapi_protocol_object_t *p;
230 omapi_object_t *c;
231 u_int16_t nlen;
232 u_int32_t vlen;
233
234 if (h -> type != omapi_type_protocol) {
235 /* XXX shouldn't happen. Put an assert here? */
236 return ISC_R_UNEXPECTED;
237 }
238 p = (omapi_protocol_object_t *)h;
239
240 /* Not a signal we recognize? */
241 if (strcmp (name, "ready")) {
242 if (p -> inner && p -> inner -> type -> signal_handler)
243 return (*(p -> inner -> type -> signal_handler)) (h,
244 name,
245 ap);
246 return ISC_R_NOTFOUND;
247 }
248
249 if (!p -> outer || p -> outer -> type != omapi_type_connection)
250 return ISC_R_INVALIDARG;
251 c = p -> outer;
252
253 /* We get here because we requested that we be woken up after
254 some number of bytes were read, and that number of bytes
255 has in fact been read. */
256 switch (p -> state) {
257 case omapi_protocol_intro_wait:
258 /* Get protocol version and header size in network
259 byte order. */
e92653f1
TL
260 omapi_connection_get_uint32
261 (c, (u_int32_t *)&p -> protocol_version);
262 omapi_connection_get_uint32
263 (c, (u_int32_t *)&p -> header_size);
61b844bf
TL
264
265 /* We currently only support the current protocol version. */
266 if (p -> protocol_version != OMAPI_PROTOCOL_VERSION) {
267 omapi_disconnect (c, 1);
268 return ISC_R_VERSIONMISMATCH;
269 }
270
271 if (p -> header_size < sizeof (omapi_protocol_header_t)) {
272 omapi_disconnect (c, 1);
273 return ISC_R_PROTOCOLERROR;
274 }
275
276 status = omapi_signal_in (h -> inner, "ready");
277
278 to_header_wait:
279 /* The next thing we're expecting is a message header. */
280 p -> state = omapi_protocol_header_wait;
281
282 /* Register a need for the number of bytes in a
283 header, and if we already have that many, process
284 them immediately. */
285 if ((omapi_connection_require
286 (c, p -> header_size)) != ISC_R_SUCCESS)
287 break;
288 /* If we already have the data, fall through. */
289
290 case omapi_protocol_header_wait:
291 status = omapi_message_new ((omapi_object_t **)&p -> message,
292 "omapi_protocol_signal_handler");
293 if (status != ISC_R_SUCCESS) {
294 omapi_disconnect (c, 1);
295 return status;
296 }
297
61b844bf 298 /* Swap in the header... */
e92653f1
TL
299 omapi_connection_get_uint32
300 (c, (u_int32_t *)&p -> message -> authid);
61b844bf
TL
301
302 /* XXX bind the authenticator here! */
e92653f1
TL
303 omapi_connection_get_uint32
304 (c, (u_int32_t *)&p -> message -> authlen);
305 omapi_connection_get_uint32
306 (c, (u_int32_t *)&p -> message -> op);
307 omapi_connection_get_uint32
308 (c, (u_int32_t *)&p -> message -> handle);
309 omapi_connection_get_uint32
310 (c, (u_int32_t *)&p -> message -> id);
311 omapi_connection_get_uint32
312 (c, (u_int32_t *)&p -> message -> rid);
61b844bf
TL
313
314 /* If there was any extra header data, skip over it. */
315 if (p -> header_size > sizeof (omapi_protocol_header_t)) {
316 omapi_connection_copyout
317 (0, c, (p -> header_size -
318 sizeof (omapi_protocol_header_t)));
319 }
320
321 /* XXX must compute partial signature across the
322 XXX preceding bytes. Also, if authenticator
323 specifies encryption as well as signing, we may
324 have to decrypt the data on the way in. */
325
581e37e4
TL
326 /* First we read in message-specific values, then object
327 values. */
328 p -> reading_message_values = 1;
329
61b844bf
TL
330 need_name_length:
331 /* The next thing we're expecting is length of the
332 first name. */
333 p -> state = omapi_protocol_name_length_wait;
334
335 /* Wait for a 16-bit length. */
336 if ((omapi_connection_require (c, 2)) != ISC_R_SUCCESS)
337 break;
338 /* If it's already here, fall through. */
339
340 case omapi_protocol_name_length_wait:
341 omapi_connection_get_uint16 (c, &nlen);
342 /* A zero-length name means that we're done reading name+value
343 pairs. */
344 if (nlen == 0) {
581e37e4
TL
345 /* If we've already read in the object, we are
346 done reading the message, but if we've just
347 finished reading in the values associated
348 with the message, we need to read the
349 object. */
350 if (p -> reading_message_values) {
351 p -> reading_message_values = 0;
352 goto need_name_length;
353 }
354
61b844bf
TL
355 /* If the authenticator length is zero, there's no
356 signature to read in, so go straight to processing
357 the message. */
358 if (p -> message -> authlen == 0)
359 goto message_done;
360
361 /* The next thing we're expecting is the
362 message signature. */
363 p -> state = omapi_protocol_signature_wait;
364
365 /* Wait for the number of bytes specified for
366 the authenticator. If we already have it,
367 go read it in. */
368 if (omapi_connection_require
369 (c, p -> message -> authlen) == ISC_R_SUCCESS)
370 goto signature_wait;
371 break;
372 }
373
374 /* Allocate a buffer for the name. */
375 status = (omapi_data_string_new
376 (&p -> name, nlen, "omapi_protocol_signal_handler"));
377 if (status != ISC_R_SUCCESS) {
378 omapi_disconnect (c, 1);
379 return ISC_R_NOMEMORY;
380 }
581e37e4 381 p -> state = omapi_protocol_name_wait;
61b844bf
TL
382 if (omapi_connection_require (c, nlen) != ISC_R_SUCCESS)
383 break;
384 /* If it's already here, fall through. */
385
386 case omapi_protocol_name_wait:
387 omapi_connection_copyout (p -> name -> value, c,
388 p -> name -> len);
389 /* Wait for a 32-bit length. */
581e37e4 390 p -> state = omapi_protocol_value_length_wait;
61b844bf
TL
391 if ((omapi_connection_require (c, 4)) != ISC_R_SUCCESS)
392 break;
393 /* If it's already here, fall through. */
394
395 case omapi_protocol_value_length_wait:
396 omapi_connection_get_uint32 (c, &vlen);
397
398 /* Zero-length values are allowed - if we get one, we
399 don't have to read any data for the value - just
400 get the next one, if there is a next one. */
401 if (!vlen)
402 goto insert_new_value;
403
404 status = (omapi_typed_data_new
581e37e4 405 (&p -> value, omapi_datatype_data, vlen,
61b844bf
TL
406 "omapi_protocol_signal_handler"));
407 if (status != ISC_R_SUCCESS) {
408 omapi_disconnect (c, 1);
409 return ISC_R_NOMEMORY;
410 }
411
581e37e4 412 p -> state = omapi_protocol_value_wait;
61b844bf
TL
413 if (omapi_connection_require (c, vlen) != ISC_R_SUCCESS)
414 break;
415 /* If it's already here, fall through. */
416
417 case omapi_protocol_value_wait:
418 omapi_connection_copyout (p -> value -> u.buffer.value, c,
419 p -> value -> u.buffer.len);
420
421 insert_new_value:
581e37e4
TL
422 if (p -> reading_message_values) {
423 status = (omapi_set_value
424 ((omapi_object_t *)p -> message,
425 p -> message -> id_object,
426 p -> name, p -> value));
427 } else {
428 if (!p -> message -> object) {
429 /* We need a generic object to hang off of the
430 incoming message. */
431 status = (omapi_generic_new
432 (&p -> message -> object,
433 "omapi_protocol_signal_handler"));
434 if (status != ISC_R_SUCCESS) {
435 omapi_disconnect (c, 1);
436 return status;
437 }
438 }
439 status = (omapi_set_value
440 ((omapi_object_t *)p -> message -> object,
441 p -> message -> id_object,
442 p -> name, p -> value));
443 }
61b844bf
TL
444 if (status != ISC_R_SUCCESS) {
445 omapi_disconnect (c, 1);
446 return status;
447 }
448 omapi_data_string_dereference
449 (&p -> name, "omapi_protocol_signal_handler");
450 omapi_typed_data_dereference (&p -> value,
451 "omapi_protocol_signal_handler");
452 goto need_name_length;
453
454 signature_wait:
455 case omapi_protocol_signature_wait:
456 status = omapi_typed_data_new (&p -> message -> authenticator,
457 omapi_datatype_data,
458 p -> message -> authlen);
459
460 if (status != ISC_R_SUCCESS) {
461 omapi_disconnect (c, 1);
462 return ISC_R_NOMEMORY;
463 }
464 omapi_connection_copyout
465 (p -> message -> authenticator -> u.buffer.value, c,
466 p -> message -> authlen);
467 /* XXX now do something to verify the signature. */
468
581e37e4 469 /* Process the message. */
61b844bf 470 message_done:
5a8e13c6
TL
471 status = omapi_message_process ((omapi_object_t *)p -> message,
472 h);
581e37e4
TL
473 if (status != ISC_R_SUCCESS) {
474 omapi_disconnect (c, 1);
475 return ISC_R_NOMEMORY;
476 }
477
61b844bf 478 /* XXX unbind the authenticator. */
581e37e4
TL
479 auth_unbind:
480 omapi_object_dereference ((omapi_object_t **)&p -> message,
481 "omapi_protocol_signal_handler");
61b844bf
TL
482
483 /* Now wait for the next message. */
484 goto to_header_wait;
485
486 default:
487 /* XXX should never get here. Assertion? */
8a6dfe4c 488 break;
61b844bf
TL
489 }
490 return ISC_R_SUCCESS;
491}
492
493isc_result_t omapi_protocol_set_value (omapi_object_t *h,
494 omapi_object_t *id,
495 omapi_data_string_t *name,
496 omapi_typed_data_t *value)
497{
498 if (h -> type != omapi_type_protocol)
499 return ISC_R_INVALIDARG;
500
501 if (h -> inner && h -> inner -> type -> set_value)
502 return (*(h -> inner -> type -> set_value))
503 (h -> inner, id, name, value);
504 return ISC_R_NOTFOUND;
505}
506
507isc_result_t omapi_protocol_get_value (omapi_object_t *h,
508 omapi_object_t *id,
509 omapi_data_string_t *name,
510 omapi_value_t **value)
511{
512 if (h -> type != omapi_type_protocol)
513 return ISC_R_INVALIDARG;
514
515 if (h -> inner && h -> inner -> type -> get_value)
516 return (*(h -> inner -> type -> get_value))
517 (h -> inner, id, name, value);
518 return ISC_R_NOTFOUND;
519}
520
b1b7b521 521isc_result_t omapi_protocol_destroy (omapi_object_t *h, const char *name)
61b844bf
TL
522{
523 omapi_protocol_object_t *p;
524 if (h -> type != omapi_type_protocol)
525 return ISC_R_INVALIDARG;
526 p = (omapi_protocol_object_t *)h;
527 if (p -> message)
528 omapi_object_dereference ((omapi_object_t **)&p -> message,
529 name);
530 if (p -> authinfo)
531 return omapi_object_dereference (&p -> authinfo, name);
532 return ISC_R_SUCCESS;
533}
534
535/* Write all the published values associated with the object through the
536 specified connection. */
537
538isc_result_t omapi_protocol_stuff_values (omapi_object_t *c,
539 omapi_object_t *id,
540 omapi_object_t *p)
541{
542 int i;
543
544 if (p -> type != omapi_type_protocol)
545 return ISC_R_INVALIDARG;
546
547 if (p -> inner && p -> inner -> type -> stuff_values)
548 return (*(p -> inner -> type -> stuff_values)) (c, id,
549 p -> inner);
550 return ISC_R_SUCCESS;
551}
552
553/* Set up a listener for the omapi protocol. The handle stored points to
554 a listener object, not a protocol object. */
555
556isc_result_t omapi_protocol_listen (omapi_object_t *h,
557 int port,
558 int max)
559{
560 isc_result_t status;
561 omapi_protocol_listener_object_t *obj;
562
563 obj = (omapi_protocol_listener_object_t *)malloc (sizeof *obj);
564 if (!obj)
565 return ISC_R_NOMEMORY;
566 memset (obj, 0, sizeof *obj);
567 obj -> refcnt = 1;
568 obj -> type = omapi_type_protocol_listener;
569
570 status = omapi_object_reference (&h -> outer, (omapi_object_t *)obj,
571 "omapi_protocol_listen");
572 if (status != ISC_R_SUCCESS) {
573 omapi_object_dereference ((omapi_object_t **)&obj,
574 "omapi_protocol_listen");
575 return status;
576 }
577 status = omapi_object_reference (&obj -> inner, h,
578 "omapi_protocol_listen");
579 if (status != ISC_R_SUCCESS) {
580 omapi_object_dereference ((omapi_object_t **)&obj,
581 "omapi_protocol_listen");
582 return status;
583 }
584
585 status = omapi_listen ((omapi_object_t *)obj, port, max);
586 omapi_object_dereference ((omapi_object_t **)&obj,
587 "omapi_protocol_listen");
588 return status;
589}
590
591/* Signal handler for protocol listener - if we get a connect signal,
592 create a new protocol connection, otherwise pass the signal down. */
593
594isc_result_t omapi_protocol_listener_signal (omapi_object_t *o,
b1b7b521 595 const char *name, va_list ap)
61b844bf
TL
596{
597 isc_result_t status;
598 omapi_object_t *c;
599 omapi_protocol_object_t *obj;
600 omapi_protocol_listener_object_t *p;
601
602 if (!o || o -> type != omapi_type_protocol_listener)
603 return ISC_R_INVALIDARG;
604 p = (omapi_protocol_listener_object_t *)o;
605
606 /* Not a signal we recognize? */
607 if (strcmp (name, "connect")) {
608 if (p -> inner && p -> inner -> type -> signal_handler)
609 return (*(p -> inner -> type -> signal_handler))
610 (p -> inner, name, ap);
611 return ISC_R_NOTFOUND;
612 }
613
614 c = va_arg (ap, omapi_object_t *);
615 if (!c || c -> type != omapi_type_connection)
616 return ISC_R_INVALIDARG;
617
618 obj = (omapi_protocol_object_t *)malloc (sizeof *obj);
619 if (!obj)
620 return ISC_R_NOMEMORY;
621 memset (obj, 0, sizeof *obj);
622 obj -> refcnt = 1;
623 obj -> type = omapi_type_protocol;
624
625 status = omapi_object_reference (&obj -> outer, c,
626 "omapi_protocol_accept");
627 if (status != ISC_R_SUCCESS) {
628 lose:
629 omapi_object_dereference ((omapi_object_t **)&obj,
630 "omapi_protocol_accept");
631 omapi_disconnect (c, 1);
632 return status;
633 }
634
635 status = omapi_object_reference (&c -> inner, (omapi_object_t *)obj,
636 "omapi_protocol_accept");
637 if (status != ISC_R_SUCCESS)
638 goto lose;
639
640 /* Send the introductory message. */
641 status = omapi_protocol_send_intro ((omapi_object_t *)obj,
642 OMAPI_PROTOCOL_VERSION,
643 sizeof (omapi_protocol_header_t));
644 if (status != ISC_R_SUCCESS)
645 goto lose;
646
647 omapi_object_dereference ((omapi_object_t **)&obj,
648 "omapi_protocol_accept");
649 return status;
650}
651
652isc_result_t omapi_protocol_listener_set_value (omapi_object_t *h,
653 omapi_object_t *id,
654 omapi_data_string_t *name,
655 omapi_typed_data_t *value)
656{
657 if (h -> type != omapi_type_protocol_listener)
658 return ISC_R_INVALIDARG;
659
660 if (h -> inner && h -> inner -> type -> set_value)
661 return (*(h -> inner -> type -> set_value))
662 (h -> inner, id, name, value);
663 return ISC_R_NOTFOUND;
664}
665
666isc_result_t omapi_protocol_listener_get_value (omapi_object_t *h,
667 omapi_object_t *id,
668 omapi_data_string_t *name,
669 omapi_value_t **value)
670{
671 if (h -> type != omapi_type_protocol_listener)
672 return ISC_R_INVALIDARG;
673
674 if (h -> inner && h -> inner -> type -> get_value)
675 return (*(h -> inner -> type -> get_value))
676 (h -> inner, id, name, value);
677 return ISC_R_NOTFOUND;
678}
679
b1b7b521
TL
680isc_result_t omapi_protocol_listener_destroy (omapi_object_t *h,
681 const char *name)
61b844bf
TL
682{
683 if (h -> type != omapi_type_protocol_listener)
684 return ISC_R_INVALIDARG;
685 return ISC_R_SUCCESS;
686}
687
688/* Write all the published values associated with the object through the
689 specified connection. */
690
691isc_result_t omapi_protocol_listener_stuff (omapi_object_t *c,
692 omapi_object_t *id,
693 omapi_object_t *p)
694{
695 int i;
696
697 if (p -> type != omapi_type_protocol_listener)
698 return ISC_R_INVALIDARG;
699
700 if (p -> inner && p -> inner -> type -> stuff_values)
701 return (*(p -> inner -> type -> stuff_values)) (c, id,
702 p -> inner);
703 return ISC_R_SUCCESS;
704}
705
5a8e13c6
TL
706isc_result_t omapi_protocol_send_status (omapi_object_t *po,
707 omapi_object_t *id,
708 isc_result_t waitstatus,
b1b7b521 709 unsigned rid, const char *msg)
5a8e13c6
TL
710{
711 isc_result_t status;
712 omapi_object_t *message = (omapi_object_t *)0;
713
714 if (po -> type != omapi_type_protocol)
715 return ISC_R_INVALIDARG;
716
717 status = omapi_message_new (&message, "omapi_protocol_send_status");
718 if (status != ISC_R_SUCCESS)
719 return status;
720
721 status = omapi_set_int_value (message, (omapi_object_t *)0,
722 "op", OMAPI_OP_STATUS);
723 if (status != ISC_R_SUCCESS) {
724 omapi_object_dereference (&message,
725 "omapi_protocol_send_status");
726 return status;
727 }
728
729 status = omapi_set_int_value (message, (omapi_object_t *)0,
b1b7b521 730 "rid", (int)rid);
5a8e13c6
TL
731 if (status != ISC_R_SUCCESS) {
732 omapi_object_dereference (&message,
733 "omapi_protocol_send_status");
734 return status;
735 }
736
737 status = omapi_set_int_value (message, (omapi_object_t *)0,
b1b7b521 738 "result", (int)waitstatus);
5a8e13c6
TL
739 if (status != ISC_R_SUCCESS) {
740 omapi_object_dereference (&message,
741 "omapi_protocol_send_status");
742 return status;
743 }
744
745 /* If a message has been provided, send it. */
746 if (msg) {
747 status = omapi_set_string_value (message, (omapi_object_t *)0,
748 "message", msg);
749 if (status != ISC_R_SUCCESS) {
750 omapi_object_dereference
751 (&message, "omapi_protocol_send_status");
752 return status;
753 }
754 }
755
756 return omapi_protocol_send_message (po,
757 id, message, (omapi_object_t *)0);
758}
759
760isc_result_t omapi_protocol_send_update (omapi_object_t *po,
761 omapi_object_t *id,
b1b7b521 762 unsigned rid,
5a8e13c6
TL
763 omapi_object_t *object)
764{
765 isc_result_t status;
766 omapi_object_t *message = (omapi_object_t *)0;
767
768 if (po -> type != omapi_type_protocol)
769 return ISC_R_INVALIDARG;
770
771 status = omapi_message_new (&message, "omapi_protocol_send_update");
772 if (status != ISC_R_SUCCESS)
773 return status;
774
775 status = omapi_set_int_value (message, (omapi_object_t *)0,
776 "op", OMAPI_OP_UPDATE);
777 if (status != ISC_R_SUCCESS) {
778 omapi_object_dereference (&message,
779 "omapi_protocol_send_update");
780 return status;
781 }
782
783 if (rid) {
e5bbe4da 784 omapi_handle_t handle;
5a8e13c6 785 status = omapi_set_int_value (message, (omapi_object_t *)0,
b1b7b521 786 "rid", (int)rid);
5a8e13c6
TL
787 if (status != ISC_R_SUCCESS) {
788 omapi_object_dereference
789 (&message, "omapi_protocol_send_update");
790 return status;
791 }
e5bbe4da 792
5a8e13c6
TL
793 status = omapi_object_handle (&handle, object);
794 if (status != ISC_R_SUCCESS) {
795 omapi_object_dereference
796 (&message, "omapi_protocol_send_update");
797 return status;
798 }
799 status = omapi_set_int_value (message, (omapi_object_t *)0,
b1b7b521 800 "handle", (int)handle);
5a8e13c6
TL
801 if (status != ISC_R_SUCCESS) {
802 omapi_object_dereference
803 (&message, "omapi_protocol_send_update");
804 return status;
805 }
806 }
807
808 status = omapi_set_object_value (message, (omapi_object_t *)0,
809 "object", object);
810 if (status != ISC_R_SUCCESS) {
811 omapi_object_dereference (&message, "dhcpctl_open_object");
812 return status;
813 }
814
815 return omapi_protocol_send_message (po,
816 id, message, (omapi_object_t *)0);
817}